PCIe 配置空间机制
PCIe 配置空间是每个设备功能Function独立拥有的 4KB4096 字节标准化寄存器集合是系统枚举、识别、分配资源与控制设备的核心接口前 256 字节兼容传统 PCI后 3840 字节为 PCIe 扩展区域。核心作用设备识别存储厂商 ID、设备 ID、类别码用于驱动匹配。资源分配通过 BAR 寄存器分配内存 / I/O 地址、中断MSI/MSI‑X。功能控制配置电源管理、链路状态、错误报告、虚拟化SR‑IOV等。枚举初始化BIOS/OS 扫描配置空间完成设备发现与初始化。整体结构4KB地址范围区域名称说明0x00–0xFF256 字节PCI 兼容配置空间与 PCI 完全兼容含标准头与 PCI 能力链表0x100–0xFFF3840 字节PCIe 扩展配置空间PCIe 特有存放扩展能力AER、VC、SR‑IOV 等PCI 兼容区0x00–0xFF1标准配置头0x00–0x3F64 字节分 **Type 0端点设备与Type 1桥 / 交换机** 两种结构。关键寄存器Type 00x00–0x03Vendor ID厂商 IDDevice ID设备 ID只读驱动匹配核心。0x04–0x05Command命令Status状态使能内存 / I/O 访问、总线主控、中断反映能力、错误、中断 pending 等。0x08Class Code类别码3 字节定义设备类型如 0x02 网卡、0x01 存储。0x0DHeader Type头类型bit71 表示多功能设备bit6–00Type0/1Type1。0x10–0x24BAR基地址寄存器共 6 个分配内存 / I/O 空间、标记 64 位 / 可预取、大小。0x34Capability Pointer能力指针指向 PCI 能力链表首块偏移0x40 起。2PCI 能力链表0x40–0xFF以Capability Pointer为入口的单向链表每个能力块含Capability ID1 字节、Next Pointer1 字节、能力寄存器。常见 ID0x01PM电源管理、0x05MSI、0x11MSI‑X。PCIe 扩展区0x100–0xFFF仅通过ECAM访问不兼容传统 I/O 端口方式。首 4 字节0x100–0x103为扩展能力链表头结构同 PCI 能力但支持更大空间。常见扩展能力AER高级错误报告、VC虚拟通道、SR‑IOV单根 IO 虚拟化、PCIe 链路控制。PCI/PCIe 配置头类型配置头类型在配置空间偏移 0x0E1 字节决定了 0x10~0xFF 这一段的布局格式。偏移0x0E位定义bit 0~6Header Type配置头类型bit 7MF 位Multi-Function1 表示这是一个多功能设备一个 BDF 下有多个 funcType 0 → 0x00最常见适用端点设备Endpoint网卡、显卡、NVMe、USB 控制器、GPU 等都是 Type 0。布局0x00~0x3F0x00: VID/DID 0x04: Command/Status 0x08: RevID/ClassCode 0x0C: CacheLine/LatencyTimer/HeaderType 0x10: BAR0 0x14: BAR1 0x18: BAR2 0x1C: BAR3 0x20: BAR4 0x24: BAR5 0x28: CardBus CIS Pointer 0x2C: Subsystem VID/DID 0x30: Expansion ROM BAR 0x34: Capabilities Pointer 0x38: Reserved 0x3C: Interrupt Line/PIN/Min_Gnt/Max_Lat特点有6 个 BAR0~5用于普通功能设备配置头类型 0最常见普通端点 / 交换机偏移长度字段作用0x002Vendor ID厂商 ID如 Intel0x80860x022Device ID设备 ID0x042Command总线主控、MMIO、IO 使能0x062Status能力链表存在、中断状态0x081Revision ID硬件版本0x093Class Code设备类型网卡 / 显卡 / 存储0x0D1Cache Line Size缓存行大小0x0E1Latency Timer延迟计时器0x0F1Header Type配置头类型0 普通设备0x10 ~ 0x276×4BAR0~BAR5地址空间MMIO/IO0x2C2Subsystem Vendor ID子系统厂商0x2E2Subsystem ID子系统设备0x304Expansion ROM固件 ROM 基地址0x341Capabilities Pointer能力链表首地址0x3C1Interrupt Line中断号0x3D1Interrupt Pin中断引脚Type 1 → 0x01PCIe 桥片专用适用PCIe 根端口、交换机下游端口、PCI-to-PCI 桥0x10: BAR0 0x14: BAR1 0x18: Primary Bus Number 0x19: Secondary Bus Number 0x1A: Subordinate Bus Number 0x1B: Secondary Latency Timer 0x1C: I/O Base 0x1D: I/O Limit 0x1E: Secondary Status 0x20: Memory Base 0x22: Memory Limit 0x24: Prefetchable Memory Base 0x26: Prefetchable Memory Limit 0x28: Prefetchable Base Upper 32 0x2C: Prefetchable Limit Upper 32 0x30: I/O Base Upper 16 0x32: I/O Limit Upper 16 0x34: Capability Pointer 0x38: Expansion ROM BAR 0x3C: Interrupt Line / Interrupt Pin特点只有2 个 BAR核心是总线号、IO/MEM 窗口用于路由下游总线事务所有 PCIe Switch Up/Downstream Port 都是 Type 1Type 2 → 0x02CardBus 桥适用古老的 CardBusPC 卡桥片现代 PCIe 设备基本见不到。访问机制1. 传统 PCI 方式仅访问 0x00–0xFFx86通过I/O 端口 0xCF8CONFIG_ADDRESS与0xCFCCONFIG_DATA。地址格式0x80000000 | (bus16) | (device11) | (function8) | (offset0xFC)。2. ECAM增强配置访问机制PCIe 标准将整个 4KB 配置空间映射到系统内存地址通过 MMIO 访问。基地址由 ACPI 的MCFG 表提供。地址计算ECAM基地址 (bus20) | (device15) | (function12) | 寄存器偏移。关键概念Function功能一个物理设备可含多个独立功能如网卡 RAID每个功能有独立 4KB 配置空间。Capability能力设备支持的扩展功能以链表组织按需遍历发现。BAR 空间设备映射到系统的内存 / I/O 窗口驱动通过 BAR 访问设备寄存器。PCIeECAMECAM 基地址MMCONFIG是固件BIOS/UEFI通过ACPI MCFG 表通告给系统的物理内存基地址用于通过内存映射MMIO访问完整 4KB PCIe 配置空间。核心信息速览来源ACPI MCFG 表Memory-Mapped Configuration Space Base Address Description Table平台差异x86 显示为PCI MMCONFIGARM64 显示为PCI ECAM地址计算ECAM_BASE (Bus 20) (Dev 15) (Func 12) Offset单设备空间每 BDF 对应4KB连续配置空间ECAM 配置空间本身的基地址不在配置空间里而是系统固件 / ACPI 告诉你的位于 ACPI 表MCFG Table每个 PCIe 总线段有一个Base Address Start Bus End Bus典型大小每个总线 1MB1024KBARM64 的ECAM 基地址是 PCIe 配置空间的内存映射物理基地址由ACPI MCFG 表或Device TreeDT提供Linux 下可直接查看与解析。ECAM 基地址绝大多数 ARM64 平台都是硬件固定的软件只能 “读”不能改。它不是 PCIe 设备自己决定的而是PCIe Host Controller / 系统集成硬件在设计时就写死在地址映射里。为什么是硬件固化ECAM 是CPU 物理地址空间 → PCIe 配置空间的硬件映射这个映射关系在SoC 内部总线AXI/NoC上就定死了地址由芯片设计工程师分配出厂就不能改固件UEFI/ATF/UBoot只能告知系统这个地址是多少不能修改它所以ECAM Base 硬件固定地址ACPI MCFG / Device Tree 只是把这个固定地址告诉操作系统ARM64 ECAM 核心规则标准ARM64 服务器 / UEFI 平台强制用ECAM无传统 0xCF8/0xCFC 端口。地址公式物理地址ECAM_BASE (Bus 20) | (Dev 15) | (Func 12) Offset每个BDF占4KB0x1000完整 4KB 配置空间。多段一个系统可有多段 ECAM多 PCIe 域 / 多 Host Bridge。Device Tree嵌入式 / 非 ACPI 平台查看 DTB 中 PCI 节点的reg属性dtc -I dtb -O dts /sys/firmware/fdt | grep -A 10 pcie典型节点pcie23fff0000000 { compatible pci-host-ecam-generic; device_type pci; reg 0x23ff 0xf0000000 0x0 0x10000000; // ECAM 基地址大小 bus-range 0x0 0xff; };ECAM 地址计算ECAM_Base (Bus 20) | (Device 15) | (Function 12) 寄存器偏移这就是整个 4KB 配置空间在内存中的物理基地址。ECAM 基地址与配置空间地址ECAM 基地址 整个 PCIe 配置空间区域的起始物理地址配置空间地址 ECAM 基地址 BDF 偏移 寄存器偏移ECAM 基地址是硬件固定的大窗口配置空间地址是窗口里某个具体设备的某个寄存器。ECAM 基地址硬件固定ARM64 硬件写死的一段物理地址例如0x200000000、0x60000000、0x4010000000它代表从这个地址开始往后一大片空间全部映射到 PCIe 配置空间这片空间的布局是按总线号固定排布的1 条总线bus占用1MB 2²⁰1 个设备dev占用32KB 2¹⁵1 个功能func占用4KB 2¹²所以 ECAM 基地址是整个配置区域的根。配置空间地址公式是 ARM64/PCIe 标准固定的配置空间地址 ECAM 基地址 (bus 20) (dev 15) (func 12) 寄存器偏移bus 20→ 每条总线占 1MBdev 15→ 每个设备占 32KBfunc 12→ 每个功能占 4KB偏移 0~0xFFF → 该功能的 4KB 配置空间传统 PCI I/O 端口基地址x86 legacy 方式地址端口0xCF8数据端口0xCFC这是访问前 256 字节配置空间的端口基地址不是内存基地址。典型访问流程Linux读取Vendor ID/Device ID识别设备。解析Class Code确定设备类型。遍历Capability 链表获取 PM、MSI‑X 等能力。配置Command 寄存器使能内存 / 总线主控。分配BAR并映射到内核虚拟地址。配置PCIe 扩展能力AER、链路速度等。能力指针标准能力能力指针Capability Pointer是 PCI/PCIe 配置空间中用于定位能力结构Capability Structure链表的入口字段是枚举设备高级功能如 MSI、PM、PCIe 链路、SR-IOV的核心机制。基础定位与定义1. 位置与格式偏移地址PCI 兼容配置空间0x00–0xFF的0x341 字节只读。含义存储第一个能力结构的起始偏移必须 4 字节对齐范围 0x40–0xFF。使能标志配置头 0x06Status 寄存器的Bit41表示设备支持能力链表。2. 能力结构通用头部所有能力一致每个能力结构的前 2 字节固定为偏移 0Cap ID1 字节能力类型PCI-SIG 分配如 0x01PM、0x05MSI、0x10PCIe。偏移 1Next Pointer1 字节下一个能力结构的偏移0x00表示链表结束。工作机制链表遍历读取配置空间0x34得到第一个能力的偏移cap_ptr。若cap_ptr0无能力否则进入循环读取cap_ptr处的Cap ID识别能力类型。读取cap_ptr1处的Next Pointer更新cap_ptr。直到Next Pointer0遍历完成。常见能力 ID 与结构Cap ID能力名称典型偏移核心用途0x01PCI Power Management0x40电源管理D0/D1/D2/D30x05MSI0x50消息信号中断替代引脚中断0x10PCI Express (PCIe)0x70PCIe 链路、设备控制与状态0x11MSI-X0x80扩展 MSI支持更多中断向量0x14SR-IOV0xA0单根 IO 虚拟化PF/VF与扩展能力Extended Capability的区别标准能力Capability位于0x00–0xFF由0x34 指针引导1 字节 ID1 字节 Next Pointer。扩展能力Extended Capability位于0x100–0xFFF由0x100处的Extended Capability Pointer引导2 字节 ID2 字节 Next Pointer用于 AER、ACS、PHY 等高级特性。扩展能力PCIe 扩展能力是位于 PCIe 扩展配置空间0x100–0xFFF的高级功能链表用于实现 AER、ACS、SR-IOV、PHY 等 PCI 标准能力无法容纳的增强特性通过固定入口与 2 字节 ID / 指针的链表遍历访问。基础定位与空间范围位置PCIe 扩展配置空间偏移 0x100 开始前 256 字节为标准 PCI 兼容区。大小扩展区共3840 字节0x100–0xFFF整个 PCIe 配置空间为4KB0x000–0xFFF。入口第一个扩展能力固定从 0x100 开始无单独指针寄存器。扩展能力结构通用头部每个扩展能力的前4 字节DWORD为固定头部格式如下偏移位宽字段名说明016 位Extended Cap ID能力类型PCI-SIG 分配如 0x0001AER24 位Capability Version该能力的版本号区分不同规范版本212 位Next Capability Offset下一个扩展能力的DWORD 偏移0 表示链表结束关键约束偏移以DWORD4 字节为单位实际地址 0x100 Next Offset × 4。必须4 字节对齐Next Offset 为整数。最后一个能力的Next Offset 0。遍历流程1. 标准能力Capability入口0x341 字节→ 第一个能力偏移0x40–0xFF。头部1 字节 ID 1 字节 Next Pointer字节偏移。范围0x00–0xFF。2. 扩展能力Extended Capability入口固定 0x100无指针寄存器。头部2 字节 ID 4 位版本 12 位 Next OffsetDWORD 偏移。范围0x100–0xFFF。常见扩展能力 ID 与用途Ext Cap ID名称核心用途适用场景0x0001AERAdvanced Error Reporting高级错误报告记录链路 / 事务错误服务器、高可靠设备0x0002VCVirtual Channel虚拟通道链路 QoS 与流量隔离网络、存储、实时系统0x0003Device Serial Number设备唯一序列号资产识别、安全认证0x0004Power Budgeting电源预算管理系统功耗分配、热设计0x000DACSAccess Control Services访问控制服务阻断非法 P2P 访问虚拟化、安全隔离0x000EARIAlternative Routing-ID Interpretation扩展路由 ID支持 8 个 Function高密度设备、SR-IOV0x0010PHY/Lane Margining物理层裕度测试信号质量调试高速链路、信号完整性分析0x001ASR-IOV单根 IO 虚拟化PF/VF云平台、网络虚拟化0x001FLTRLatency Tolerance Reporting延迟容忍报告优化电源管理移动 / 低功耗设备与标准能力的核心区别特性标准能力Capability扩展能力Extended Capability空间0x00–0xFF256 字节0x100–0xFFF3840 字节入口0x341 字节指针固定 0x100头部1 字节 ID 1 字节 Next字节偏移2 字节 ID 4 位版本 12 位 NextDWORD 偏移功能基础功能PM、MSI、PCIe高级 / 可选特性AER、ACS、SR-IOV遍历单位字节DWORD4 字节PCIe 配置空间总结图0x000 ~ 0x0FF标准配置空间 ├── 厂商ID/设备ID ├── BAR 地址 ├── 0x34 能力指针 └── 能力链表PM、MSI、PCIe 0x100 ~ 0xFFF扩展配置空间 └── 扩展能力链表AER、ACS、SR-IOV、LTR...Expansion ROMExpansion ROM 就是PCI 扩展 ROM俗称Option ROM主要用于设备在系统启动阶段初始化、提供固件驱动网卡 PXE、RAID 卡、显卡 VBIOS 等。它在配置空间里是一个标准 BAR 类寄存器位置和解析规则固定。位置Type 0 头端点设备偏移0x304 字节Type 1 头PCI/PCIe 桥偏移0x384 字节寄存器格式32bit位置Type0 端点0x3032bitType1 桥片0x3832bit格式31 11 10 1 0 ┌───────────────────┬───────────┬─┐ │ ROM 基地址 │ 保留 │E│ └───────────────────┴───────────┴─┘EBit0ROM 使能位0 不映射到地址空间1 映射到 CPU 物理地址Bit1~10保留Bit11~31ROM 基地址必须按2KB 对齐低 11 位为 0读出全 0 → 设备无扩展 ROMROM 空间结构读取到的镜像格式映射到内存后ROM 镜像开头是固定结构两字节签名0x55 0xAA标志这是一个合法 PCI Option ROM第三字节ROM 大小以 512 字节为单位接下来是入口点、PCI 数据结构、初始化代码等典型用途网卡PXE 网络启动显卡VBIOS初始化显示输出RAID/HBA 卡BIOS 配置界面 引导支持NVMe 设备部分有 NVMe 启动 ROM映射的完整流程1. 读出当前 ROM BARuint32_t rom_bar pci_read_config_dword(bdf, 0x30);2. 写入全 1获取 ROM 大小和 BAR 一样要先探测大小pci_write_config_dword(bdf, 0x30, 0xFFFFFFFF); uint32_t rom_mask pci_read_config_dword(bdf, 0x30); uint32_t rom_size ~(rom_mask 0xFFFFF800) 1;ROM 大小一定是2KB 的整数倍常见2KB / 8KB / 16KB / 32KB / 64KB3. 分配一段 CPU 物理地址BIOS 或驱动分配一段空闲物理地址例如0xFD0000004. 写入基地址先关闭使能uint32_t rom_base 0xFD000000; pci_write_config_dword(bdf, 0x30, rom_base);此时 Bit0 0还没映射。5. 使能映射Bit0 1pci_write_config_dword(bdf, 0x30, rom_base | 1);映射完成后发生了什么CPU 访问物理地址0xFD000000 ~ 0xFD00FFFF地址被PCIe 桥路由到该设备设备返回Option ROM 内容如 PXE、VBIOS、RAID ROM你可以直接memcpy读出来uint8_t *rom_virt ioremap(rom_base, rom_size); // 现在 rom_virt 指向映射后的 ROM 镜像Interrupt Line / Interrupt Pin这两个寄存器都在标准配置空间偏移 0x3C专门用于传统 PCI 引脚中断INTx和 MSI/MSI-X 无关。位置与格式偏移0x3C ~ 0x3F4 字节偏移长度寄存器名说明0x3C1Interrupt Line中断线号交给系统软件用0x3D1Interrupt Pin使用哪个 INTx 引脚0x3E1Min_GntPCI 传统请求周期PCIe 无用0x3F1Max_LatPCI 传统延迟PCIe 无用Interrupt Pin中断引脚偏移0x3D只读硬件固定取值含义0x00设备不使用 INTx 引脚中断0x01INTA#0x02INTB#0x03INTC#0x04INTD#关键要点PCI/PCIe 设备最多 4 个中断引脚INTA ~ INTD绝大多数设备只用INTA#0x01多功能设备会分配 INTB/INTC/INTDPCIe 里没有真正的物理引脚只是虚拟 INTx 消息如果设备用 MSI/MSI-X此字段依然可读但一般不再使用Interrupt Line中断线号偏移0x3C可读可写含义这是系统固件 / OS 写入的值设备本身不解析、不使用本质是告诉驱动 “这个 INTx 最终被路由到 CPU 的哪条 IRQ”典型值0 ~ 15ISA 传统 IRQ现代系统一般映射到APIC 中断号工作流程BIOS / 内核在枚举 PCI 时根据路由表填写 Interrupt Line驱动读取它知道 “我这个设备的引脚中断对应 IRQ xx”驱动注册 IRQ handler设备触发 INTx → 中断控制器 → CPU 触发对应 IRQPCIe 与 INTx 的特别说明PCIe 没有真正的物理中断引脚INTx 是通过PCIe Message 信号模拟的Assert_INTA、Deassert_INTAInterrupt Pin 是硬件固定的驱动不能改只能读。Interrupt Line 是软件配置的设备不关心只用于驱动和系统沟通。现代驱动基本不用这俩优先 MSI/MSI-X更高效、支持多向量、不共享中断。