OF、ACPI、ECAM 与配置空间后端
1. 分层边界
PCI Core 通过struct pci_ops读取配置空间,并不要求 Host 一定使用 ECAM。固件/平台层的任务是:
- 描述或发现 Host Bridge;
- 提供 bus number 与 CPU/PCI resource windows;
- 建立配置空间访问后端;
- 描述 INTx/MSI 与 IOMMU 拓扑;
- 最终调用
pci_host_probe()。
RK3588 常用 DT + DWC iATU 路径;标准 ECAM 和 ACPI MCFG 是其它可选后端,三者不能混为一套实现。
2. Device Tree:of.c
of.c把 DT PCI 节点转换为 PCI Core 可用信息,主要包括:
- domain/segment 与 bus-range;
ranges中的 I/O、MEM、Prefetchable MEM 窗口;- CPU 地址与 PCI Bus Address offset;
interrupt-map中的 INTx 路由;- MSI domain;
- OF 节点与扫描所得
pci_dev关联; - 最大链路速率等通用属性。
关键辅助函数:
devm_of_pci_bridge_init():of.c:591;of_pci_get_max_link_speed():619 行;of_irq_parse_and_map_pci():529 行;pci_host_bridge_of_msi_domain():79 行。
解析 DT 只建立软件描述,不能替代 regulator、clock、reset、PHY 和链路训练。
3. ranges地址转换
一个 DT range 同时包含:
1 | PCI child address |
Core 将其登记为 Host Bridge window,并保存 offset。BAR 资源在 Linux 中通常以 CPU 物理地址表示,写回 BAR 时再转换为 PCI Bus Address。DWC Host 还需配置 outbound iATU,使 CPU 实际访问与该转换一致。
常见错误:
- child/parent 地址填反;
- 32 位窗口无法容纳 64 位 BAR;
- Prefetchable flag 丢失;
- 多个 Host 的 CPU 窗口重叠;
- DT range 正确但 iATU region 未覆盖。
4. INTx、MSI 与 IOMMU 固件描述
interrupt-map按 BDF/Interrupt Pin 映射 INTA~INTD;msi-parent或msi-map选择 MSI domain;iommu-map把 PCI Requester ID 映射为 IOMMU Stream ID;- 三者都与 BDF/rid 路由相关,但分别管理线中断、消息中断和 DMA 翻译。
只修正 MSI 映射不会解决 IOMMU fault;只看到 IOMMU group 也不能证明 Endpoint IRQ 正常。
5. 通用 ECAM:ecam.c
ECAM 为每个 Function 提供标准 MMIO 配置窗口:
1 | offset = bus << 20 | device << 15 | function << 12 | register |
主要入口:
pci_ecam_create():ecam.c:42;pci_ecam_map_bus():191 行。
pci_ecam_create()验证 bus range、计算窗口大小并映射资源;pci_generic_config_read/write再通过map_bus返回的地址访问配置空间。
ECAM 映射通常只用于 Configuration Space,不能当作设备 BAR Memory Space。
6. ACPI 与 MCFG
ACPI 系统通常通过:
- MCFG:给出 PCI Segment 的 ECAM 地址;
_CRS:Host Bridge I/O/MEM windows;_PRT:INTx 路由;_OSC:固件与 OS 协商 AER、Hotplug、PME 等原生控制;_DSM:平台或 EDR 等扩展协作。
本目录pci-acpi.c处理 PCI 设备 ACPI companion、PM/唤醒及平台协作。架构 ACPI PCI root 创建逻辑还分布在drivers/acpi/pci_root.c等目录,不能仅阅读drivers/pci/pci-acpi.c就认为覆盖完整 Host 枚举。
acpi_pci_root_get_mcfg_addr()位于pci-acpi.c:108,用于获取 Root 对应 MCFG 信息。
7. 非标准 ECAM Quirk
部分控制器对 Root Port 和下游配置空间使用不同访问方式,不能直接套标准 ECAM。ARM64 ACPI + PCI quirks 下,本树会编入pcie-dw-rockchip-acpi.c:
rk_pcie_ecam_init():78 行;rk_pcie_ecam_map_bus():153 行;- Root Port 可转向 DBI;
- 下游 BDF 通过 DWC iATU/MCFG 窗口访问。
这属于 ACPI MCFG quirk,不等于 RK3588 DT 启动的pcie-dw-rockchip.c主路径。
8. RK3588 DT 主链
1 | rk3588*.dtsi PCIe node |
配置访问后端的选择由 Host 驱动决定。虽然 DTS compatible 含snps,dw-pcie,并不表示该节点自动走ecam.c的标准pci_ecam_map_bus()。
9. 排障判据
| 现象 | 固件/后端检查 |
|---|---|
| Root Port 不出现 | Host probe、DBI、bus-range、domain |
| Root Port 有而 Endpoint 无 | CFG0/CFG1 map、iATU、链路 |
| BAR 地址异常 | DT ranges/_CRS 与 offset |
| INTx 无法触发 | interrupt-map/_PRT 和 swizzle |
| MSI 申请失败 | msi-map/msi-parent 与 IRQ domain |
| DMA IOMMU fault | iommu-map、RID/Stream ID |
| AER/Hotplug 未接管 | ACPI _OSC 或pcie_ports=策略 |
10. 修改原则
- 平台电源和 PHY 差异放控制器 glue;
- 通用 DT 解析留在
of.c; - 标准 ECAM 保持规范寻址;
- 非标准配置访问用受限 compatible/ACPI quirk;
- 不为修一块板而改变所有 Host Bridge 的通用扫描规则。
正在加载留言…