如何从PCIe中的条地址计算MMIO映射区域的大小

如何从PCIe中的条地址计算MMIO映射区域的大小,io,pci,pci-e,base-address,Io,Pci,Pci E,Base Address,我一直在深入探讨PCIe的一般工作原理,我一直停留在许多书籍和网站谈论PCIe配置空间的地方。 到目前为止,我所了解到的是,对于每个分配的设备及其BDF(总线设备功能位),该设备对应一个4KB的配置空间,其中包括如下所示的64B区域: 我对每个基址寄存器(表示内存映射区域)的解码理解如下: (两个图像均来自) 我不知道该区域的大小是如何确定的。例如,在一台服务器中,我为连接到BDF的GPU获取以下信息00:05.0commandlspci-x-v-s05:00.0: 05:00.0 VGA

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

我对每个基址寄存器(表示内存映射区域)的解码理解如下:

(两个图像均来自)

我不知道该区域的大小是如何确定的。例如,在一台服务器中,我为连接到BDF的GPU获取以下信息
00:05.0
command
lspci-x-v-s05: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
05:00.0 VGA兼容控制器:NVIDIA Corporation GV100[TITAN V](版本a1)(prog if 00[VGA控制器])
子系统:NVIDIA Corporation GV100[泰坦V]
标志:总线主节点、快速devsel、延迟0、IRQ 80、NUMA节点0
f8000000时的内存(32位,不可预取)[大小=16M]
a0000000处的内存(64位,可预取)[大小=256M]
b0000000处的内存(64位,可预取)[大小=32M]
d000处的I/O端口[size=128]
000c0000处的[虚拟]扩展ROM[已禁用][大小=128K]
能力:,以及)他们谈论的:
(1)查找地址的补码值,该补码值应为区域的长度(在某些方面对我来说没有意义)或
(2)由于
0xf8000000
1111 1000 0000
,因此该区域的大小是
2^27=128MB
,因为在满足第一个1之前有27个连续的0

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

下面是我真正的问题: 1.如何准确计算内存区域大小? 2.此外,上面映射的内存加起来似乎是16M+256M+32M+128(+128K),但GPU内存的实际大小略大于12GB。并非所有GPU内存都通过PCIe映射到MMIO,这是否正确

提前感谢。

您提到的定义了探测条的协议:

要确定PCI设备所需的地址空间量,请 必须保存条的原始值,将所有1的值写入 打开寄存器,然后将其读回。这样就可以减少内存量 通过掩蔽信息位,执行按位NOT (C中的“~”),并将该值递增1。原始价值 然后,应恢复酒吧。条形寄存器自然对齐,并且 因此,您只能修改设置的位

您提到的定义了探测条的协议:

要确定PCI设备所需的地址空间量,请 必须保存条的原始值,将所有1的值写入 打开寄存器,然后将其读回。这样就可以减少内存量 通过掩蔽信息位,执行按位NOT (C中的“~”),并将该值递增1。原始价值 然后,应恢复酒吧。条形寄存器自然对齐,并且 因此,您只能修改设置的位


这就是我所说的“寻找地址的补码值”。例如,如果
BAR0
值为
0xf4880000
,那么通过获取补码值,大小为
0x0b780000
,但从我提到的示例来看,情况显然不是这样?还有,“信息位”是什么意思?这是酒吧的最后4位吗?谢谢,在将1s写入所有地址位后,您应该对从条中读取的值执行此计算,而不是当前配置的值,即当前分配给条的地址。这就是我所说的“查找地址的补码值”。例如,如果
BAR0
值为
0xf4880000
,那么通过获取补码值,大小为
0x0b780000
,但从我提到的示例来看,情况显然不是这样?还有,“信息位”是什么意思?这是酒吧的最后4位吗?谢谢,在将1s写入所有地址位后,您应该对从条形图读取的值执行此计算,而不是当前配置的值,即当前分配给条形图的地址。