OF、ACPI、ECAM 与配置空间后端

OF、ACPI、ECAM 与配置空间后端

1. 分层边界

PCI Core 通过struct pci_ops读取配置空间,并不要求 Host 一定使用 ECAM。固件/平台层的任务是:

  1. 描述或发现 Host Bridge;
  2. 提供 bus number 与 CPU/PCI resource windows;
  3. 建立配置空间访问后端;
  4. 描述 INTx/MSI 与 IOMMU 拓扑;
  5. 最终调用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
2
3
4
PCI child address
CPU parent physical address
size
space type/flags

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-parentmsi-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
2
3
4
5
6
7
8
rk3588*.dtsi PCIe node
-> platform_device
-> rk_pcie_probe()
-> 解析 Rockchip/DWC 资源
-> dw_pcie_host_init()
-> devm_of_pci_bridge_init()/Host windows
-> DWC pci_ops(DBI + CFG0/CFG1 iATU)
-> pci_host_probe()

配置访问后端的选择由 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 的通用扫描规则。

文章互动

阅读 --

留言

0 条留言

正在加载留言…