15

我知道 PCI 配置空间中的基地址寄存器 (BAR) 定义了 PCI 地址的起始位置,但是这个区域的大小是如何确定的呢?

当然,这是硬件的一个属性,因为只有它知道它可以处理多远的地址空间。但是,我似乎在 PCI 配置结构中看不到 BAR 大小字段。

4

3 回答 3

23

首先,BAR 大小必须是 2 的幂(例如,1 KiB,2 MiB),并且每个区域必须在内存中对齐,以log2(size)使基地址的低位始终为零。例如,假设一个端点有一个 4 KiB 的内存区域,它给出的地址范围是0-0xfff. 主机可以将此区域的开头重新映射到 fx0x10000xabcd000通过写入 BAR 寄存器,但不能重新映射到0x1080or 0xabcd100

写入 BAR 寄存器时,端点将忽略 LSB 并在读取时始终返回零。因此写入0xffffffff寄存器然后读回该值表示该区域的大小。对于 4 KiB 示例,这将返回0xfffff00X(低四位保留,请参阅规范)。要确定大小:

  • 将低四位清零 ( 0xfffff000)
  • 反转所有 32 位 ( 0xfff)
  • 结果加一 ( 0x1000 = 4096 bytes)

这也适用于 64 位区域。下一个基地址寄存器的值构成基地址的 MSB。PCI 3.0 规范的第 6.2.5.1 节对此进行了描述。

于 2016-09-21T13:51:50.450 回答
10

在OSDev Wiki上找到了答案:

“要确定 PCI 设备所需的地址空间量,您必须保存 BAR 的原始值,将全 1 的值写入寄存器,然后将其读回。”

于 2013-09-26T14:20:13.950 回答
2

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。

于 2016-02-04T19:14:52.337 回答