Skip to content

Commit 08435f8

Browse files
committed
doe_pci_cfg: Support devices with DOE v2
Signed-off-by: Alistair Francis <[email protected]>
1 parent 06244ba commit 08435f8

File tree

1 file changed

+113
-25
lines changed

1 file changed

+113
-25
lines changed

src/doe_pci_cfg.rs

Lines changed: 113 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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;
498520
const DOE_RESPONSE_PROTOCOL_MASK: u32 = 0x00FF_0000;
499521
const DOE_RESPONSE_NEXT_INDEX_MASK: u32 = 0xFF00_0000;
500522
const 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
503527
const DOE_RESPONSE_VID_SHIFT: u32 = 0;
504528
const DOE_RESPONSE_PROTOCOL_SHIFT: u32 = 16;
505529
const DOE_RESPONSE_NEXT_INDEX_SHIFT: u32 = 24;
530+
const DOE_RESPONSE_ADD_INFO_SHIFT: u32 = 18;
506531

507532
// Masks for Discovery Request
508533
const DOE_REQUEST_INDEX: u32 = 0x0000_00FF;
509534
const DOE_REQUEST_VID_MASK: u32 = 0x0000_FFFF;
510535
const DOE_REQUEST_PROTOCOL_MASK: u32 = 0x00FF_0000;
511536
const 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
514542
const _DOE_REQUEST_VID_SHIFT: u32 = 0;
515543
const 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-
527553
impl 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+
533561
impl 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+
"\tDISC_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

Comments
 (0)