【发布时间】: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 开始的区域的大小呢?从我检查过的一些网站(one、two 和 three)他们谈到:
(1) 找到地址的补码值,应该是长度区域的大小(在某些方面对我来说没有意义)或
(2) 因为0xf8000000 是1111 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