如何通过MMIO访问pci express配置空间?

时间:2018-09-02 10:50:19

标签: pci pci-e

我是PCI Express的新手,我想通过MMIO地址读取/写入PCI Express配置空间。我知道如何通过0xCFC和0xCF8端口地址(在x86上)将端口映射的IO读/写到PCI Express配置空间。我还编写了一个示例Linux内核模块,以通过端口映射io读取pci配置空间,效果很好。我想通过MMIO / MMCFG访问来做同样的事情。

我也进行了搜索,但找不到令人信服的答案。我正在寻找详细信息,并且还在寻找一些代码示例以更好地理解它。

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

硬件

ACPI table MCFG中给出了PCI段组中每个PCIe设备的配置空间的MMIO区域的基地址。

MCFG表为每个PCI段组列出了PCI段组的第一个和最后一个(包括)总线号以及扩展配置空间的基址。

BIOS / UEFI根据位于以下位置的主机桥/ DRAM寄存器设备中的PCIEXBAR(对于我的处理器,偏移量为60h)的值来设置MCFG表 00:00.0
这是常用地址,由于Nehalem体系结构,该设备已集成在处理器插槽中,并且从未更改过地址。
您可以使用Google处理器生成数据表,以获取正确的设备地址和寄存器偏移量。

还请注意,并不是所有的256 MiB区域都可以映射,我的处理器允许256/128/64 MiB映射,其中128 MiB是BIOS / UEFI选择的。


Linux

我不知道如何在Linux中正确处理此问题,有pci_{read|write}_config_XXX function函数似乎使用了PCIe扩展配置空间。
因此,访问配置空间应该非常容易。

或者,pci_mcfg_lookup将为PCI网段组和总线范围提供扩展配置空间的物理地址(您应该能够通过仅使用resource定义结构来使其工作。 startend字段设置为总线号。
如果您想要一个较低级别的方法。

最后,您可以获取MCFG表的地址并自己(重新)解析它-确切地说,我不知道如何在Linux中获得这样的地址。
有一个acpi_tb_find_table,您可以在其中传递表的签名以及 null oem和表ID,以获取表索引
在同一文件的第114行,有一段代码可以按索引访问表,您可以将其用作文档。
您可能必须从ACPI模块导入一个或多个符号。