【发布时间】:2013-09-25 13:42:38
【问题描述】:
我知道 PCI 配置空间中的基地址寄存器 (BAR) 定义了 PCI 地址的起始位置,但是这个区域的大小是如何确定的呢?
这当然是硬件的一个属性,因为只有它知道它可以处理多远的地址空间。但是,我似乎在 PCI 配置结构中看不到 BAR 大小字段。
【问题讨论】:
我知道 PCI 配置空间中的基地址寄存器 (BAR) 定义了 PCI 地址的起始位置,但是这个区域的大小是如何确定的呢?
这当然是硬件的一个属性,因为只有它知道它可以处理多远的地址空间。但是,我似乎在 PCI 配置结构中看不到 BAR 大小字段。
【问题讨论】:
首先,BAR 大小必须是 2 的幂(例如,1 KiB,2 MiB),并且每个区域必须在内存中对齐,以使基地址的低 log2(size) 位始终为零。例如,假设一个端点有一个 4 KiB 的内存区域,它给出的地址范围是0-0xfff。宿主可能会将该区域的起点重新映射到 f.x。 0x1000 或 0xabcd000 写入 BAR 寄存器,但不写入 0x1080 或 0xabcd100。
写入 BAR 寄存器时,端点将忽略 LSB 并在读取时始终返回零。因此将0xffffffff 写入寄存器然后读回该值表示该区域的大小。对于 4 KiB 示例,这将返回 0xfffff00X(低四位保留,请参阅规范)。确定大小:
0xfffff000)0xfff)0x1000 = 4096 bytes)这也适用于 64 位区域。下一个基地址寄存器的值构成基地址的 MSB。 PCI 3.0 规范的第 6.2.5.1 节对此进行了描述。
【讨论】:
在OSDev Wiki找到答案:
“要确定 PCI 设备所需的地址空间量,您必须保存 BAR 的原始值,将全 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。
【讨论】: