PCI-e mmap内存空间访问

6
我正在使用基于PowerPC架构的Freescale MPC8308处理器上的PCI-e端口,并尝试使用时遇到了一些问题。端点PCI-e设备具有等于256MB的内存空间。我可以轻松地通过使用“pciutils”软件包读取和写入端点设备的配置空间。
在将正确的值写入配置寄存器并获得访问内存空间的权限后,我尝试使用C语言中的“mmap()”函数访问内存空间,并使用位于以下位置的文件描述符:

"/sys/devices/pci0000:00/0000:00:00.0/resource0"

这个设备的内存空间大小恰好是256 MB(与终端设备的内存空间相同),因此似乎我正在使用正确的文件描述符路径。您可以在此处找到我的代码,其中使用了"mmap()",如https://github.com/billfarrow/pcimem所述:

https://github.com/billfarrow/pcimem/blob/master/pcimem.c

但是,不幸的是,当我尝试使用“mmap()”函数返回的地址来使用内存空间时,我无法正确读取端点设备的只读寄存器。而且,当我读取大于“0x7FFFFFC”的地址时,MPC8308会重新启动。 考虑到上述情况,我是否错过了初始化PCI-e接口的任何步骤?我应该更改Linux内核映像或U-Boot代码中的任何内容吗?对于使用PowerPC PCI-e和mmap()有什么不同吗?您是否有任何示例代码可以帮助我读取PCI-e内存空间?
谢谢

端点的256MB内存空间似乎太大了。在我的处理器(i.MX6)上,我无法拥有大于16MB的端点。您的Linux引导中是否存在PCIe的初始化错误?您的PCI-e内存设备是什么?它是FPGA吗? - FabienM
是的,这对我来说也似乎太多了,但是在Linux引导过程中我没有任何错误,并且根据/proc/iomem中的信息,它已经为设备分配了256 MB的内存。终端设备不是FPGA,而是带有PCI-e接口的ASIC。 - ali rasteh
1
另一种方法是通过查找设备的基本物理地址和其限制,并映射到/dev/mem。(说实话我不能保证这个方法会起作用,但我很好奇它是否有效。) - ruthafjord
1个回答

2

mmap()是一种非常有用但随意的方式,可以从用户空间访问PCIe设备。

我注意到您将0作为第一个参数传递给mmap。在我的情况下,我使用lspci调用获取插入x86计算机中的FPGA卡的物理地址。然后,我将该物理地址用作mmap的第一个参数。我知道您正在写入设备的配置空间中的BAR,但也许应该再次检查lspci。

$ sudo lspci -s 02:00 -v
02:00.0 Memory controller: Xilinx Corporation Device 8028
    Subsystem: Xilinx Corporation Device 0007
    Flags: bus master, fast devsel, latency 0, IRQ 11
    Memory at f7e00000 (32-bit, non-prefetchable) [size=1M]
    Capabilities: [80] Power Management version 3
    Capabilities: [90] MSI: Enable- Count=1/1 Maskable- 64bit+
    Capabilities: [c0] Express Endpoint, MSI 00
    Capabilities: [100] Advanced Error Reporting

mmap的第一个参数确定了在调用mmap的进程中,结果映射的虚拟地址。为什么需要将其设置为设备的BAR的物理地址? - haggai_e

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接