【问题标题】:PCIe 64-bit Non-Prefetchable SpacesPCIe 64 位不可预取空间
【发布时间】:2012-05-04 22:12:26
【问题描述】:

我一直在阅读可怕的 PCIe 规范,但仍然无法解决以下问题。

  1. PCIe 是否允许将巨大的(例如 16GB)64 位不可预取内存空间映射到 4GB 边界以上?还是它们仍然绑定到与 32 位时代相同的 1GB,并且无法调用大量不可预取的空间?

  2. 假设规范允许(而且我的阅读确实如此),那么广泛可用的 BIOS 是否支持它?还是理论上允许,实践中不允许?

【问题讨论】:

  • 除非我遗漏了什么,否则我看不出为什么不,至少在规范方面——在 64 位模式下,设备能够寻址 64 位空间(远高于 4GB)。

标签: pci pci-e


【解决方案1】:

TL;DR / 简短回答

没有。对不可预取内存的 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 到 PCI 桥)。这显示了 PCI 配置空间标头类型 0x01(PCI 到 PCI 桥的标头格式)。请注意,从该表中的寄存器 1C 开始,有:

  • 1C:8 位(中间)用于 I/O 基地址。只有前 4 位可用。
  • 1D:8 位(中间)用于 I/O 限制地址。只有前 4 位可用。
  • 忽略 1E-1F。
  • 20:16 位用于不可预取的内存基地址。只有前 12 位可用。
  • 22:16 位用于不可预取的内存限制地址。只有前 12 位可用。
  • 24:16(中间)位用于可预取内存基址
  • 26:16(中间)位用于可预取内存限制地址
  • 28:高 32 位用于扩展可预取内存基地址
  • 2C:扩展可预取内存限制地址的高位 32 位
  • 30:扩展 I/O 基地址的高 16 位
  • 32:扩展 I/O 限制地址的高 16 位

实际地址是通过将这些寄存器的(部分)与 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 以内。

【讨论】:

  • 能否请您解释一下这个 lspci 输出系统外围设备:Intel Corporation Xeon E7 v3/Xeon E5 v3/Core i7 DMA Channel 0 (rev 02) Memory at fbf1c000 (64-bit, non-prefetchable) [大小=16K]
  • @Pyjong 这是 CPU 自己的根复合体,它在 32 位地址空间(16K @0xfbf1c000<0x100000000)中公开了一个 0x00 类型的标头和一个 64 位不可预取的 BAR。标头类型 0x00 允许以低于 20 位对齐的 64 位不可预取 BAR。但是,您永远不会在网桥后面和 32 位地址空间之上看到不可预取的 BAR,实际上这不是一个例子。
  • 啊哈我明白了。嗯,无论如何我都在挖掘更多信息,PCIe 规范说 PCIe 交换机从不缓冲读取或合并写入,因此可预取不再意味着太多(遗留)。但我想能够说这是内存/这些是寄存器仍然是一个很好的提示。
  • 那么 - 如果设备直接连接到根端口,那么具有大型(>4G 不可预取)BAR 的设备应该没问题??
  • @IwillnotexistIdonotexist 许多更新和更新的芯片(尤其是服务器 SKU)具有越来越多的根端口 - 其中许多直接路由到物理插槽而无需网桥。 (PCIe、NVMe、M.2 等)。
【解决方案2】:

PCIe 可以定义 64b 内存寻址。 BAR(基地址寄存器)的定义和使用在 PCI 3.0 规范(第 6.2.5.1 章“地址映射”)中定义,而不是在 PCIe 规范中。

【讨论】:

    猜你喜欢
    • 2014-12-11
    • 1970-01-01
    • 1970-01-01
    • 2010-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    相关资源
    最近更新 更多