6个版本

0.3.2 2024年5月7日
0.3.1 2022年9月26日
0.3.0 2022年8月30日
0.2.0 2022年6月28日
0.1.0 2022年1月11日

#97硬件支持

Download history 136/week @ 2024-05-04 11/week @ 2024-05-11 88/week @ 2024-05-18 57/week @ 2024-05-25 123/week @ 2024-06-01 60/week @ 2024-06-08 44/week @ 2024-06-15 95/week @ 2024-06-22 61/week @ 2024-06-29 56/week @ 2024-07-06 109/week @ 2024-07-13 100/week @ 2024-07-20 109/week @ 2024-07-27 84/week @ 2024-08-03 99/week @ 2024-08-10 127/week @ 2024-08-17

每月435次下载
pcitool 中使用

MIT 许可证

730KB
14K SLoC

PCI配置空间

PCI配置空间是常规PCI、PCI-X和PCI Express对插入其总线的卡进行自动配置的底层方式。

此库实现了PCI配置空间和PCI Express扩展配置空间的解码。

设计

此库的主要目的是将配置空间数据表示为分层结构。因此,CPU和内存使用可能不是最优的。

该库分为三个部分

使用

# use pcics::{
#     DDR_OFFSET, ECS_OFFSET,
#     capabilities::{
#         bridge_subsystem_vendor_id::BridgeSubsystemVendorId, Capability, CapabilityKind,
#     },
#     extended_capabilities::{
#         vendor_specific_extended_capability::VendorSpecificExtendedCapability,
#         ExtendedCapability, ExtendedCapabilityKind,
#     },
#     Capabilities, ExtendedCapabilities, Header,
# };
let conf_space_data = include_bytes!(concat!(
    env!("CARGO_MANIFEST_DIR"),
    "/tests/data/device/8086_2030/config"
));

let header = Header::try_from(&conf_space_data[..DDR_OFFSET]).unwrap();
assert_eq!((0x8086, 0x2030), (header.vendor_id, header.device_id));

let mut caps = Capabilities::new(&conf_space_data[DDR_OFFSET..ECS_OFFSET], &header);
let BridgeSubsystemVendorId {
    subsystem_vendor_id,
    ..
} = caps
    .find_map(|cap| {
        if let Ok(Capability {
            kind: CapabilityKind::BridgeSubsystemVendorId(ssvid),
            ..
        }) = cap
        {
            Some(ssvid)
        } else {
            None
        }
    })
    .unwrap();
assert_eq!(0x8086, subsystem_vendor_id);

let mut ecaps = ExtendedCapabilities::new(&conf_space_data[ECS_OFFSET..]);
let VendorSpecificExtendedCapability { header, .. } = ecaps
    .find_map(|ecap| {
        if let Ok(ExtendedCapability {
            kind: ExtendedCapabilityKind::VendorSpecificExtendedCapability(vsec),
            ..
        }) = ecap
        {
            Some(vsec)
        } else {
            None
        }
    })
    .unwrap();
assert_eq!(0x0c, header.vsec_length);

模块描述中的更详细使用说明

依赖项

~2MB
~41K SLoC