1. PCIe配置空间全景


每个PCIe Function有256字节配置空间(Type0 EP)或4KB配置空间(Type1 RC/Bridge):
1.1 配置空间分区域
- 0x000-0x003:Vendor ID / Device ID(只读,识别设备)
- 0x004-0x007:Command / Status(最常用的控制寄存器)
- 0x008-0x00B:Class Code / Revision ID(设备类别)
- 0x00C-0x00D:BIST / Header Type / Latency Timer
- 0x010-0x027:BAR0~BAR5(6个基地址寄存器)
- 0x028-0x02F:Cardbus CIS Pointer
- 0x034-0x035:Expansion ROM Base Address
- 0x03C-0x03D:Max Latency / Min Grant / Interrupt Pin / Interrupt Line
- 0x040-0x0FF:PCIe Capabilities Chain(链式结构)
- 0x100-0xFFF:PCIe Extended Capabilities(扩展能力)
────────────────────────────────────────────────────────────
2. Command寄存器:设备使能的开关
Command寄存器(Offset 0x004)是调试时最常看的寄存器:
|---------|-----------------------|-------------|----------------|
| Bit | 名称 | 说明 | 调试注意事项 |
| 0 | I/O Space | IO空间使能(已淘汰) | 现代设备保持0 |
| 1 | Memory Space | Memory空间使能 | 必须设为1才能访问BAR |
| 2 | Bus Master | 总线主控使能 | EP发起请求必须置1 |
| 6 | Parity Error Response | 奇偶校验错误响应 | 建议设为1 |
| 8 | SERR# Enable | 系统错误报告使能 | 建议设为1 |
| 10 | Interrupt Disable | INTx中断禁止 | 使用MSI/MSI-X时置1 |
典型调试场景:BAR读返回全F?先检查Command寄存器的Memory Space Enable位是否为1!
────────────────────────────────────────────────────────────
3. BAR(Base Address Register)完全指南
3.1 BAR发现流程
BAR是系统发现设备地址空间需求的机制,分为两步:
- Step 1:软件向BAR写入全1(0xFFFFFFFF)
- Step 2:设备返回需要的地址范围掩码(只读位保持为1,可写位显示粒度)
- Step 3:软件根据掩码分配可用物理地址
- Step 4:软件将分配的地址写回BAR
以一个需要256MB Memory空间的设备为例:
软件写入 BAR: 0xFFFFFFFF
设备返回(只读位): 0xF000_0000
↑______256MB粒度(1<<28)
软件分配物理地址: 0xD000_0000
软件写回 BAR: 0xD000_0000
→ CPU访问0xD000_0000~0xD0FF_FFFF即映射到该设备
3.2 BAR位定义
BAR bit 0决定是Memory BAR还是IO BAR:
|---------|--------------------|------------|
| Bit | Memory BAR | IO BAR |
| 0 | 0(表示Memory) | 1(表示IO) |
| 2:1 | 00=32bit, 10=64bit | 保留 |
| 3 | 0=不可预取, 1=可预取 | 保留 |
| 其他 | 基地址(低位为0) | 基地址(低位为0) |
3.3 64-bit BAR
BAR可以链接成64-bit模式,实现超过4GB的地址空间映射:
- BARn(低位)和BARn+1(高位)必须成对使用
- BARn的bit 2:1必须为10b(表示64-bit类型)
- 64-bit BAR的地址可以是64-bit,映射到系统内存任意位置
Synopsys PCIe IP中典型配置:BAR0=1MB寄存器空间,BAR2=64MB用户RAM空间(64-bit)。
────────────────────────────────────────────────────────────
4. iATU(Inbound Address Translation Unit)
iATU是EP端最重要的地址翻译模块,负责将RC发来的PCIe地址翻译为EP内部地址。

4.1 iATU工作原理
iATU维护多个翻译Region,每个Region描述一段PCIe地址到内部地址的映射:
- PCIe Addr Base:RC访问的PCIe地址(必须是对齐的)
- PCIe Addr Limit:区域上限(base+size-1)
- Target Addr:EP内部地址(AXI/内部地址)
- Control:使能/BAR匹配模式/区域号
4.2 iATU配置实例
// Synopsys PCIe IP iATU配置示例
// 将RC侧的0x4000_0000映射到EP AXI地址0x1000_0000,大小64MB
// Region 0: Inbound BAR Match Mode
write32(iatu_base + 0x0, 0xC000_0400); // REGION_EN | MATCH_MODE | BAR4
write32(iatu_base + 0x4, 0x1000_0000); // Target Addr (AXI)
write32(iatu_base + 0x8, 0x4000_0000); // PCIe Addr Base
write32(iatu_base + 0x10, 0x0400_0000-1); // Limit = 64MB-1
// BAR4 Match Mode:
// RC发送MWr/MRd到 BAR4_addr+offset
// → iATU匹配 BAR4+offset
// → 翻译到 Target_Addr+offset
// → EP内部AXI总线访问 Target_Addr+offset
4.3 地址路由 vs iATU
理解两种地址映射的区别:
- BAR配置:告诉系统"这个设备在哪个地址范围",系统分配PCIe地址
- iATU配置:告诉EP"收到的PCIe地址应该翻译成哪个内部地址"
两者配合:BAR确定PCIe地址范围 → iATU把PCIe地址翻译为AXI地址 → EP内部访问正确寄存器/RAM
────────────────────────────────────────────────────────────
5. Type0 vs Type1 Header

配置空间Header Type决定设备类型:
|-------------------|----------------|-----------------------|
| 寄存器 | Type0 (EP) | Type1 (RC/Bridge) |
| Header Type | 0x00 | 0x01 |
| Vendor/Device ID | 设备标识 | 桥的上游标识 |
| BAR0~BAR5 | 设备地址空间 | 无(用作其他功能) |
| Primary Bus | 无 | 上游总线号 |
| Secondary Bus | 无 | 下游总线号 |
| Subordinate Bus | 无 | 子树最大总线号 |
| IO Limit/Base | 无 | IO地址范围 |
| Memory Limit/Base | 无 | Memory地址范围 |
────────────────────────────────────────────────────────────
6. PCIe Extended Capabilities(扩展能力)
PCIe在配置空间0x100之后定义了扩展能力结构,链式组织:
|-------------------|--------------------------|-------------------------|
| Capability ID | 名称 | 说明 |
| 0x0001 | Advanced Error Reporting | 高级错误报告(AER) |
| 0x0002 | VC (Virtual Channel) | 虚拟通道 |
| 0x0003 | Device Serial Number | 设备序列号 |
| 0x0004 | Power Budgeting | 动态功耗预算 |
| 0x0005 | Alternative Routing-ID | ARI(扩大Function数) |
| 0x0006 | ATS | 地址转换服务(虚拟化) |
| 0x0007 | SR-IOV | 单根IO虚拟化 |
| 0x0009 | Multicast | 多播 |
| 0x000B | 饈Time Sync | 时间同步 |
| 0x000D | ACS | Access Control Services |
| 0x0010 | Process Address Space ID | PASID(虚拟化) |
| 0x0015 | L1 PM Substates | L1子状态 |
参考资料:PCI Express Base Spec 5.0 Chapter 7, Synopsys DWC_pcie_ctl Databook Chapter Configuration, Linux PCI Subsystem