我一直在阅读 PCIe 规范的恐怖,但仍然无法解决以下问题对。
PCIe 是否允许将巨大的(比如 16GB)64 位不可预取内存空间映射到 4GB 边界以上?还是它们仍然绑定到 32 位时代的 1GB,并且没有办法调用大量不可预取的空间?
假设规范允许它(并且我的阅读确实如此),那么广泛可用的 BIOS 是否支持它?还是理论上允许但实践中不允许?
不可以。对不可预取内存的 BAR 请求仅限于使用低 32 位地址空间。
http://www.pcisig.com/reflector/msg03550.html
答案是否定的原因与 PCI 内部有关。描述 PCI 总线包含的内存范围的数据结构仅保留足够的空间来存储 32 位基址和限制地址,用于不可预取的内存和 I/O 内存范围。但是,它确实保留了足够的空间来存储 64 位基址和可预取内存的限制。
具体来说,请查看http://wiki.osdev.org/PCI#PCI_Device_Structure,图 3(PCI-to-PCI 桥)。这显示了 PCI 配置空间报头类型 0x01(PCI 到 PCI 桥的报头格式)。请注意,从该表中的寄存器 1C 开始,有:
实际地址是通过将这些寄存器的(部分)与 0(用于基地址)或 1(用于限制地址)连接在一起来创建的。I/O 和不可预取的基地址和限制地址是 32 位的,形成如下:
Bit# 31 20 19 16 15 0
I/O Base: [ 16 upper bits : 4 middle bits : 12 zeros ]
I/O Limit: [ 16 upper bits : 4 middle bits : 12 ones ]
Non-prefetchable Base: [ 12 bits : 20 zeros ]
Non-prefetchable Limit: [ 12 bits : 20 ones ]
可预取的基地址和限制地址是 64 位的,形成如下:
Prefetchable Base:
Bit# 63 32
[ 32 upper bits ]
[ 12 middle bits : 20 zeros ]
Bit# 31 16 15 0
Prefetchable Limit:
Bit# 63 32
[ 32 upper bits ]
[ 12 middle bits : 20 ones ]
Bit# 31 16 15 0
如您所见,只有可预取的内存基址和限制寄存器被赋予足够的位来表达 64 位地址。所有其他的仅限于 32 个。
PCIe 可以定义 64b 内存寻址。BAR(基地址寄存器)的定义和使用在PCI 3.0规范(第 6.2.5.1 章“地址映射”)中定义,而不是在PCIe规范中。