我知道PCI配置空间中的基地址寄存器(BAR)定义了PCI地址的起始位置,但该区域的大小是如何建立的?
当然这是硬件的一个属性,因为它只知道它可以处理的地址空间有多远。但是,我似乎无法在PCI配置结构中看到BAR大小字段。
答案 0 :(得分:9)
首先,BAR大小必须是2的幂(例如,1 KiB,2 MiB),并且每个区域必须在内存中对齐,以便基址的低log2(size)
位始终为零。例如,假设端点具有4 KiB存储区,其地址范围为0-0xfff
。主机可以将该区域的开头重新映射到f.x.通过写入BAR寄存器0x1000
或0xabcd000
,但不是0x1080
或0xabcd100
。
当写入BAR寄存器时,端点将忽略LSB并始终在读取时返回零。因此,将0xffffffff
写入寄存器然后读回该值表示该区域的大小。对于4 KiB示例,这将返回0xfffff00X
(保留较低的四位,请参阅规范)。确定尺寸:
0xfffff000
)0xfff
)0x1000 = 4096 bytes
)这也适用于64位区域。下一个基地址寄存器的值形成基地址的MSB。这在PCI 3.0规范的6.2.5.1节中有所描述。
答案 1 :(得分:7)
在OSDev Wiki找到答案:
“要确定PCI设备所需的地址空间量,必须保存BAR的原始值,将所有1的值写入寄存器,然后再读回。”
答案 2 :(得分:1)
PCIe设备可以具有Type-0(端点)或Type-1(RC或交换机或网桥)配置空间。
- Type-0设备总共可以有6个BAR,而Type-1只能有2个BAR。
- BAR提供有关设备所需地址空间的信息。
- 每个BAR为32位,其中前4位3:0始终为只读。
- 2 ^(最低有效位的最后一个R / W位的位置)=特定BAR所需的地址窗口。
如何知道任何BAR所代表的地区的地址窗口或大小:
1)最初读取任何BAR(在我们的例子中假设为BAR0),我们得到值32'h0000_000F。 (请记住:最后4位只读!!)。
2)将所有1写入BAR0。
3)再次读取BAR0并假设我们得到值32'hFFFF_000F。因此位16是最低有效R / W位。因此BAR0所需的地址空间为2 ^ 16。