我是PCI Express的新手,我想通过MMIO地址读取/写入PCI Express配置空间。我知道如何通过0xCFC和0xCF8端口地址(在x86上)将端口映射的IO读/写到PCI Express配置空间。我还编写了一个示例Linux内核模块,以通过端口映射io读取pci配置空间,效果很好。我想通过MMIO / MMCFG访问来做同样的事情。
我也进行了搜索,但找不到令人信服的答案。我正在寻找详细信息,并且还在寻找一些代码示例以更好地理解它。
感谢您的帮助。
答案 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中正确处理此问题,有pci_{read|write}_config_XXX
function函数似乎使用了PCIe扩展配置空间。
因此,访问配置空间应该非常容易。
或者,pci_mcfg_lookup
将为PCI网段组和总线范围提供扩展配置空间的物理地址(您应该能够通过仅使用resource
定义结构来使其工作。 start
和end
字段设置为总线号。
如果您想要一个较低级别的方法。
最后,您可以获取MCFG
表的地址并自己(重新)解析它-确切地说,我不知道如何在Linux中获得这样的地址。
有一个acpi_tb_find_table
,您可以在其中传递表的签名以及 null oem和表ID,以获取表索引。
在同一文件的第114
行,有一段代码可以按索引访问表,您可以将其用作文档。
您可能必须从ACPI模块导入一个或多个符号。