@@ -478,6 +478,28 @@ unsafe fn doe_wait_status_dor(device: *mut pci_dev, doe_offset: i32) -> Result<(
478478 Ok ( ( ) )
479479}
480480
481+ /// # Summary
482+ ///
483+ /// A helper function to retrieve the DOE version,
484+ ///
485+ /// # Parameter
486+ ///
487+ /// * `device`: `pci_dev` pointing to the target device
488+ /// * `doe_offset`: offset at which doe sits in the extended capability list
489+ ///
490+ /// # Returns
491+ ///
492+ /// The capability version
493+ ///
494+ /// # Panics
495+ ///
496+ /// Panics if `pci_dev` is invalid
497+ unsafe fn doe_capability_version ( device : * mut pci_dev , doe_offset : i32 ) -> u8 {
498+ let doe_extended_cap = pci_read_long ( device, doe_offset) ;
499+
500+ ( ( doe_extended_cap & 0xF0000 ) >> 16 ) as u8
501+ }
502+
481503//---------------------FOLLOWING CODE IS FOR TESTING--------------------------//
482504
483505/// DOE Header
@@ -498,18 +520,24 @@ const DOE_RESPONSE_VID_MASK: u32 = 0x0000_FFFF;
498520const DOE_RESPONSE_PROTOCOL_MASK : u32 = 0x00FF_0000 ;
499521const DOE_RESPONSE_NEXT_INDEX_MASK : u32 = 0xFF00_0000 ;
500522const DOE_RESPONSE_LEN_MASK : u32 = 0x0001_FFFF ;
523+ const DOE_RESPONSE_MAX_DO_LEN_MASK : u32 = 0x0003_FFFF ;
524+ const DOE_RESPONSE_ADD_INFO_MASK : u32 = 0xFFFC_0000 ;
501525
502526// Shifts for Discovery Response
503527const DOE_RESPONSE_VID_SHIFT : u32 = 0 ;
504528const DOE_RESPONSE_PROTOCOL_SHIFT : u32 = 16 ;
505529const DOE_RESPONSE_NEXT_INDEX_SHIFT : u32 = 24 ;
530+ const DOE_RESPONSE_ADD_INFO_SHIFT : u32 = 18 ;
506531
507532// Masks for Discovery Request
508533const DOE_REQUEST_INDEX : u32 = 0x0000_00FF ;
509534const DOE_REQUEST_VID_MASK : u32 = 0x0000_FFFF ;
510535const DOE_REQUEST_PROTOCOL_MASK : u32 = 0x00FF_0000 ;
511536const DOE_REQUEST_LEN_MASK : u32 = 0x0001_FFFF ;
512537
538+ const DOE_VERSION : u8 = 2 ;
539+ const DOE_REQUEST_VERSION_SHIFT : u32 = 8 ;
540+
513541// Shifts for Discovery Request
514542const _DOE_REQUEST_VID_SHIFT: u32 = 0 ;
515543const DOE_REQUEST_PROTOCOL_SHIFT : u32 = 16 ;
@@ -522,17 +550,17 @@ pub struct DoeDiscoveryPacket {
522550 dw0 : u32 ,
523551}
524552
525- pub struct DoeDiscoveryResponse ( Vec < u32 > ) ;
526-
527553impl DoeDiscoveryPacket {
528554 pub fn as_array ( & self ) -> [ u32 ; 3 ] {
529555 [ self . header1 , self . header2 , self . dw0 ]
530556 }
531557}
532558
559+ pub struct DoeDiscoveryResponse ( Vec < u32 > ) ;
560+
533561impl fmt:: Display for DoeDiscoveryResponse {
534562 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
535- if self . 0 . len ( ) != 3 {
563+ if ! ( self . 0 . len ( ) == 3 || self . 0 . len ( ) == 4 ) {
536564 return writeln ! ( f, "inner vector invalid" ) ;
537565 }
538566 let header1 = self . 0 [ 0 ] ;
@@ -554,6 +582,15 @@ impl fmt::Display for DoeDiscoveryResponse {
554582 ( dw0 & DOE_RESPONSE_PROTOCOL_MASK ) >> DOE_RESPONSE_PROTOCOL_SHIFT ,
555583 dw0 & DOE_RESPONSE_VID_MASK
556584 ) ?;
585+ if self . 0 . len ( ) == 4 {
586+ let dw1 = self . 0 [ 3 ] ;
587+ writeln ! (
588+ f,
589+ "\t DISC_RESP: [ADDITIONAL_INFO: {}, MAX_DO_LEN: {}]" ,
590+ ( dw1 & DOE_RESPONSE_ADD_INFO_MASK ) >> DOE_RESPONSE_ADD_INFO_SHIFT ,
591+ dw1 & DOE_RESPONSE_MAX_DO_LEN_MASK
592+ ) ?;
593+ }
557594 writeln ! ( f, "}}" )
558595 }
559596}
@@ -598,13 +635,26 @@ pub unsafe fn test_discovery_basic() -> Result<(), ()> {
598635 let pcie_ids = PCIE_IDENTIFIERS . get ( ) . unwrap ( ) ;
599636 let ( pacc, device, doe_offset) = get_pcie_dev ( pcie_ids. vid , pcie_ids. devid ) . unwrap ( ) ;
600637 doe_wait_not_busy ( device, doe_offset) ?;
638+ let doe_version = doe_capability_version ( device, doe_offset) ;
601639 let doe_discovery_index: u32 = 0 ;
602- let discovery_packet = DoeDiscoveryPacket {
603- header1 : ( PCI_DOE_PROTOCOL_DISCOVERY << DOE_HEADER1_OFST_TYPE )
604- | ( PCI_VENDOR_ID_PCI_SIG << DOE_HEADER1_OFST_VID ) ,
605- // We are sending 3DWs (inc 2 for header)
606- header2 : 3 << DOE_HEADER2_OFST_LEN ,
607- dw0 : doe_discovery_index << DOE_DISC_OFST_SHIFT ,
640+
641+ let discovery_packet = if doe_version == DOE_VERSION {
642+ DoeDiscoveryPacket {
643+ header1 : ( PCI_DOE_PROTOCOL_DISCOVERY << DOE_HEADER1_OFST_TYPE )
644+ | ( PCI_VENDOR_ID_PCI_SIG << DOE_HEADER1_OFST_VID ) ,
645+ // We are sending 3DWs (inc 2 for header)
646+ header2 : 3 << DOE_HEADER2_OFST_LEN ,
647+ dw0 : doe_discovery_index << DOE_DISC_OFST_SHIFT
648+ | ( DOE_VERSION as u32 ) << DOE_REQUEST_VERSION_SHIFT ,
649+ }
650+ } else {
651+ DoeDiscoveryPacket {
652+ header1 : ( PCI_DOE_PROTOCOL_DISCOVERY << DOE_HEADER1_OFST_TYPE )
653+ | ( PCI_VENDOR_ID_PCI_SIG << DOE_HEADER1_OFST_VID ) ,
654+ // We are sending 3DWs (inc 2 for header)
655+ header2 : 3 << DOE_HEADER2_OFST_LEN ,
656+ dw0 : doe_discovery_index << DOE_DISC_OFST_SHIFT ,
657+ }
608658 } ;
609659 info ! ( "Discovery Request: {}" , discovery_packet) ;
610660 for data in discovery_packet. as_array ( ) . iter ( ) {
@@ -668,6 +718,8 @@ pub unsafe fn test_discovery_all() -> Result<(), ()> {
668718 let ( pacc, device, doe_offset) = get_pcie_dev ( pcie_ids. vid , pcie_ids. devid ) . unwrap ( ) ;
669719 doe_wait_not_busy ( device, doe_offset) ?;
670720
721+ let doe_version = doe_capability_version ( device, doe_offset) ;
722+
671723 let mut doe_discovery_index: u32 = 0 ;
672724 let mut discovery_packet = DoeDiscoveryPacket {
673725 header1 : ( PCI_DOE_PROTOCOL_DISCOVERY << DOE_HEADER1_OFST_TYPE )
@@ -681,6 +733,10 @@ pub unsafe fn test_discovery_all() -> Result<(), ()> {
681733 // We want to loop till we hit the end of discoverable objects on the
682734 // doe instance. Response `next_index` = 0 to indicate the final entry.
683735 discovery_packet. dw0 = doe_discovery_index << DOE_DISC_OFST_SHIFT ;
736+ if doe_version == DOE_VERSION {
737+ discovery_packet. dw0 |= ( DOE_VERSION as u32 ) << DOE_REQUEST_VERSION_SHIFT ;
738+ }
739+
684740 info ! ( "Discovery Request: {}" , discovery_packet) ;
685741
686742 for data in discovery_packet. as_array ( ) . iter ( ) {
@@ -708,22 +764,38 @@ pub unsafe fn test_discovery_all() -> Result<(), ()> {
708764 doe_status = pci_read_long ( device, doe_offset + DOE_STATUS ) ;
709765 }
710766
711- assert_eq ! (
712- recv. 0 . len( ) ,
713- 3 ,
714- "Response expected bytes mismatch, expected 12bytes got {}bytes" ,
715- recv. 0 . len( ) * 4
716- ) ;
717767 // This is the 3rd dword which is the response data (see table 6-42)
718768 doe_discovery_index =
719769 ( recv. 0 [ 2 ] & DOE_RESPONSE_NEXT_INDEX_MASK ) >> DOE_RESPONSE_NEXT_INDEX_SHIFT ;
720770 let vid = ( recv. 0 [ 2 ] & DOE_RESPONSE_VID_MASK ) >> DOE_RESPONSE_VID_SHIFT ;
721771
722772 match ( recv. 0 [ 2 ] & DOE_RESPONSE_PROTOCOL_MASK ) >> DOE_RESPONSE_PROTOCOL_SHIFT {
723- 0 => info ! ( "VID: {} - Discovery Support [OK]" , vid) ,
724- 1 => info ! ( "VID: {} - CMA/SPDM Support [OK]" , vid) ,
725- 2 => info ! ( "VID: {} - Secured CMA/SPDM Support [OK]" , vid) ,
726- _ => info ! ( "Reserved" ) ,
773+ 0 => {
774+ info ! ( "VID: {} - Discovery Support [OK]" , vid) ;
775+ assert_eq ! (
776+ recv. 0 . len( ) ,
777+ 3 ,
778+ "Response expected bytes mismatch, expected 12bytes got {}bytes" ,
779+ recv. 0 . len( ) * 4
780+ ) ;
781+ }
782+ 1 => {
783+ info ! ( "VID: {} - CMA/SPDM Support [OK]" , vid) ;
784+ assert ! (
785+ recv. 0 . len( ) == 3 || recv. 0 . len( ) == 4 ,
786+ "Response expected bytes mismatch, expected 12 or 16bytes got {}bytes" ,
787+ recv. 0 . len( ) * 4
788+ ) ;
789+ }
790+ 2 => {
791+ info ! ( "VID: {} - Secured CMA/SPDM Support [OK]" , vid) ;
792+ assert ! (
793+ recv. 0 . len( ) == 3 || recv. 0 . len( ) == 4 ,
794+ "Response expected bytes mismatch, expected 12 or 16bytes got {}bytes" ,
795+ recv. 0 . len( ) * 4
796+ ) ;
797+ }
798+ _ => info ! ( "Reserved/Unsupported by SPDM-Utils" ) ,
727799 }
728800 // Print the receive buffer.
729801 info ! ( "Discovery Response: {}" , recv) ;
@@ -757,16 +829,32 @@ pub unsafe fn test_discovery_error() -> Result<(), ()> {
757829 info ! ( "--- Testing Discovery: Error Cases ---" ) ;
758830 let pcie_ids = PCIE_IDENTIFIERS . get ( ) . unwrap ( ) ;
759831 let ( pacc, device, doe_offset) = get_pcie_dev ( pcie_ids. vid , pcie_ids. devid ) . unwrap ( ) ;
832+
760833 doe_wait_not_busy ( device, doe_offset) ?;
834+
835+ let doe_version = doe_capability_version ( device, doe_offset) ;
836+
761837 // Note that this index is invalid
762838 let doe_discovery_index: u32 = 32 ;
763- let discovery_packet = DoeDiscoveryPacket {
764- header1 : ( PCI_DOE_PROTOCOL_DISCOVERY << DOE_HEADER1_OFST_TYPE )
765- | ( PCI_VENDOR_ID_PCI_SIG << DOE_HEADER1_OFST_VID ) ,
766- // We are sending 3DWs (inc 2 for header)
767- header2 : 3 << DOE_HEADER2_OFST_LEN ,
768- dw0 : doe_discovery_index << DOE_DISC_OFST_SHIFT ,
839+ let discovery_packet = if doe_version == DOE_VERSION {
840+ DoeDiscoveryPacket {
841+ header1 : ( PCI_DOE_PROTOCOL_DISCOVERY << DOE_HEADER1_OFST_TYPE )
842+ | ( PCI_VENDOR_ID_PCI_SIG << DOE_HEADER1_OFST_VID ) ,
843+ // We are sending 3DWs (inc 2 for header)
844+ header2 : 3 << DOE_HEADER2_OFST_LEN ,
845+ dw0 : doe_discovery_index << DOE_DISC_OFST_SHIFT
846+ | ( DOE_VERSION as u32 ) << DOE_REQUEST_VERSION_SHIFT ,
847+ }
848+ } else {
849+ DoeDiscoveryPacket {
850+ header1 : ( PCI_DOE_PROTOCOL_DISCOVERY << DOE_HEADER1_OFST_TYPE )
851+ | ( PCI_VENDOR_ID_PCI_SIG << DOE_HEADER1_OFST_VID ) ,
852+ // We are sending 3DWs (inc 2 for header)
853+ header2 : 3 << DOE_HEADER2_OFST_LEN ,
854+ dw0 : doe_discovery_index << DOE_DISC_OFST_SHIFT ,
855+ }
769856 } ;
857+
770858 info ! ( "Discovery Request: {}" , discovery_packet) ;
771859
772860 for data in discovery_packet. as_array ( ) . iter ( ) {
0 commit comments