【问题标题】:How to calculate size of MMIO-mapped region from BAR address in PCIe如何从 PCIe 中的 BAR 地址计算 MMIO 映射区域的大小
【发布时间】:2020-07-22 13:45:29
【问题描述】:

我一直在深入研究 PCIe 的一般工作原理,但我被许多书籍和网站谈论 PCIe 配置空间的地方困住了。
到目前为止我了解到的是,对于每个分配的设备及其 BDF(总线设备功能位),该设备对应一个 4KB 配置空间,其中包括如下 64B 区域:

我了解每个基地址寄存器(代表内存映射区域)的解码如下:

(两张图均来自this site

我不明白区域的大小是如何确定的。例如,在一台服务器中,我得到以下连接到 BDF 的 GPU 00:05.0 命令 lspci -x -v -s 05:00.0

05:00.0 VGA compatible controller: NVIDIA Corporation GV100 [TITAN V] (rev a1) (prog-if 00 [VGA controller])
    Subsystem: NVIDIA Corporation GV100 [TITAN V]
    Flags: bus master, fast devsel, latency 0, IRQ 80, NUMA node 0
    Memory at f8000000 (32-bit, non-prefetchable) [size=16M]
    Memory at a0000000 (64-bit, prefetchable) [size=256M]
    Memory at b0000000 (64-bit, prefetchable) [size=32M]
    I/O ports at d000 [size=128]
    [virtual] Expansion ROM at 000c0000 [disabled] [size=128K]
    Capabilities: <access denied>
    Kernel driver in use: nvidia
    Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
00: de 10 81 1d 07 05 10 00 a1 00 00 03 00 00 80 00
10: 00 00 00 f8 0c 00 00 a0 00 00 00 00 0c 00 00 b0
20: 00 00 00 00 01 d0 00 00 00 00 00 00 de 10 18 12
30: 00 00 00 00 60 00 00 00 00 00 00 00 0b 01 00 00

我们可以看到BAR0的值为0xf8000000。但是我们如何知道从地址0xf8000000 开始的区域的大小呢?从我检查过的一些网站(onetwothree)他们谈到:
(1) 找到地址的补码值,应该是长度区域的大小(在某些方面对我来说没有意义)或
(2) 因为0xf80000001111 1000 0000 0000 0000 0000 0000 0000,所以区域的大小是2^27=128MB 因为有是 27 个连续的 0,直到它遇到第一个 1。

但这两种方法都是错误的,因为lspci 命令说特定区域映射了16MB,而不是128MB。

所以这是我真正的问题: 1. 内存区域大小应该如何精确计算? 2. 另外,上面映射的内存加起来好像是16M+256M+32M+128(+128K),但是GPU内存的实际大小是12GB多一点。不是所有的 GPU 内存都通过 PCIe 映射到 MMIO 对吗?

提前致谢。

【问题讨论】:

    标签: io pci pci-e base-address


    【解决方案1】:

    你提到的OSDev link定义了探测BAR的协议:

    要确定 PCI 设备所需的地址空间量,您可以 必须保存 BAR 的原始值,将一个全 1 的值写入 寄存器,然后读回来。那么内存量可以是 通过屏蔽信息位确定,执行按位非 (C 中的“~”),并将值加 1。 然后应该恢复 BAR。 BAR 寄存器自然对齐并且 因此,您只能修改设置的位。

    【讨论】:

    • 这就是我所说的“找到地址的补码”。比如BAR0的值是0xf4880000,那么通过得到补码值,大小就是0x0b780000,但是从我提到的例子来看,显然不是这样吗?另外,“信息位”是什么意思?它是 BAR 的最后 4 位吗?谢谢
    • 您应该对所有地址位写入 1 后从 BAR 读取的值执行此计算,而不是当前配置的值,即当前分配给 BAR 的地址。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 2020-12-25
    • 2020-08-21
    • 1970-01-01
    相关资源
    最近更新 更多