1.PCIe ECAM机制
PCI Express Enhanced Configuration Access Mechanism (ECAM)是访问PCIe配置空间的一种机制。是将PCIe的配置空间映射到MEM空间,使用MEM访问其配置空间的一种实现。可参考NCB-PCI_Express_Base_5.0r1.0-2019-05-22.pdf的第7.2.2小节。
其地址映射如下图所示:
根据上图,可以根据一个PCIe设备的BDF得到其配置空间偏移地址:
#define PCI_ECAM_ADDRESS(Bus,Device,Function,Offset) \
(((Offset) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))
2.PCIe ECAM基地址
查看一台主机是否支持PCIe ECAM机制,可通过以下命令查看:
- 2.1.对于x86主机:
sudo cat /proc/iomem | grep MMCONFIG
若支持ECAM,则会出现类似以下字段:
f8000000 - fbffffff : PCI MMCONFIG 0000 [bus 00-3f]
其中0xf8000000就是该主机下PCIe ECAM的基地址。加上PCI_ECAM_ADDRESS(bus, device, func, reg),就得到了指定PCIe设备的物理地址,可以使用此地址直接访问其配置空间。
- 2.2.对于ARM64主机:
sudo cat /proc/iomem | grep ECAM
若支持ECAM,则会出现以下字段:
40000000-4fffffff : PCI ECAM
其中0x40000000就是该主机下PCIe ECAM的基地址。加上PCI_ECAM_ADDRESS(bus, device, func, reg),就得到了指定PCIe设备的物理地址,可以使用此地址直接访问其配置空间。
3.linux下使用devmem2工具读取PCIe配置空间的寄存器。
-
3.1 devmem2读数据用法
devmem2 address [ type ]
参数说明:
address : 物理地址
type :要访问的数据类型 : [b]yte, [h]alfword, [w]ord -
3.2.devmem2写数据用法
devmem2 address type data
参数说明:
address : 物理地址
type :要访问的数据类型 : [b]yte, [h]alfword, [w]ord
data :想要写入的数据 -
3.3.devmem2读写BDF=1:0:0的PCIe的配值空间,假设ECAM_BASE = 0x40000000
3.3.1. 读取venderid和deviceid,reg =0x00:
offset = PCI_ECAM_ADDRESS(1, 0, 0, 0) = 0x100000sudo devmem2 0x40100000 w
3.3.2. 读取BAR0,reg =0x10:
offset = PCI_ECAM_ADDRESS(1, 0, 0, 0x10) = 0x100010sudo devmem2 0x40100010 w
3.3.3. Enable Expansion ROM,reg =0x30:
offset = PCI_ECAM_ADDRESS(1, 0, 0, 0x30) = 0x100030
获取Expansion ROM基地址:sudo devmem2 0x40100030 w
假设读出的值为0x60800000。
以下命令使能Expansion ROMsudo devmem2 0x40100030 w 0x60800001
4.linux内核中对ECAM的实现
代码路径:drivers\pci\ecam.c