让Thunderbolt可以使用更大的BAR

Table of Contents

问题描述

在Xilinx 7-Series FPGA上用AXI Memory Mapped to PCI Express IP核设置了一个256M的BAR,这个BAR直接连接到主板的PCIe上可以正常进行MMIO,但将FPGA通过Thunderbolt硬盘盒+M.2转PCIe连接到Thunderbolt上却无法使用。

通过查阅dmesg可观测到如下报错信息:

[  246.677146] pci 0000:0c:00.0: BAR 0: no space for [mem size 0x10000000 64bit pref]
[  246.677147] pci 0000:0c:00.0: BAR 0: failed to assign [mem size 0x10000000 64bit pref]

其中,0000:0c这一地址便是我的FPGA,可以看出,BAR 0的256MB的地址无法被assign到物理地址空间,这就导致我们无法通过Kernel相关API或是/dev/mem来对这个BAR进行MMIO访问。

调试过程

然后我尝试将BAR大小降低到128M,重新用JTAG烧写bitstream,然后连接Thunderbolt,然后观察dmesg,结果如下:

[  737.544256] pci 0000:0c:00.0: BAR 0: assigned [mem 0x6108000000-0x610fffffff 64bit pref]

可以看到,这个BAR 0被正确地分配到了物理地址空间,于是我查看了lspci -v,果然也能看到Memory at xxxx [size=128M]。并在sysfs对这个device进行了enable操作后,用户态通过mmap映射/dev/mem对应的地址,也能正确完成MMIO。

0c:00.0 Memory controller: Xilinx Corporation Device 7021
        Subsystem: Xilinx Corporation Device 0007
        Physical Slot: 1-1
        Flags: fast devsel, IOMMU group 32
        Memory at 6108000000 (64-bit, prefetchable) [disabled] [size=128M]

然后,为了找到预留地址空间的根源,我查看了/proc/iomem,相关的PCIe树结果如下:

  60e0000000-612a0fffff : PCI Bus 0000:07 (Intel Corporation Thunderbolt 4 Bridge)
    60e0000000-612a0fffff : PCI Bus 0000:08 (Intel Corporation Thunderbolt 4 Bridge)
      60e0000000-6104ffffff : PCI Bus 0000:3e
      6105000000-6129ffffff : PCI Bus 0000:0a
        6108000000-6129ffffff : PCI Bus 0000:0b (Intel Corporation JHL7540 Thunderbolt 3 Bridge)
          6108000000-611107ffff : PCI Bus 0000:0c
          6108000000-610fffffff : 0000:0c:00.0 (Xilinx Corporation Device 7021)
          6111100000-61111fffff : PCI Bus 0000:24 (Intel Corporation JHL7540 Thunderbolt 3 USB Controller)
          6111200000-61220fffff : PCI Bus 0000:25
      612a000000-612a0fffff : PCI Bus 0000:09
        612a000000-612a03ffff : 0000:09:00.0 (USB controller: Intel Corporation Thunderbolt 4 NH)
          612a000000-612a03ffff : thunderbolt
        612a040000-612a040fff : 0000:09:00.0

然后,我尝试了拔出Thunderbolt线,整个/proc/iomem变成了这样:

  60e0000000-612a0fffff : PCI Bus 0000:07 (Intel Corporation Thunderbolt 4 Bridge)
    60e0000000-612a0fffff : PCI Bus 0000:08 (Intel Corporation Thunderbolt 4 Bridge)
      60e0000000-6104ffffff : PCI Bus 0000:3e
      6105000000-6129ffffff : PCI Bus 0000:0a
      612a000000-612a0fffff : PCI Bus 0000:09
        612a000000-612a03ffff : 0000:09:00.0
          612a000000-612a03ffff : thunderbolt
        612a040000-612a040fff : 0000:09:00.0

其实很显然我们可以看出,问题在于给每一个端口都只分配了576MB内存(0x6129ffffff-0x6108000000),结果这些内存实际分配到一个设备的Bus却只有144.5M了(0x611107ffff-0x6108000000),这显然就放不下一个256MB的BAR了,我个人其实不太明白这个物理内存空间的预留逻辑,调试一度陷入僵局。

于是我来到BIOS,发现了这样的设置:

既然Reserved PMemory可以修改,且最大值可以大至4096,那么我就直接改成了4096。

(反正不是占据物理内存,只是在64bit物理地址空间中划一块地)

随后F10保存重启,结果如下:

0c:00.0 Memory controller: Xilinx Corporation Device 7021
        Subsystem: Xilinx Corporation Device 0007
        Physical Slot: 1-1
        Flags: fast devsel, IOMMU group 32
        Memory at 6160000000 (64-bit, prefetchable) [disabled] [size=256M]
        Capabilities: [40] Power Management version 3
        Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
        Capabilities: [60] Express Endpoint, MSI 00
        Capabilities: [100] Device Serial Number 00-00-00-00-00-00-00-00

可以看到,256M的BAR成功出现!

再次查看/proc/iomem,结果如下:

  60e0000000-61e00fffff : PCI Bus 0000:07 (Intel Corporation Thunderbolt 4 Bridge)
    60e0000000-61e00fffff : PCI Bus 0000:08 (Intel Corporation Thunderbolt 4 Bridge)
      60e0000000-615fffffff : PCI Bus 0000:3e
      6160000000-61dfffffff : PCI Bus 0000:0a
        6160000000-61dfffffff : PCI Bus 0000:0b (Intel Corporation JHL7540 Thunderbolt 3 Bridge)
          6160000000-619007ffff : PCI Bus 0000:0c (Xilinx Corporation Device 7021)
          6160000000-616fffffff : 0000:0c:00.0
          6190100000-61901fffff : PCI Bus 0000:24
          6190200000-61d00fffff : PCI Bus 0000:25

可以看到,对于整个FPGA设备的Bus有了768M物理地址空间,开个256M的BAR就不再是个问题了。

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to Top