【问题标题】:Linux 64 bit BAR programmingLinux 64 位 BAR 编程
【发布时间】:2018-05-09 02:30:05
【问题描述】:

PCI 桥支持 32/64 首选项/无首选项:

pci_bus 0000:00: root bus resource [bus 00-ff]
pci_bus 0000:00: root bus resource [io  0x0000-0xffff] 
pci_bus 0000:00: root bus resource [mem 0x1000000000-0x10ffffffff] (bus address [0x00000000-0xffffffff])
pci_bus 0000:00: root bus resource [mem 0x1100000000-0x11ffffffff pref] (bus address [0x00000000-0xffffffff])
pci_bus 0000:00: root bus resource [mem 0x2000000000-0x2fffffffff] (bus address [0x00000000-0xfffffffff])
pci_bus 0000:00: root bus resource [mem 0x3000000000-0x3fffffffff pref] (bus  address [0x00000000-0xfffffffff])

使用 2 个 BAR 扫描端点:

pci 0000:01:00.0: BAR 2: assigned [mem 0x2100000000-0x211fffffff 64bit pref]
pci 0000:01:00.0: BAR 0: assigned [mem 0x1000000000-0x100007ffff]

桥上有窗户:

pci 0000:00:00.0: PCI bridge to [bus 01]
pci 0000:00:00.0:   bridge window [mem 0x1000000000-0x10000fffff]
pci 0000:00:00.0:   bridge window [mem 0x2100000000-0x211fffffff 64bit pref]

端点汇总 BAR:

endpoint: BAR 0 addr = 0x1000000000, size = 524287
endpoint: BAR 1 addr = 0x2100000000, size = 536870911

BAR1 的高 32 位将被编程为什么?我期待 0x21,但找到 0x1。

这是因为 pcibios_bus_to_resource/pcibios_resource_to_bus。 它标识了 3 个窗口偏移量:

window->res->start = 1000000000 window->offset = 1000000000 window->res->end = 10FFFFFFFF
window->res->start = 1100000000 window->offset = 1100000000 window->res->end = 11FFFFFFFF
window->res->start = 2000000000 window->offset = 2000000000 window->res->end = 2FFFFFFFFF

它在显示上面的地址时添加偏移量,但在编程 BAR 时减去它们 在端点注册。所以 0x2100000000 变成了 0x100000000。

这对于 64 位地址和 32 位 BAR 可能有意义,但为什么对于 64 位 BAR 会正确?

【问题讨论】:

    标签: linux pci-e


    【解决方案1】:

    据此(取自问题):

        pci_bus 0000:00: root bus resource [mem 0x1000000000-0x10ffffffff] (bus address [0x00000000-0xffffffff])
        pci_bus 0000:00: root bus resource [mem 0x1100000000-0x11ffffffff pref] (bus address [0x00000000-0xffffffff])
        pci_bus 0000:00: root bus resource [mem 0x2000000000-0x2fffffffff] (bus address [0x00000000-0xfffffffff])
        pci_bus 0000:00: root bus resource [mem 0x3000000000-0x3fffffffff pref] (bus  address [0x00000000-0xfffffffff])
    

    内存地址0x20'0000'0000对应总线地址0。

    因此,如果要使用内存地址 0x21'0000'0000 访问设备中的 BAR,则需要将其编程为 0x1'0000'0000。

    同样,内存地址 0x10'0000'0000 对应总线地址 0。因此设备中的 BAR 被编程为 0,以便使用内存地址 0x10'0000'0000 访问。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-05
      • 2016-11-13
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      • 2015-01-05
      • 2019-10-01
      相关资源
      最近更新 更多