use heterob::{P3, bit_numbering::{LsbInto, Lsb}, endianness::FromLeBytes};
use snafu::prelude::*;
use super::ECS_OFFSET;
pub const ECH_BYTES: usize = 4;
#[derive(Snafu, Debug, Clone, PartialEq, Eq)]
pub enum ExtendedCapabilityError {
#[snafu(display("extended capability offset should be greater than 0xFF"))]
Offset,
#[snafu(display("[{offset:03x}] extended capability header shorter than u32"))]
Header { offset: u16 },
#[snafu(display("[{offset:03x}] extended capability has empty header"))]
EmptyHeader { offset: u16 },
#[snafu(display("[{offset:03x}] {source} data read error"))]
Data { offset: u16, source: ExtendedCapabilityDataError },
#[snafu(display("[{offset:03x}] Root Complex Link Declaration error: {source}"))]
RootComplexLinkDeclaration {
offset: u16,
source: root_complex_link_declaration::RootComplexLinkDeclarationError,
},
#[snafu(display("[{offset:03x}] Multi-Function Virtual Channel error: {source}"))]
MultifunctionVirtualChannel {
offset: u16,
source: multifunction_virtual_channel::MultifunctionVirtualChannelError,
},
#[snafu(display("[{offset:03x}] Single Root I/O Virtualization error: {source}"))]
SingleRootIoVirtualization {
offset: u16,
source: single_root_io_virtualization::SingleRootIoVirtualizationError,
},
#[snafu(display("[{offset:03x}] Advanced Error Reporting error: {source}"))]
AdvancedErrorReporting {
offset: u16,
source: advanced_error_reporting::AdvancedErrorReportingError,
},
#[snafu(display("[{offset:03x}] Downstream Port Containment error: {source}"))]
DownstreamPortContainment {
offset: u16,
source: downstream_port_containment::DownstreamPortContainmentError,
},
#[snafu(display("[{offset:03x}] Resizable BAR error: {source}"))]
ResizableBar {
offset: u16,
source: resizable_bar::ResizableBarError,
},
#[snafu(display("[{offset:03x}] Dynamic Power Allocation error: {source}"))]
DynamicPowerAllocation {
offset: u16,
source: dynamic_power_allocation::DynamicPowerAllocationError,
},
#[snafu(display("[{offset:03x}] Protocol Multiplexing error: {source}"))]
ProtocolMultiplexing {
offset: u16,
source: protocol_multiplexing::ProtocolMultiplexingError,
},
#[snafu(display("[{offset:03x}] Designated Vendor-Specific Extended Capabilities error: {source}"))]
DesignatedVendorSpecificExtendedCapability {
offset: u16,
source: designated_vendor_specific_extended_capability::DesignatedVendorSpecificExtendedCapabilityError,
},
#[snafu(display("[{offset:03x}] VF Resizable BAR error: {source}"))]
VfResizableBar {
offset: u16,
source: vf_resizable_bar::VfResizableBarError,
},
}
#[derive(Snafu, Debug, Clone, Copy, PartialEq, Eq)]
#[snafu(display("{name} ({size} bytes)"))]
pub struct ExtendedCapabilityDataError {
name: &'static str,
size: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExtendedCapabilities<'a> {
ecs: &'a [u8],
next_capability_offset: u16,
}
impl<'a> ExtendedCapabilities<'a> {
pub fn new(ecs: &'a [u8]) -> Self {
Self { ecs, next_capability_offset: ECS_OFFSET as u16 }
}
}
impl<'a> Iterator for ExtendedCapabilities<'a> {
type Item = ExtendedCapabilityResult<'a>;
fn next(&mut self) -> Option<Self::Item> {
if self.next_capability_offset == 0 {
return None;
}
match parse_ecap(self.ecs, &mut self.next_capability_offset) {
Err(ExtendedCapabilityError::EmptyHeader { .. }) => None,
v => Some(v),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExtendedCapabilityHeader {
pub extended_capability_id: u16,
pub capability_version: u8,
pub next_capability_offset: u16,
}
impl From<u32> for ExtendedCapabilityHeader {
fn from(dword: u32) -> Self {
let Lsb((
extended_capability_id,
capability_version,
next_capability_offset,
)) = P3::<_, 16, 4, 12>(dword).into();
Self {
extended_capability_id,
capability_version,
next_capability_offset,
}
}
}
impl ExtendedCapabilityHeader {
pub const SIZE: usize = 4;
}
struct ExtendedCapabilityHeaderPlaceholder;
impl FromLeBytes<4> for ExtendedCapabilityHeaderPlaceholder {
fn from_le_bytes(_: [u8;4]) -> Self {
Self
}
}
type ExtendedCapabilityResult<'a> = Result<ExtendedCapability<'a>, ExtendedCapabilityError>;
fn parse_ecap<'a>(
bytes: &'a [u8],
next_capability_offset: &mut u16,
) -> ExtendedCapabilityResult<'a> {
let offset = *next_capability_offset;
let ecs_offset = (offset as usize).checked_sub(ECS_OFFSET).ok_or_else(|| {
*next_capability_offset = 0;
ExtendedCapabilityError::Offset
})?;
let ecap_data_offset = ecs_offset + ECH_BYTES;
let dword = &bytes
.get(ecs_offset..ecap_data_offset)
.map(|slice| u32::from_le_bytes(slice.try_into().unwrap()))
.ok_or_else(|| {
*next_capability_offset = 0;
ExtendedCapabilityError::Header { offset }
})?;
if *dword == 0 {
return Err(ExtendedCapabilityError::EmptyHeader { offset });
}
let (id, version, next_cap_offset) = P3::<_, 16, 4, 12>(*dword).lsb_into();
*next_capability_offset = next_cap_offset;
let ecap_data = &bytes[ecap_data_offset..];
use ExtendedCapabilityKind as Kind;
let kind = match id {
0x0000 => Kind::Null,
0x0001 => ecap_data
.try_into()
.map(Kind::AdvancedErrorReporting)
.context(AdvancedErrorReportingSnafu { offset })?,
0x0002 => ecap_data
.try_into()
.map(Kind::VirtualChannel)
.context(DataSnafu { offset })?,
0x0003 => ecap_data
.try_into()
.map(Kind::DeviceSerialNumber)
.context(DataSnafu { offset })?,
0x0004 => ecap_data
.try_into()
.map(Kind::PowerBudgeting)
.context(DataSnafu { offset })?,
0x0005 => ecap_data
.try_into()
.map(Kind::RootComplexLinkDeclaration)
.context(RootComplexLinkDeclarationSnafu { offset })?,
0x0006 => ecap_data
.try_into()
.map(Kind::RootComplexInternalLinkControl)
.context(DataSnafu { offset })?,
0x0007 => ecap_data
.try_into()
.map(Kind::RootComplexEventCollectorEndpointAssociation)
.context(DataSnafu { offset })?,
0x0008 => bytes
.try_into()
.map(Kind::MultifunctionVirtualChannel)
.context(MultifunctionVirtualChannelSnafu { offset })?,
0x0009 => ecap_data
.try_into()
.map(Kind::VirtualChannelMfvcPresent)
.context(DataSnafu { offset })?,
0x000A => bytes
.try_into()
.map(Kind::RootComplexRegisterBlockHeader)
.context(DataSnafu { offset })?,
0x000B => ecap_data
.try_into()
.map(Kind::VendorSpecificExtendedCapability)
.context(DataSnafu { offset })?,
0x000C => bytes
.try_into()
.map(Kind::ConfigurationAccessCorrelation)
.context(DataSnafu { offset })?,
0x000D => ecap_data
.try_into()
.map(Kind::AccessControlServices)
.context(DataSnafu { offset })?,
0x000E => ecap_data
.try_into()
.map(Kind::AlternativeRoutingIdInterpretation)
.context(DataSnafu { offset })?,
0x000F => ecap_data
.try_into()
.map(Kind::AddressTranslationServices)
.context(DataSnafu { offset })?,
0x0010 => ecap_data
.try_into()
.map(Kind::SingleRootIoVirtualization)
.context(DataSnafu { offset })?,
0x0011 => Kind::MultiRootIoVirtualization(MultiRootIoVirtualization),
0x0012 => bytes
.try_into()
.map(Kind::Multicast)
.context(DataSnafu { offset })?,
0x0013 => ecap_data
.try_into()
.map(Kind::PageRequestInterface)
.context(DataSnafu { offset })?,
0x0014 => Kind::ReservedForAmd(ReservedForAmd),
0x0015 => bytes
.try_into()
.map(Kind::ResizableBar)
.context(ResizableBarSnafu { offset })?,
0x0016 => bytes
.try_into()
.map(Kind::DynamicPowerAllocation)
.context(DynamicPowerAllocationSnafu { offset })?,
0x0017 => ecap_data
.try_into()
.map(Kind::TphRequester)
.context(DataSnafu { offset })?,
0x0018 => ecap_data
.try_into()
.map(Kind::LatencyToleranceReporting)
.context(DataSnafu { offset })?,
0x0019 => ecap_data
.try_into()
.map(Kind::SecondaryPciExpress)
.context(DataSnafu { offset })?,
0x001A => bytes
.try_into()
.map(Kind::ProtocolMultiplexing)
.context(ProtocolMultiplexingSnafu { offset })?,
0x001B => ecap_data
.try_into()
.map(Kind::ProcessAddressSpaceId)
.context(DataSnafu { offset })?,
0x001C => bytes
.try_into()
.map(Kind::LnRequester)
.context(DataSnafu { offset })?,
0x001D => ecap_data
.try_into()
.map(Kind::DownstreamPortContainment)
.context(DownstreamPortContainmentSnafu { offset })?,
0x001E => ecap_data
.try_into()
.map(Kind::L1PmSubstates)
.context(DataSnafu { offset })?,
0x001F => ecap_data
.try_into()
.map(Kind::PrecisionTimeMeasurement)
.context(DataSnafu { offset })?,
0x0020 => bytes
.try_into()
.map(Kind::PciExpressOverMphy)
.context(DataSnafu { offset })?,
0x0021 => bytes
.try_into()
.map(Kind::FrsQueuing)
.context(DataSnafu { offset })?,
0x0022 => bytes
.try_into()
.map(Kind::ReadinessTimeReporting)
.context(DataSnafu { offset })?,
0x0023 => bytes
.try_into()
.map(Kind::DesignatedVendorSpecificExtendedCapability)
.context(DesignatedVendorSpecificExtendedCapabilitySnafu { offset })?,
0x0024 => bytes
.try_into()
.map(Kind::VfResizableBar)
.context(VfResizableBarSnafu { offset })?,
0x0025 => Kind::DataLinkFeature(DataLinkFeature),
0x0026 => Kind::PhysicalLayer16GTps(PhysicalLayer16GTps),
0x0027 => Kind::LaneMarginingAtTheReceiver(LaneMarginingAtTheReceiver),
0x0028 => Kind::HierarchyId(HierarchyId),
0x0029 => Kind::NativePcieEnclosureManagement(NativePcieEnclosureManagement),
0x002A => Kind::PhysicalLayer32GTps(PhysicalLayer32GTps),
0x002B => Kind::AlternateProtocol(AlternateProtocol),
0x002C => Kind::SystemFirmwareIntermediary(SystemFirmwareIntermediary),
v => Kind::Reserved(v),
};
Ok(ExtendedCapability {
kind,
version,
offset,
})
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ExtendedCapability<'a> {
pub kind: ExtendedCapabilityKind<'a>,
pub version: u8,
pub offset: u16,
}
impl<'a> ExtendedCapability<'a> {
pub const HEADER_SIZE: usize = 4;
pub fn id(&self) -> u16 {
match self.kind {
ExtendedCapabilityKind::Null => 0x0000,
ExtendedCapabilityKind::AdvancedErrorReporting(_) => 0x0001,
ExtendedCapabilityKind::VirtualChannel(_) => 0x0002,
ExtendedCapabilityKind::DeviceSerialNumber(_) => 0x0003,
ExtendedCapabilityKind::PowerBudgeting(_) => 0x0004,
ExtendedCapabilityKind::RootComplexLinkDeclaration(_) => 0x0005,
ExtendedCapabilityKind::RootComplexInternalLinkControl(_) => 0x0006,
ExtendedCapabilityKind::RootComplexEventCollectorEndpointAssociation(_) => 0x0007,
ExtendedCapabilityKind::MultifunctionVirtualChannel(_) => 0x0008,
ExtendedCapabilityKind::VirtualChannelMfvcPresent(_) => 0x0009,
ExtendedCapabilityKind::RootComplexRegisterBlockHeader(_) => 0x000A,
ExtendedCapabilityKind::VendorSpecificExtendedCapability(_) => 0x000B,
ExtendedCapabilityKind::ConfigurationAccessCorrelation(_) => 0x000C,
ExtendedCapabilityKind::AccessControlServices(_) => 0x000D,
ExtendedCapabilityKind::AlternativeRoutingIdInterpretation(_) => 0x000E,
ExtendedCapabilityKind::AddressTranslationServices(_) => 0x000F,
ExtendedCapabilityKind::SingleRootIoVirtualization(_) => 0x0010,
ExtendedCapabilityKind::MultiRootIoVirtualization(_) => 0x0011,
ExtendedCapabilityKind::Multicast(_) => 0x0012,
ExtendedCapabilityKind::PageRequestInterface(_) => 0x0013,
ExtendedCapabilityKind::ReservedForAmd(_) => 0x0014,
ExtendedCapabilityKind::ResizableBar(_) => 0x0015,
ExtendedCapabilityKind::DynamicPowerAllocation(_) => 0x0016,
ExtendedCapabilityKind::TphRequester(_) => 0x0017,
ExtendedCapabilityKind::LatencyToleranceReporting(_) => 0x0018,
ExtendedCapabilityKind::SecondaryPciExpress(_) => 0x0019,
ExtendedCapabilityKind::ProtocolMultiplexing(_) => 0x001A,
ExtendedCapabilityKind::ProcessAddressSpaceId(_) => 0x001B,
ExtendedCapabilityKind::LnRequester(_) => 0x001C,
ExtendedCapabilityKind::DownstreamPortContainment(_) => 0x001D,
ExtendedCapabilityKind::L1PmSubstates(_) => 0x001E,
ExtendedCapabilityKind::PrecisionTimeMeasurement(_) => 0x001F,
ExtendedCapabilityKind::PciExpressOverMphy(_) => 0x0020,
ExtendedCapabilityKind::FrsQueuing(_) => 0x0021,
ExtendedCapabilityKind::ReadinessTimeReporting(_) => 0x0022,
ExtendedCapabilityKind::DesignatedVendorSpecificExtendedCapability(_) => 0x0023,
ExtendedCapabilityKind::VfResizableBar(_) => 0x0024,
ExtendedCapabilityKind::DataLinkFeature(_) => 0x0025,
ExtendedCapabilityKind::PhysicalLayer16GTps(_) => 0x0026,
ExtendedCapabilityKind::LaneMarginingAtTheReceiver(_) => 0x0027,
ExtendedCapabilityKind::HierarchyId(_) => 0x0028,
ExtendedCapabilityKind::NativePcieEnclosureManagement(_) => 0x0029,
ExtendedCapabilityKind::PhysicalLayer32GTps(_) => 0x002A,
ExtendedCapabilityKind::AlternateProtocol(_) => 0x002B,
ExtendedCapabilityKind::SystemFirmwareIntermediary(_) => 0x002C,
ExtendedCapabilityKind::ShadowFunctions(_) => 0x002D,
ExtendedCapabilityKind::DataObjectExchange(_) => 0x002E,
ExtendedCapabilityKind::Device3(_) => 0x002F,
ExtendedCapabilityKind::IntegrityAndDataEncryption(_) => 0x0030,
ExtendedCapabilityKind::PhysicalLayer64GTps(_) => 0x0031,
ExtendedCapabilityKind::FlitLogging(_) => 0x0032,
ExtendedCapabilityKind::FlitPerformanceMeasurement(_) => 0x0033,
ExtendedCapabilityKind::FlitErrorInjection(_) => 0x0034,
ExtendedCapabilityKind::Reserved(v) => v,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExtendedCapabilityKind<'a> {
Null,
AdvancedErrorReporting(AdvancedErrorReporting),
VirtualChannel(VirtualChannel<'a>),
DeviceSerialNumber(DeviceSerialNumber),
PowerBudgeting(PowerBudgeting),
RootComplexLinkDeclaration(RootComplexLinkDeclaration<'a>),
RootComplexInternalLinkControl(RootComplexInternalLinkControl),
RootComplexEventCollectorEndpointAssociation(RootComplexEventCollectorEndpointAssociation),
MultifunctionVirtualChannel(MultifunctionVirtualChannel<'a>),
VirtualChannelMfvcPresent(VirtualChannel<'a>),
RootComplexRegisterBlockHeader(RootComplexRegisterBlockHeader),
VendorSpecificExtendedCapability(VendorSpecificExtendedCapability<'a>),
ConfigurationAccessCorrelation(ConfigurationAccessCorrelation),
AccessControlServices(AccessControlServices<'a>),
AlternativeRoutingIdInterpretation(AlternativeRoutingIdInterpretation),
AddressTranslationServices(AddressTranslationServices),
SingleRootIoVirtualization(SingleRootIoVirtualization),
MultiRootIoVirtualization(MultiRootIoVirtualization),
Multicast(Multicast),
PageRequestInterface(PageRequestInterface),
ReservedForAmd(ReservedForAmd),
ResizableBar(ResizableBar<'a>),
DynamicPowerAllocation(DynamicPowerAllocation<'a>),
TphRequester(TphRequester<'a>),
LatencyToleranceReporting(LatencyToleranceReporting),
SecondaryPciExpress(SecondaryPciExpress<'a>),
ProtocolMultiplexing(ProtocolMultiplexing<'a>),
ProcessAddressSpaceId(ProcessAddressSpaceId),
LnRequester(LnRequester),
DownstreamPortContainment(DownstreamPortContainment),
L1PmSubstates(L1PmSubstates),
PrecisionTimeMeasurement(PrecisionTimeMeasurement),
PciExpressOverMphy(PciExpressOverMphy),
FrsQueuing(FrsQueuing),
ReadinessTimeReporting(ReadinessTimeReporting),
DesignatedVendorSpecificExtendedCapability(DesignatedVendorSpecificExtendedCapability<'a>),
VfResizableBar(VfResizableBar<'a>),
DataLinkFeature(DataLinkFeature),
PhysicalLayer16GTps(PhysicalLayer16GTps),
LaneMarginingAtTheReceiver(LaneMarginingAtTheReceiver),
HierarchyId(HierarchyId),
NativePcieEnclosureManagement(NativePcieEnclosureManagement),
PhysicalLayer32GTps(PhysicalLayer32GTps),
AlternateProtocol(AlternateProtocol),
SystemFirmwareIntermediary(SystemFirmwareIntermediary),
ShadowFunctions(ShadowFunctions),
DataObjectExchange(DataObjectExchange),
Device3(Device3),
IntegrityAndDataEncryption(IntegrityAndDataEncryption),
PhysicalLayer64GTps(PhysicalLayer64GTps),
FlitLogging(FlitLogging),
FlitPerformanceMeasurement(FlitPerformanceMeasurement),
FlitErrorInjection(FlitErrorInjection),
Reserved(u16),
}
pub mod advanced_error_reporting;
pub use advanced_error_reporting::AdvancedErrorReporting;
pub mod virtual_channel;
pub use virtual_channel::VirtualChannel;
pub mod device_serial_number;
pub use device_serial_number::DeviceSerialNumber;
pub mod power_budgeting;
pub use power_budgeting::PowerBudgeting;
pub mod root_complex_link_declaration;
pub use root_complex_link_declaration::RootComplexLinkDeclaration;
pub mod root_complex_internal_link_control;
pub use root_complex_internal_link_control::RootComplexInternalLinkControl;
pub mod root_complex_event_collector_endpoint_association;
pub use root_complex_event_collector_endpoint_association::RootComplexEventCollectorEndpointAssociation;
pub mod multifunction_virtual_channel;
pub use multifunction_virtual_channel::MultifunctionVirtualChannel;
pub mod root_complex_register_block_header;
pub use root_complex_register_block_header::RootComplexRegisterBlockHeader;
pub mod vendor_specific_extended_capability;
pub use vendor_specific_extended_capability::VendorSpecificExtendedCapability;
pub mod configuration_access_correlation;
pub use configuration_access_correlation::ConfigurationAccessCorrelation;
pub mod access_control_services;
pub use access_control_services::AccessControlServices;
pub mod alternative_routing_id_interpolation;
pub use alternative_routing_id_interpolation::AlternativeRoutingIdInterpretation;
pub mod address_translation_services;
pub use address_translation_services::AddressTranslationServices;
pub mod single_root_io_virtualization;
pub use single_root_io_virtualization::SingleRootIoVirtualization;
pub mod multi_root_io_virtualization {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct MultiRootIoVirtualization;
}
pub use multi_root_io_virtualization::MultiRootIoVirtualization;
pub mod multicast;
pub use multicast::Multicast;
pub mod page_request_interface;
pub use page_request_interface::PageRequestInterface;
pub mod reserved_for_amd {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ReservedForAmd;
}
pub use reserved_for_amd::ReservedForAmd;
pub mod resizable_bar;
pub use resizable_bar::ResizableBar;
pub mod dynamic_power_allocation;
pub use dynamic_power_allocation::DynamicPowerAllocation;
pub mod tph_requester;
pub use tph_requester::TphRequester;
pub mod latency_tolerance_reporting;
pub use latency_tolerance_reporting::LatencyToleranceReporting;
pub mod secondary_pci_express;
pub use secondary_pci_express::SecondaryPciExpress;
pub mod protocol_multiplexing;
pub use protocol_multiplexing::ProtocolMultiplexing;
pub mod process_address_space_id;
pub use process_address_space_id::ProcessAddressSpaceId;
pub mod ln_requester;
pub use ln_requester::LnRequester;
pub mod downstream_port_containment;
pub use downstream_port_containment::DownstreamPortContainment;
pub mod l1_pm_substates;
pub use l1_pm_substates::L1PmSubstates;
pub mod precision_time_measurement;
pub use precision_time_measurement::PrecisionTimeMeasurement;
pub mod pci_express_over_m_phy;
pub use pci_express_over_m_phy::PciExpressOverMphy;
pub mod frs_queuing;
pub use frs_queuing::FrsQueuing;
pub mod readiness_time_reporting;
pub use readiness_time_reporting::ReadinessTimeReporting;
pub mod designated_vendor_specific_extended_capability;
pub use designated_vendor_specific_extended_capability::DesignatedVendorSpecificExtendedCapability;
pub mod vf_resizable_bar {
pub type VfResizableBar<'a> = super::ResizableBar<'a>;
pub type VfResizableBarError = super::resizable_bar::ResizableBarError;
}
pub use vf_resizable_bar::VfResizableBar;
pub mod data_link_feature {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DataLinkFeature;
}
pub use data_link_feature::DataLinkFeature;
pub mod physical_layer_16_gtps {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PhysicalLayer16GTps;
}
pub use physical_layer_16_gtps::PhysicalLayer16GTps;
pub mod lane_margining_at_the_receiver {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LaneMarginingAtTheReceiver;
}
pub use lane_margining_at_the_receiver::LaneMarginingAtTheReceiver;
pub mod hierarchy_id {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct HierarchyId;
}
pub use hierarchy_id::HierarchyId;
pub mod native_pcie_enclosure_management {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NativePcieEnclosureManagement;
}
pub use native_pcie_enclosure_management::NativePcieEnclosureManagement;
pub mod physical_layer_32_gtps {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PhysicalLayer32GTps;
}
pub use physical_layer_32_gtps::PhysicalLayer32GTps;
pub mod alternate_protocol {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AlternateProtocol;
}
pub use alternate_protocol::AlternateProtocol;
pub mod system_firmware_intermediary {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SystemFirmwareIntermediary;
}
pub use system_firmware_intermediary::SystemFirmwareIntermediary;
pub mod shadow_functions {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ShadowFunctions;
}
pub use shadow_functions::ShadowFunctions;
pub mod data_object_exchange {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DataObjectExchange;
}
pub use data_object_exchange::DataObjectExchange;
pub mod device_3 {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Device3;
}
pub use device_3::Device3;
pub mod integrity_and_data_encryption {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct IntegrityAndDataEncryption;
}
pub use integrity_and_data_encryption::IntegrityAndDataEncryption;
pub mod physical_layer_64_gtps {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PhysicalLayer64GTps;
}
pub use physical_layer_64_gtps::PhysicalLayer64GTps;
pub mod flit_logging {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FlitLogging;
}
pub use flit_logging::FlitLogging;
pub mod flit_performance_measurement {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FlitPerformanceMeasurement;
}
pub use flit_performance_measurement::FlitPerformanceMeasurement;
pub mod flit_error_injection {
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FlitErrorInjection;
}
pub use flit_error_injection::FlitErrorInjection;
#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;
use std::prelude::v1::*;
const DATA: &[u8] = include_bytes!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/data/device/8086_2030/config"
));
#[test]
fn iterator() {
let ecaps = ExtendedCapabilities::new(DATA[ECS_OFFSET..].try_into().unwrap());
let sample = vec![
Ok((0x100, 0x000b)),
Ok((0x110, 0x000d)),
Ok((0x148, 0x0001)),
Ok((0x1d0, 0x000b)),
Ok((0x250, 0x0019)),
Ok((0x280, 0x000b)),
Ok((0x298, 0x000b)),
Ok((0x300, 0x000b)),
];
let result = ecaps
.map(|ecap| ecap.map(|ecap| (ecap.offset, ecap.id())))
.collect::<Vec<_>>();
assert_eq!(sample, result);
}
}