PCI 段(域)如何与多个主机桥(或根桥)相关?
How is PCI segment(domain) related to multiple Host Bridges(or Root Bridges)?
我想了解 PCI 段(域)与多个主机桥的关系?
有人说多个PCI域对应多个Host Bridge,也有人说是一个Host Bridge下有多个Root Bridge。我很困惑,我在 PCI SIG 基本规范中找不到太多有用的信息。
不知道
(1) 假设我在 MCFG 中设置了 3 个 PCI 域,我是否有 3 个连接 3 CPU 和总线的主桥,或者我有 3 个支持 3 倍总线但都共享的根桥一个通用主机桥 CPU?
(2) 如果我有多个主机桥(或根桥),这些桥是否共享一个公共南桥(例如 ICH9),还是它们有单独的南桥?
我是初学者,google 并没有解决我的问题。如果有人能给我一些线索,我将不胜感激。
使用的措辞令人困惑。
我将尝试通过对 PCI 和 PCI Express 技术的简短 不完整 总结来修正我的术语。
跳到最后一节阅读答案。
PCI
Conventional PCI bus (henceforward PCI) is a designed around the bus topology:一个共享总线用于连接所有的设备。
为了创建更复杂的层次结构,一些设备可以作为 桥 运行:桥将 PCI 总线连接到另一个辅助总线。
辅助总线可以是另一条 PCI 总线(该设备称为 PCI-to-PCI bridge,以后称为 P2P)或不同类型的总线(例如 PCI-to-ISA 桥)。
这将创建以下形式的拓扑:
_____ _______
----------| P2P |--------| P2ISA |------------- PCI BUS 0
‾‾|‾‾ ‾‾‾|‾‾‾
-------------|---------------+----------------- ISA BUS 0
|
-------------+--------------------------------- PCI BUS 1
非正式地,每个 PCI 总线称为一个 PCI 段。
在上图中,显示了两个段(PCI BUS 0 和 PCI BUS 1)。
PCI 定义了三种类型的事务:内存、IO 和配置。
假定前两个是必需的知识。
第三个用于访问各个设备的配置地址space(CAS);在此 CAS 中,可以 meta-configure 设备。
比如它映射到系统内存地址的地方space。
为了访问设备的 CAS,设备必须是可寻址的。
在电气方面,PCI 总线段中的每个 PCI 插槽(集成或不集成)都连接起来以创建由三部分组成的寻址方案:device (0-31),function (0-7), register (0-255).
每个设备最多可以有七个逻辑功能,每个功能都有一个 256 字节的 CAS。
在上面的三元组中添加一个总线编号,以在整个总线拓扑中(而不仅仅是在总线段内)唯一标识一个设备。
这个四联体叫做身份证地址.
需要注意的是,这些ID地址是由软件分配的(但对于设备部分,是由接线固定的)。
它们是合乎逻辑的,但是,建议从根开始按顺序对总线进行编号。
CPU 本身不生成 PCI 事务,主机桥 是必需的。
它是一个让 CPU 执行 PCI 事务的桥(概念上是 Host-to-PCI 桥)。
例如,在 x86 的情况下,任何未被其他代理回收的内存写入或 IO 写入(例如内存、内存映射 CPU 组件、遗留设备等)都由主机桥传递到 PCI 总线。
要生成 CAS 事务,x86 CPU 写入 IO 端口 0xcf8
和 0xcfc
(第一个包含 ID 地址,第二个包含 read/write 的数据)。
一个 CPU 可以拥有多个 Host Bridge,没有什么可以阻止它,尽管这种情况非常罕见。
更有可能的是,一个系统可以有多个 CPU,并且每个系统都集成了一个 Host Bridge,一个系统可以有多个 Host Bridge。
对于 PCI,每个 Host Bridge 建立一个 PCI 域:一组总线段。
PCI 域的主要特征是它与其他 PCI 域隔离:事务 不需要 需要在域之间路由。
一个OS可以随意分配每个PCI域的总线号,它可以重复使用总线号,也可以按顺序分配:
NON OVERLAPPING | OVERLAPPING
|
Host-to-PCI Host-to-PCI | Host-to-PCI Host-to-PCI
bridge 0 bridge 1 | bridge 0 bridge 1
|
| | | | |
| | | | |
BUS 0 | BUS 2 | | BUS 0 | BUS 0 |
| | | | | | | | |
+------+ +------+ | +------+ +------+
| | | | | | | | |
| | | | | | | | |
| BUS 1 | BUS 3 | | BUS 1 | BUS 1
不幸的是,PCI域这个词在Linux内核中也有含义,它被用来给每个Host Bridge编号。
就 PCI 而言,这是可行的,但是随着 PCI express 的引入,这变得令人困惑,因为 PCI express 有自己的 "Host Bridge number" 名称(即 PCI 段组)和术语 PCI 域表示PCI express根端口的下游link。
PCI Express
PCI Express bus (henceforward PCIe) is designed around a point-to-point拓扑:一个设备只连接到另一个设备。
为了保持软件兼容性,大量使用了虚拟 P2P 桥。
PCI 总线的基本组件是设备和桥接器,而 PCIe 的基本组件是设备和开关。
从软件的角度来看,没有任何改变(但添加了新功能)并且总线以相同的方式枚举:使用设备和桥接器。
PCIe交换机是设备之间的基本粘合剂,它有n 下游端口.
交换机内部有一个 PCI 总线段,对于每个端口,在内部总线段中创建一个虚拟 P2P 桥(虚拟形容词在那里是因为每个 P2P 只响应 CAS 事务,这对于 PCI 兼容软件来说已经足够了)。
每个下游端口是一个 PCIe link.
一个PCIelink被认为是一个PCI总线段;这检查了交换机为每个下游端口都有一个 P2P 桥这一事实(交换机总共有 1 + n PCI 总线段)。
一台交换机多了一个端口:上行端口。
它就像一个下游端口,但它使用减法解码,就像网络交换机一样,它用于从 "logical external network" 接收流量并路由未知目的地。
所以一个交换机占用1 + N + 1个PCI段总线。
设备直接连接到交换机。
在 PCI 的情况下,一个桥将 CPU 连接到 PCI 子系统,因此期望一个开关将 CPU 连接到 PCIe 子系统是合乎逻辑的。
确实是这样,PCI complex root (PCR).
PCR 基本上是一个具有重要转折的交换机:它的每个端口都建立一个新的 PCI 域.
这意味着不需要将流量从端口 1 路由到端口 2(当然需要交换机)。
如前所述,这会产生 Linux 术语的转变,因为 Linux 为每个主机桥或 PCR 分配一个域号,而根据规范,每个 PCR 有多个域。
长话短说:同一个词,不同的意思。
PCIe规范使用PCI段组这个词来定义每个PCR的编号(简单的说PCI段组就是每个PCR的扩展CAS机制的基地址,所以有一个one-to-one 本地映射)。
由于它们的隔离 属性,PCR 的端口被称为 PCIe 根端口 。
备注
术语根桥在规范中不存在,我只能在UEFI Root Bridge IO Specification中找到它作为主机桥和PCR的总称(因为他们有相似的职责)。
Host Bridge 也被称为 Host Adapter。
最后是你的问题
(1) Suppose I setup 3 PCI domains in MCFG, do I have 3 Host Bridges that connects 3 CPUs and buses, or do I have 3 Root Bridges that support 3x times buses but all share a common Host Bridge in one CPU?
如果您有 3 个 PCI 域,您要么有 3 个主机桥接端口,要么有 3 个 PCIe 根端口。
如果 PCI 域是指 PCI 总线,在 PCI 总线段的意义上(不考虑它们的隔离),那么您可以让单个主机 Bridge/PCR 处理具有 3 个总线或更多总线的拓扑一台主机 Bridge/PCR 处理 3 条总线的组合。
在这种情况下没有特定要求,正如您所看到的,可以将总线与网桥进行级联。
如果您希望总线不被隔离(因此不是 PCI 域),您需要一个主桥或一个 PCIe 根端口。
一组 P2P 桥(真实的或虚拟的)将总线连接在一起。
(2) If I have multiple Host Bridges(or Root Bridges), do these bridges share a common South Bridge(e.g., ICH9), or they have separate ones?
桥接平台几年前就已经淡出,我们现在有一个系统代理集成到 CPU 中,它公开了一组 PCIe 通道(通常 20+)和一个平台控制器集线器(PCH),连接使用 DMI link.
到 CPU
PCH 也可以集成到与 CPU.
相同的插座中
从软件的角度来看,PCH 公开了一些似乎来自 CPU PCR 的更多通道。
无论如何,如果您有多个主机桥,它们通常位于不同的插槽上,但通常它们都只有一个南桥。
但是,这是(现在也不是)严格强制性的。
现代英特尔 C620 PCH 可以在仅端点模式 (EPO) 下运行,在该模式下它不用作主 PCH(具有固件和引导职责),而是用作一组 PCIe-endpoint。
想法是主机桥只是将 CPU 事务转换为 PCI 事务,其中这些事务的路由取决于总线拓扑,这本身就是一个非常有创意的主题。
集成此拓扑结构组件的地方是另一项创造性任务,最终有可能为每个主机桥提供专用的单独芯片或在所有甚至同时共享(或分区)一个大的单个芯片!
DOMAIN/SEGMENT 在配置 Space 寻址中(域往往是 Linux 术语,段是 Windows 和 PCISIG 术语)主要是平台级构造。 DOMAIN 和 SEGMENT 在此答案中可互换使用。从逻辑上讲,SEGMENT是PCI Family Configuration Space寻址机制的DOMAIN:Bus:Device:Function:Offset寻址方案中最重要的selector(最重要的地址位selector)。 (PCIe、PCI-X、PCI 和后来的 follow-on 软件兼容总线互连)。
在 PCI-Express (PCIe) 和更早的规范中,DOMAIN 不会出现在总线上(或 link 上),也不会出现在 link 事务数据包中。只有 BUS、DEVICE、FUNCTION、OFFSET 出现在事务中或总线上。但是,SEGMENT 在基于 SEGMENT:Bus,Dev,Func:OFFSET Configuration Space 软件地址的逻辑软件如何用于实际创建互连协议包 (PCIe) 或总线周期序列 (PCI ) 被描述为配置 Space 事务。在 PCI-Express (PCIe) 规范扩展配置 Space 访问方法 (ECAM) 中,这已部分解决。其余部分由 PCI 固件规范 3.2(涵盖更新的 PCIe 规范软件要求)处理。
在现代 PCIe 中,配置 Space 访问方法由操作系统的 ECAM 机制处理,操作系统抽象了这种配置 space 访问机制(将 CPU 内存 space 访问指令进入 Bus/Interconnect 配置 Space 事务)。操作系统软件将 SEGMENT/DOMAIN 理解为配置 Space 的 SEGMENT:BUS:DEVICE:FUNC:OFFSET 地址方案中的最高级别(最顶层)逻辑 select 或地址组件。 SEGMENT 如何从软件逻辑概念转移到物理硬件实例化,以 ECAM 转换器的形式出现,或者具体而言,平台中存在多个 ECAM 转换器。 ECAM 转换器在内存类型事务和配置 space 类型事务之间进行转换。 PCIe 规范描述了单个 ECAM 转换器实现如何将目标转换内存写入或读取中的特定内存地址位转换为配置 Space 写入或读取。其工作方式如下:
Address Bits:
11:00 (Offset bits, allows 4K of configuration space per PCIe device)
14:12 Function selection bits.
19:15 Device selection Bits.
27:20 Bus Selection Bits. 1 <= n <= 8 (Maximum of 8 bits, 256 numbers, can be less)
63:28 Base address of the individual ECAM.
真正没有明确(或根本)没有涵盖的是,多个 ECAM 可以存在。一个平台可以设置多个 ECAM 区域。平台为什么要这么做?因为 ECAM 地址位(8 位)的总线 selection 位允许是限制性的,只允许系统中总共有 256 个总线,这在某些系统上是不够的。
PCI 固件规范 3.2(2015 年 1 月 26 日)从软件逻辑角度描述了 ECAM。固件规范描述了称为 MCFG table 的软件内存结构(存在于 BIOS 保留区域中,BIOS 和操作系统使用该保留区域进行通信)。 MCFG table 描述了平台硬件实现中存在的基于 ECAM 硬件配置 space 循环生成器的一个或多个实例。这些是内存地址 space 事务(内存写入)到配置 space 周期事务转换区域。例如ECAM 硬件实现是 CPU 实例化以允许通过软件生成配置 Space 事务的机制。平台实现(通常由 CPU/Chipset 设计指定和限制,但有时也由 BIOS 设计选择决定)允许一定数量的 ECAM 配置 Space 周期生成器。一个平台必须至少支持一个,然后它才会有一个 SEGMENT。但是一个平台可能支持多个ECAM,那么对于每个支持的ECAM它都有一个SEGMENT。 MCFG table 拥有平台支持的每个 ECAM 配置 Space 基地址分配结构。单个 SEGMENT 平台将只有一个条目,multi-SEGMENT 平台将有多个条目,每个支持的 ECAM 一个。每个条目包含内存基地址(ECAM 区域配置Space 周期生成器),一个与此ECAM 和sub-range 总线编号对应的逻辑SEGMENT 组,以及一个sub-range 总线编号(开始和结束)存在于这个逻辑段中。
一个 BIOS 不能仅仅决定它需要很多 ECAM 并描述多个 ECAM 并使用常规内存地址作为“基地址”。硬件实际上必须通过设计将内存地址实例化为配置 Space 循环生成逻辑,该逻辑锚定到特定地址(有时由 CPU/chipset 设计固定,有时可根据位置配置 CPU/chipset BIOS 可以编程的特定 non-standard 位置配置寄存器。)在任何一种情况下,BIOS 描述了存在的 ECAM,并且根据设计,描述了一种方式, 或特定的 m配置(或禁用)ECAM 组的 nner 描述系统上活动的一个或多个活动 ECAM。此类 BIOS 配置的一部分包括设置可配置的 ECAM,如果可配置,则选择启用的数量,它们将位于何处(在什么基地址),以及配置哪些芯片组设备对应于哪些 ECAM,以及配置哪些根端口对应于哪些 ECAM 并与其相关联。一旦 BIOS 内部配置完成,BIOS 必须向操作系统描述这些平台硬件和 BIOS 决策。这是使用 PCI 固件规范定义的 MCFG table 完成的,它是 ACPI 规范的一部分,用于 BIOS(固件)到操作系统平台描述定义机制。
使用 MCFG table 方案,可以拥有并描述多个 ECAM 和多个逻辑段,每个 ECAM 一个。也可能只有一个 SEGMENT,它实际上也被拆分为多个 ECAM。 (多个条目,但都使用相同的段,然后是 non-overlapping 总线编号。)但是 MCFG 在 multi-segment 配置中的典型用途是允许多个段,其中总线编号重复.例如每个 SEGMENT 最多可拥有 256 条总线,与另一个 SEGMENT 中可能存在的最多 256 条总线分开。
三组软件都知道配置 Space 寻址中的段。 BIOS(创建 MCFGtable),操作系统(读取 MCFGtable,获取 ECAM 基地址,并通过访问处理逻辑到物理地址转换软件任务正确的 ECAM,在正确的偏移量处),最后一组是所有其他总线、设备、功能 (BDF) 感知软件。所有软件都必须是 SEGMENT、BUS、DEV、FUNC 感知的,而不仅仅是 Bus、DEV、FUNC 感知的。假定 SEGMENT 始终为 0 的软件是 BROKEN。如果你曾经创建过这样的软件,你应该赶回你的办公桌并立即修复它,在任何人看到它之前,当然在它在产品中发布之前! :-)
平台设计(在硬件 ECAM 支持和 BIOS 设计中)可以实现多个 ECAM。这通常是为了规避仅使用单个 ECAM 时出现的 256 总总线限制。因为 ECAM 是由 PCISIG 定义的,并且因为该定义围绕总线上的总线数量限制(在事务字段中),单个 ECAM 无法为超过 256 条总线实现配置 Space 生成器。然而,平台 CAN 和 DO 实例化多个 ECAM 区域,并有一个 MCFG table 描述具有多个 ECAM 基地址的多个段,这允许平台拥有超过 256 条总总线。 (但是在以 PCIe 根端口为根的每个 PCIe 设备树中最多只有 256 个总线,并且共享一个公共 ECAM 配置 Space 生成器的所有根端口一起最多只有 256 个总线。每个 ECAM 区域可以描述在其域(或段)中最多 256 条总线。平台系统如何决定将主机根端口(缓存一致域到 PCI/PCIe 域桥)分组到段中是平台特定的,并且对 chipset/CPU 设计是任意的和 BIOS 配置。大多数平台是固定和简单的(通常只有一个 ECAM),有些平台灵活、严格和可配置,允许多种解决方案。提供最大的解决方案类型在平台级别使用的 PCIe 总线数量是为了支持每个根端口一个 ECAM。(现在很少有平台这样做,但都应该!)它们是用于描述平台“如何”决定对设备进行分组的两种机制,端点,并切换到 SEGMENT。第一个是 afore-mentioned MCFG结构,它简单地列出了多个 SEGMENTS,它们相关的 ECAM(如果一个 SEGMENT 中的总线范围被多个 ECAM 分割,则可能不止一个),以及每个 ECAM 的基地址(或 ECAM 总线编号 sub-region)。这种方法本身通常足以完成许多枚举任务,因为这允许 OS 枚举所有段,找到它们的 ECAM,然后对每个 SEGMENT 中的所有设备进行 PCI Bus、Device、Function 扫描。然而,第二种机制也可用,它增加了 MCFG 信息,即 ACPI 名称中的 _SEG 描述符 space。 ACPI 规范有一个通用的平台描述机制,以独立于操作系统的方式描述系统中已知设备的关系,但允许操作系统解析数据并消化平台布局。这种机制称为 ACPI 名称space。在名称space中,设备是“对象”,因此通常描述固定并包含在 ACPI 实现系统主板上的 PCIe 端点、PCIe 根端口和 PCIe 开关。在这个名字space中,对象出现了,并且有限定符或修饰符。一个这样的装饰器“methd" 是 _SEG 方法,它描述了特定对象位于哪个 SEGMENT。这样,内置设备可以分组到特定的 ECAM 访问区域,或者更常见的是,特定的 PCIe ROOT 端口被分组到 SEGMENTS(和关联的 ECAM访问区域,MCFG 描述基地址)。此外,可以是 hot-added 的设备(并且不是静态存在于主板上的)可以描述它们在 hot-plug 上重新创建的段,或者 pre-existing 他们在 hot-plug 添加时加入的 SEGMENT,以及他们实例化的那个 SEGMENT 中的总线编号。这是在名称 space 中使用描述的 Root Port 对象上的 _CBA 方法装饰器完成的在这样的名称space中,它与_SEG方法结合使用。_CBA仅适用于top-level“已知”hot-plug可用元素,例如如果两个4 CPU 系统可以动态地“加入”到单个 8 CPU 系统中,它们各自的 PCIe 根端口元素也因此“加入” n" 新的单一系统,从原始基础 4 CPU 系统的 PCIe 根端口扩展,以包括添加的 4 CPU 的新附加 PCIe 根端口。
对于出现在插槽或外部扩展机箱中的 PCIe 交换机,_SEG(或 SEGMENT 值)通常继承自平台中已有的最高级根端口,位于该 PCIe 设备树的顶层。包含该根端口的段,也是该根端口下的所有设备所属的段。
人们经常阅读较早的资料(在发明多个 ECAM 之前,以及配置 Space 和相关操作系统软件中的段的概念),PCIe 枚举是通过扫描总线编号完成的,然后是设备编号,然后是功能编号。这是不正确的,而且已经过时了。实际上,MODERN (CURRENT) BIOS 和操作系统实际上是通过分段(select 使用 ECAM)、总线编号、设备编号,最后是功能进行扫描编号(在特定 ECAM 内应用偏移量)以在特定 PCIe 根端口(例如,在特定 PCIe 设备树上)之上和之下生成配置周期。
较旧的“PCI”机制(在为 PCIe 定义增强配置配置 Space 之前)无法识别 SEGMENT。当硬件平台支持时,较旧的 CF8/CFC 配置 space PCI 访问机制(不应再被任何新编写的软件使用)通常实现遗留的最佳实用解决方案 PCI-only(不是 PCIe-aware)感知操作系统,旧机制被硬编码到该机制的 SEGMENT 0。这意味着 PCI-only-aware 系统只能访问 SEGMENT 0 中的设备。所有主要操作系统都支持 PCIe ECAM 增强机制超过 10 年,并且软件对 CF8/CFC 机制的任何使用今天被认为是过时的、陈旧的和破损的,应该被现代使用的 ECAM 机制所取代,至少支持 MCFG table 和多个 ECAM,如果操作系统要求,补充通过 ACPI 规范名称space _SEG 和 _CBA 属性对象方法信息由操作系统为完全动态 hot-plug 情况摄取。如果 OS 没有将 ACPI 热插拔方法用于其他任务,几乎所有 non-hotplug 情况都可以由 MCFG 单独处理。如果 OS 对其他设备和名称space 操作使用 ACPI 热插拔,那么通常还需要支持 _SEG 和 _CBA,操作系统和 BIOS 才能生成这些 APCI 名称 space 对象以描述设备关联的方式分组到 SEGMENT,从而描述到支持该设备、根端口或根复合桥或设备的配置周期生成的特定 ECAM 硬件。现代软件使用 SEGMENT,只有损坏和不正确的软件会假定所有设备和桥都存在于 SEGMENT 0 中。现在这并不总是正确的,并且随着时间的推移越来越不正确。
SEGMENT 分组倾向于遵循硬件设计中的一些逻辑原理以及对该设计配置的限制。 (但并非总是如此,有时,它只是随意和奇怪。)例如,在 Intel 8 套接字系统(大型多处理器)上,“本机”一致性实现在大多数情况下往往限于 4 个套接字。当供应商构建一个 8 插槽系统时,通常是通过在它们之间的连贯互连上将两组 4 个插槽每组连接到一个集群交换机来完成的。这种类型的平台可能会实现两个 PCIe 段,每个 4 个插槽集群一个。但是对于平台可能希望如何使用多个 SEGMENT 和使用多个 ECAM 没有限制。一个双套接字系统可以实现多个 ECAM,每个 CPU 一个 SEGMENT,在 o每个 CPU 最多允许 256 个 PCIe 总线,总共 512 个。如果这样的平台改为将来自两个 CPU 的所有根端口映射到单个 SEGMENT(更常见),那么整个平台只能有 256 个总线用于整个平台。优化设计的平台(在 ECAM 硬件资源方面更昂贵)将为系统中的每个根端口提供一个 ECAM,并为平台中的每个根联合体设备提供一个 ECAM。一个有 8 个根端口的两个 CPU 系统,每个 CPU 上有 4 个,每个 CPU 上有 4 个根联合体,将实现 16 个段,其中 8 个(根端口段)将每个支持最多 256 个总线,8 个支持的 Root Complex 设备树将实例化足够的总线支持来映射 Root Complex 设备和桥。因此,如果在 2048+ 总线的高端提供总线支持,这样一个完全组成的双插槽系统将支持最多 8*256 + 内置 Root Complex 设备所需的总线。今天设计的任何“真实”服务器都应该这样设计。我还在等着看这个现代的“真正的”Intel 或 AMD 服务器,而不是这些天推出的玩具。
大多数操作系统软件不需要关心“如何”实现段关联,它们只需要考虑逻辑段值是配置的一部分这一事实 SPACE 寻址(不要编码你的东西只是总线、设备、功能,假设 SEGMENT=0) 它必须被编码为 (SEGMENT, BUS, DEVICE, FUNCTION) 除非你想被标记为 slacker-type,做错了,[=120= 】 低能。支持SEGMENT值!它们现在很重要,并且将来会变得越来越重要,因为总线编号 space 和平台 运行 受到更大的压力,因为限制在低级和限制性的 256 总线上存在于单个 SEGMENT 中。单个 SEGMENT 限制的发生是由于硬件设计,但也可能是因为软件没有为 multi-SEGMENT 平台正确编写和准备。不要成为创建错误 single-SEGMENT (SEGMENT =0) 假设软件。不要成为那个人!)不要以这种方式编写操作系统软件。不要以这种方式编写 BIOS 软件,不要编写可感知 Bus、Device、Function 但不感知 SEGMENT、BUS、DEVICE、FUNCTION 的应用程序。
平台操作系统软件(在 *nix 的内核中,或在 Windows 的 HAL 中)获取 SEGMENT 值,并将其用于 select 它将访问的 ECAM(例如哪个ECAM 基地址它将添加 BDF/offset 内存地址偏移量)。然后它使用总线、设备、功能值索引到该 ECAM 中的较高地址位,最后它使用配置 Space 设备寄存器偏移地址填充输入的内存地址的较低部分ECAM 配置 Space 交易生成器作为其内存地址交易输入。
在英特尔兼容平台(英特尔和 AMD 等)上,PCI 固件规范和 ACPI 规范描述了 BIOS 如何告诉操作系统(Linux、Windows , FreeBSD 为例) 关于一个 ECAM (单段) 或每个 ECAM (多段) 基地址位于内存地址中的位置 space.
段从不出现在 PCIe 或 PCI 的总线上。在 PCIe 中,RID(路由标识符)仅对发送方的 Bus# 和 Device/Func# 进行编码。同样在配置周期中,只有目标目标的 Bus# 和 Device#/Func# 在下游事务中编码。如果启用 ARI(替代路由 ID)模式,Device/Func# 可以在 PCIe 中获得修改处理。但是 SEGMENT 值没有出现(也没有出现在 PCI 总线序列中)。它本质上是一个软件构造,但具有平台硬件支持(CPU 和芯片组)形式的真实硬件实例,用于多个 ECAM(multi-SEGMENT)或仅单个 ECAM(single-segment).请注意,不同 SEGMENT 中的设备实际上仍然可以进行点对点直接通信。点对点事务使用内存寻址进行(这是所有段之间的单个全局共享 space,例如,所有段仍然共享一个统一的内存地址 space,至少在 IOMMU 转换和通过根传输之后端口,这是可能位于不同 SEGMENT 上的先决条件)。 SEGMENT 可以有冲突和重复的总线编号 spaces,但是当它们出现在不同的 SEGMENT 中时,它们描述了不同的总线。多个 ECAM 系统实际上可以实现单个共享总线地址 spaces 以及独立的重复总线编号 space。实际上这很少见,因为系统通常会使用单个 ECAM 和单个 SEGMENT 用于单个总线地址 space。然而,一些奇怪的硬件可能需要使用 single-segment、multi-ECAM、跨多个 ECAM 的共享单总线 运行,为 256 个最大有限总线 space 提供有些奇怪设计的简单性(通常与热插拔或动态配置相关。)
一个理论上的平台,其“chipset/uncore”组件中有大量内置设备,并且其设计中有两个 CPU 插座,如果需要,可以实现四段设计。它可以将所有内置 CPU 设备放在它们自己的段中(每个 CPU 一个),使用两个段,然后将每个 CPU 的 PCIe 根端口映射到它们自己的SEGMENT,又是每个 CPU 一个唯一的 SEGMENT,总共 4 个 SEGMENT。这将允许整个系统中有 4 * 256 = 1024 个总线。
一个不同的理论平台,具有相同的两个插槽数,可以将所有 CPU(在本例中只有两个)和所有内置设备的所有设备,以及所有现有的根端口映射到一个单一的ECAM,因此是单个 SEGMENT。这样的平台将只有一个 ECAM,因此整个系统将被限制为总共 256 条总线(因此,如果平台是加载了大而复杂的 multi-endpoint add-in 卡,带有 PCIe 开关以支持 multi-device 当前。例如,前置 AI 支持 GPU 卡,或者如果它有多个 fan-out 开关(以增加其插槽数量),或者该供应商是否正确使用和支持外部 PCIe 开关扩展器(到外部 PCIe 机箱)。
目前正在设计的“最佳”平台,未来将为每个根端口实现独立的 ECAM,允许每个根端口在其设备树中单独支持多达 256 条总线,独立于每个其他根端口。迄今为止,我仍在等待这个平台,它有大量的 PCIe 段对应大量的 PCIe 根端口。此类设计对于 Compose-able I/O 解决方案、共享内存解决方案、分层内存解决方案、compose-able 存储解决方案、大型外部 I/O 外壳解决方案、支持 CXL 的解决方案至关重要加速器等。换句话说,用于现代计算。当一个平台出来并说它的时钟比上一个多 5% 时,我打哈欠。当出现一个支持每个根端口 ECAM 的平台时,我会注意到,那个平台将获得我的金印。
总线数 space 的压力现在处于临界点,因此在不久的将来可能会使用更多的段(或者应该是,如果英特尔和 AMD 正在关注的话)。像 CXL(一种 PCIe 软件模型兼容的总线基础设施)这样的技术只会增加单个 SEGMENT 的 Configuration Space 总线数量限制的压力(如今 256 条总线并不多。)每个交换机在内部使用一条总线,每个 link 使用总线,因此插槽数大、扇出高的系统将消耗超过 256 条总线。 Multi-SEGMENT 设计现在就在这里,而且会越来越普遍。立即修复您的软件!
参见:
PCI Express Base Spec 5.0(或任何更早版本)
7.2. PCI Express 增强配置访问机制 (ECAM)
http://www.pcisig.com
PCI 固件规范 3.2(或更新版本)http://www.pcisig.com
4.1.2 MCFG Table 说明
ACPI 规范“MCFG”定义http://uefi.org
_SEG(段)名称space ACPI 名称space 描述中的限定符。
UEFI 规范 http://uefi.org 描述了 OS 如何在具有 UEFI 的现代 UEFI 平台中找到 MCFG table 和所有其他基于 ACPI 的 table BIOS(引导固件)。
我想了解 PCI 段(域)与多个主机桥的关系?
有人说多个PCI域对应多个Host Bridge,也有人说是一个Host Bridge下有多个Root Bridge。我很困惑,我在 PCI SIG 基本规范中找不到太多有用的信息。
不知道
(1) 假设我在 MCFG 中设置了 3 个 PCI 域,我是否有 3 个连接 3 CPU 和总线的主桥,或者我有 3 个支持 3 倍总线但都共享的根桥一个通用主机桥 CPU?
(2) 如果我有多个主机桥(或根桥),这些桥是否共享一个公共南桥(例如 ICH9),还是它们有单独的南桥?
我是初学者,google 并没有解决我的问题。如果有人能给我一些线索,我将不胜感激。
使用的措辞令人困惑。
我将尝试通过对 PCI 和 PCI Express 技术的简短 不完整 总结来修正我的术语。
跳到最后一节阅读答案。
PCI
Conventional PCI bus (henceforward PCI) is a designed around the bus topology:一个共享总线用于连接所有的设备。
为了创建更复杂的层次结构,一些设备可以作为 桥 运行:桥将 PCI 总线连接到另一个辅助总线。
辅助总线可以是另一条 PCI 总线(该设备称为 PCI-to-PCI bridge,以后称为 P2P)或不同类型的总线(例如 PCI-to-ISA 桥)。
这将创建以下形式的拓扑:
_____ _______
----------| P2P |--------| P2ISA |------------- PCI BUS 0
‾‾|‾‾ ‾‾‾|‾‾‾
-------------|---------------+----------------- ISA BUS 0
|
-------------+--------------------------------- PCI BUS 1
非正式地,每个 PCI 总线称为一个 PCI 段。
在上图中,显示了两个段(PCI BUS 0 和 PCI BUS 1)。
PCI 定义了三种类型的事务:内存、IO 和配置。
假定前两个是必需的知识。
第三个用于访问各个设备的配置地址space(CAS);在此 CAS 中,可以 meta-configure 设备。
比如它映射到系统内存地址的地方space。
为了访问设备的 CAS,设备必须是可寻址的。
在电气方面,PCI 总线段中的每个 PCI 插槽(集成或不集成)都连接起来以创建由三部分组成的寻址方案:device (0-31),function (0-7), register (0-255).
每个设备最多可以有七个逻辑功能,每个功能都有一个 256 字节的 CAS。
在上面的三元组中添加一个总线编号,以在整个总线拓扑中(而不仅仅是在总线段内)唯一标识一个设备。
这个四联体叫做身份证地址.
需要注意的是,这些ID地址是由软件分配的(但对于设备部分,是由接线固定的)。
它们是合乎逻辑的,但是,建议从根开始按顺序对总线进行编号。
CPU 本身不生成 PCI 事务,主机桥 是必需的。
它是一个让 CPU 执行 PCI 事务的桥(概念上是 Host-to-PCI 桥)。
例如,在 x86 的情况下,任何未被其他代理回收的内存写入或 IO 写入(例如内存、内存映射 CPU 组件、遗留设备等)都由主机桥传递到 PCI 总线。
要生成 CAS 事务,x86 CPU 写入 IO 端口 0xcf8
和 0xcfc
(第一个包含 ID 地址,第二个包含 read/write 的数据)。
一个 CPU 可以拥有多个 Host Bridge,没有什么可以阻止它,尽管这种情况非常罕见。
更有可能的是,一个系统可以有多个 CPU,并且每个系统都集成了一个 Host Bridge,一个系统可以有多个 Host Bridge。
对于 PCI,每个 Host Bridge 建立一个 PCI 域:一组总线段。
PCI 域的主要特征是它与其他 PCI 域隔离:事务 不需要 需要在域之间路由。
一个OS可以随意分配每个PCI域的总线号,它可以重复使用总线号,也可以按顺序分配:
NON OVERLAPPING | OVERLAPPING
|
Host-to-PCI Host-to-PCI | Host-to-PCI Host-to-PCI
bridge 0 bridge 1 | bridge 0 bridge 1
|
| | | | |
| | | | |
BUS 0 | BUS 2 | | BUS 0 | BUS 0 |
| | | | | | | | |
+------+ +------+ | +------+ +------+
| | | | | | | | |
| | | | | | | | |
| BUS 1 | BUS 3 | | BUS 1 | BUS 1
不幸的是,PCI域这个词在Linux内核中也有含义,它被用来给每个Host Bridge编号。
就 PCI 而言,这是可行的,但是随着 PCI express 的引入,这变得令人困惑,因为 PCI express 有自己的 "Host Bridge number" 名称(即 PCI 段组)和术语 PCI 域表示PCI express根端口的下游link。
PCI Express
PCI Express bus (henceforward PCIe) is designed around a point-to-point拓扑:一个设备只连接到另一个设备。
为了保持软件兼容性,大量使用了虚拟 P2P 桥。
PCI 总线的基本组件是设备和桥接器,而 PCIe 的基本组件是设备和开关。
从软件的角度来看,没有任何改变(但添加了新功能)并且总线以相同的方式枚举:使用设备和桥接器。
PCIe交换机是设备之间的基本粘合剂,它有n 下游端口.
交换机内部有一个 PCI 总线段,对于每个端口,在内部总线段中创建一个虚拟 P2P 桥(虚拟形容词在那里是因为每个 P2P 只响应 CAS 事务,这对于 PCI 兼容软件来说已经足够了)。
每个下游端口是一个 PCIe link.
一个PCIelink被认为是一个PCI总线段;这检查了交换机为每个下游端口都有一个 P2P 桥这一事实(交换机总共有 1 + n PCI 总线段)。
一台交换机多了一个端口:上行端口。
它就像一个下游端口,但它使用减法解码,就像网络交换机一样,它用于从 "logical external network" 接收流量并路由未知目的地。
所以一个交换机占用1 + N + 1个PCI段总线。
设备直接连接到交换机。
在 PCI 的情况下,一个桥将 CPU 连接到 PCI 子系统,因此期望一个开关将 CPU 连接到 PCIe 子系统是合乎逻辑的。
确实是这样,PCI complex root (PCR).
PCR 基本上是一个具有重要转折的交换机:它的每个端口都建立一个新的 PCI 域.
这意味着不需要将流量从端口 1 路由到端口 2(当然需要交换机)。
如前所述,这会产生 Linux 术语的转变,因为 Linux 为每个主机桥或 PCR 分配一个域号,而根据规范,每个 PCR 有多个域。
长话短说:同一个词,不同的意思。
PCIe规范使用PCI段组这个词来定义每个PCR的编号(简单的说PCI段组就是每个PCR的扩展CAS机制的基地址,所以有一个one-to-one 本地映射)。
由于它们的隔离 属性,PCR 的端口被称为 PCIe 根端口 。
备注
术语根桥在规范中不存在,我只能在UEFI Root Bridge IO Specification中找到它作为主机桥和PCR的总称(因为他们有相似的职责)。
Host Bridge 也被称为 Host Adapter。
最后是你的问题
(1) Suppose I setup 3 PCI domains in MCFG, do I have 3 Host Bridges that connects 3 CPUs and buses, or do I have 3 Root Bridges that support 3x times buses but all share a common Host Bridge in one CPU?
如果您有 3 个 PCI 域,您要么有 3 个主机桥接端口,要么有 3 个 PCIe 根端口。
如果 PCI 域是指 PCI 总线,在 PCI 总线段的意义上(不考虑它们的隔离),那么您可以让单个主机 Bridge/PCR 处理具有 3 个总线或更多总线的拓扑一台主机 Bridge/PCR 处理 3 条总线的组合。
在这种情况下没有特定要求,正如您所看到的,可以将总线与网桥进行级联。
如果您希望总线不被隔离(因此不是 PCI 域),您需要一个主桥或一个 PCIe 根端口。
一组 P2P 桥(真实的或虚拟的)将总线连接在一起。
(2) If I have multiple Host Bridges(or Root Bridges), do these bridges share a common South Bridge(e.g., ICH9), or they have separate ones?
桥接平台几年前就已经淡出,我们现在有一个系统代理集成到 CPU 中,它公开了一组 PCIe 通道(通常 20+)和一个平台控制器集线器(PCH),连接使用 DMI link.
到 CPU
PCH 也可以集成到与 CPU.
相同的插座中
从软件的角度来看,PCH 公开了一些似乎来自 CPU PCR 的更多通道。
无论如何,如果您有多个主机桥,它们通常位于不同的插槽上,但通常它们都只有一个南桥。
但是,这是(现在也不是)严格强制性的。
现代英特尔 C620 PCH 可以在仅端点模式 (EPO) 下运行,在该模式下它不用作主 PCH(具有固件和引导职责),而是用作一组 PCIe-endpoint。
想法是主机桥只是将 CPU 事务转换为 PCI 事务,其中这些事务的路由取决于总线拓扑,这本身就是一个非常有创意的主题。
集成此拓扑结构组件的地方是另一项创造性任务,最终有可能为每个主机桥提供专用的单独芯片或在所有甚至同时共享(或分区)一个大的单个芯片!
DOMAIN/SEGMENT 在配置 Space 寻址中(域往往是 Linux 术语,段是 Windows 和 PCISIG 术语)主要是平台级构造。 DOMAIN 和 SEGMENT 在此答案中可互换使用。从逻辑上讲,SEGMENT是PCI Family Configuration Space寻址机制的DOMAIN:Bus:Device:Function:Offset寻址方案中最重要的selector(最重要的地址位selector)。 (PCIe、PCI-X、PCI 和后来的 follow-on 软件兼容总线互连)。
在 PCI-Express (PCIe) 和更早的规范中,DOMAIN 不会出现在总线上(或 link 上),也不会出现在 link 事务数据包中。只有 BUS、DEVICE、FUNCTION、OFFSET 出现在事务中或总线上。但是,SEGMENT 在基于 SEGMENT:Bus,Dev,Func:OFFSET Configuration Space 软件地址的逻辑软件如何用于实际创建互连协议包 (PCIe) 或总线周期序列 (PCI ) 被描述为配置 Space 事务。在 PCI-Express (PCIe) 规范扩展配置 Space 访问方法 (ECAM) 中,这已部分解决。其余部分由 PCI 固件规范 3.2(涵盖更新的 PCIe 规范软件要求)处理。
在现代 PCIe 中,配置 Space 访问方法由操作系统的 ECAM 机制处理,操作系统抽象了这种配置 space 访问机制(将 CPU 内存 space 访问指令进入 Bus/Interconnect 配置 Space 事务)。操作系统软件将 SEGMENT/DOMAIN 理解为配置 Space 的 SEGMENT:BUS:DEVICE:FUNC:OFFSET 地址方案中的最高级别(最顶层)逻辑 select 或地址组件。 SEGMENT 如何从软件逻辑概念转移到物理硬件实例化,以 ECAM 转换器的形式出现,或者具体而言,平台中存在多个 ECAM 转换器。 ECAM 转换器在内存类型事务和配置 space 类型事务之间进行转换。 PCIe 规范描述了单个 ECAM 转换器实现如何将目标转换内存写入或读取中的特定内存地址位转换为配置 Space 写入或读取。其工作方式如下:
Address Bits:
11:00 (Offset bits, allows 4K of configuration space per PCIe device)
14:12 Function selection bits.
19:15 Device selection Bits.
27:20 Bus Selection Bits. 1 <= n <= 8 (Maximum of 8 bits, 256 numbers, can be less)
63:28 Base address of the individual ECAM.
真正没有明确(或根本)没有涵盖的是,多个 ECAM 可以存在。一个平台可以设置多个 ECAM 区域。平台为什么要这么做?因为 ECAM 地址位(8 位)的总线 selection 位允许是限制性的,只允许系统中总共有 256 个总线,这在某些系统上是不够的。
PCI 固件规范 3.2(2015 年 1 月 26 日)从软件逻辑角度描述了 ECAM。固件规范描述了称为 MCFG table 的软件内存结构(存在于 BIOS 保留区域中,BIOS 和操作系统使用该保留区域进行通信)。 MCFG table 描述了平台硬件实现中存在的基于 ECAM 硬件配置 space 循环生成器的一个或多个实例。这些是内存地址 space 事务(内存写入)到配置 space 周期事务转换区域。例如ECAM 硬件实现是 CPU 实例化以允许通过软件生成配置 Space 事务的机制。平台实现(通常由 CPU/Chipset 设计指定和限制,但有时也由 BIOS 设计选择决定)允许一定数量的 ECAM 配置 Space 周期生成器。一个平台必须至少支持一个,然后它才会有一个 SEGMENT。但是一个平台可能支持多个ECAM,那么对于每个支持的ECAM它都有一个SEGMENT。 MCFG table 拥有平台支持的每个 ECAM 配置 Space 基地址分配结构。单个 SEGMENT 平台将只有一个条目,multi-SEGMENT 平台将有多个条目,每个支持的 ECAM 一个。每个条目包含内存基地址(ECAM 区域配置Space 周期生成器),一个与此ECAM 和sub-range 总线编号对应的逻辑SEGMENT 组,以及一个sub-range 总线编号(开始和结束)存在于这个逻辑段中。
一个 BIOS 不能仅仅决定它需要很多 ECAM 并描述多个 ECAM 并使用常规内存地址作为“基地址”。硬件实际上必须通过设计将内存地址实例化为配置 Space 循环生成逻辑,该逻辑锚定到特定地址(有时由 CPU/chipset 设计固定,有时可根据位置配置 CPU/chipset BIOS 可以编程的特定 non-standard 位置配置寄存器。)在任何一种情况下,BIOS 描述了存在的 ECAM,并且根据设计,描述了一种方式, 或特定的 m配置(或禁用)ECAM 组的 nner 描述系统上活动的一个或多个活动 ECAM。此类 BIOS 配置的一部分包括设置可配置的 ECAM,如果可配置,则选择启用的数量,它们将位于何处(在什么基地址),以及配置哪些芯片组设备对应于哪些 ECAM,以及配置哪些根端口对应于哪些 ECAM 并与其相关联。一旦 BIOS 内部配置完成,BIOS 必须向操作系统描述这些平台硬件和 BIOS 决策。这是使用 PCI 固件规范定义的 MCFG table 完成的,它是 ACPI 规范的一部分,用于 BIOS(固件)到操作系统平台描述定义机制。
使用 MCFG table 方案,可以拥有并描述多个 ECAM 和多个逻辑段,每个 ECAM 一个。也可能只有一个 SEGMENT,它实际上也被拆分为多个 ECAM。 (多个条目,但都使用相同的段,然后是 non-overlapping 总线编号。)但是 MCFG 在 multi-segment 配置中的典型用途是允许多个段,其中总线编号重复.例如每个 SEGMENT 最多可拥有 256 条总线,与另一个 SEGMENT 中可能存在的最多 256 条总线分开。
三组软件都知道配置 Space 寻址中的段。 BIOS(创建 MCFGtable),操作系统(读取 MCFGtable,获取 ECAM 基地址,并通过访问处理逻辑到物理地址转换软件任务正确的 ECAM,在正确的偏移量处),最后一组是所有其他总线、设备、功能 (BDF) 感知软件。所有软件都必须是 SEGMENT、BUS、DEV、FUNC 感知的,而不仅仅是 Bus、DEV、FUNC 感知的。假定 SEGMENT 始终为 0 的软件是 BROKEN。如果你曾经创建过这样的软件,你应该赶回你的办公桌并立即修复它,在任何人看到它之前,当然在它在产品中发布之前! :-)
平台设计(在硬件 ECAM 支持和 BIOS 设计中)可以实现多个 ECAM。这通常是为了规避仅使用单个 ECAM 时出现的 256 总总线限制。因为 ECAM 是由 PCISIG 定义的,并且因为该定义围绕总线上的总线数量限制(在事务字段中),单个 ECAM 无法为超过 256 条总线实现配置 Space 生成器。然而,平台 CAN 和 DO 实例化多个 ECAM 区域,并有一个 MCFG table 描述具有多个 ECAM 基地址的多个段,这允许平台拥有超过 256 条总总线。 (但是在以 PCIe 根端口为根的每个 PCIe 设备树中最多只有 256 个总线,并且共享一个公共 ECAM 配置 Space 生成器的所有根端口一起最多只有 256 个总线。每个 ECAM 区域可以描述在其域(或段)中最多 256 条总线。平台系统如何决定将主机根端口(缓存一致域到 PCI/PCIe 域桥)分组到段中是平台特定的,并且对 chipset/CPU 设计是任意的和 BIOS 配置。大多数平台是固定和简单的(通常只有一个 ECAM),有些平台灵活、严格和可配置,允许多种解决方案。提供最大的解决方案类型在平台级别使用的 PCIe 总线数量是为了支持每个根端口一个 ECAM。(现在很少有平台这样做,但都应该!)它们是用于描述平台“如何”决定对设备进行分组的两种机制,端点,并切换到 SEGMENT。第一个是 afore-mentioned MCFG结构,它简单地列出了多个 SEGMENTS,它们相关的 ECAM(如果一个 SEGMENT 中的总线范围被多个 ECAM 分割,则可能不止一个),以及每个 ECAM 的基地址(或 ECAM 总线编号 sub-region)。这种方法本身通常足以完成许多枚举任务,因为这允许 OS 枚举所有段,找到它们的 ECAM,然后对每个 SEGMENT 中的所有设备进行 PCI Bus、Device、Function 扫描。然而,第二种机制也可用,它增加了 MCFG 信息,即 ACPI 名称中的 _SEG 描述符 space。 ACPI 规范有一个通用的平台描述机制,以独立于操作系统的方式描述系统中已知设备的关系,但允许操作系统解析数据并消化平台布局。这种机制称为 ACPI 名称space。在名称space中,设备是“对象”,因此通常描述固定并包含在 ACPI 实现系统主板上的 PCIe 端点、PCIe 根端口和 PCIe 开关。在这个名字space中,对象出现了,并且有限定符或修饰符。一个这样的装饰器“methd" 是 _SEG 方法,它描述了特定对象位于哪个 SEGMENT。这样,内置设备可以分组到特定的 ECAM 访问区域,或者更常见的是,特定的 PCIe ROOT 端口被分组到 SEGMENTS(和关联的 ECAM访问区域,MCFG 描述基地址)。此外,可以是 hot-added 的设备(并且不是静态存在于主板上的)可以描述它们在 hot-plug 上重新创建的段,或者 pre-existing 他们在 hot-plug 添加时加入的 SEGMENT,以及他们实例化的那个 SEGMENT 中的总线编号。这是在名称 space 中使用描述的 Root Port 对象上的 _CBA 方法装饰器完成的在这样的名称space中,它与_SEG方法结合使用。_CBA仅适用于top-level“已知”hot-plug可用元素,例如如果两个4 CPU 系统可以动态地“加入”到单个 8 CPU 系统中,它们各自的 PCIe 根端口元素也因此“加入” n" 新的单一系统,从原始基础 4 CPU 系统的 PCIe 根端口扩展,以包括添加的 4 CPU 的新附加 PCIe 根端口。
对于出现在插槽或外部扩展机箱中的 PCIe 交换机,_SEG(或 SEGMENT 值)通常继承自平台中已有的最高级根端口,位于该 PCIe 设备树的顶层。包含该根端口的段,也是该根端口下的所有设备所属的段。
人们经常阅读较早的资料(在发明多个 ECAM 之前,以及配置 Space 和相关操作系统软件中的段的概念),PCIe 枚举是通过扫描总线编号完成的,然后是设备编号,然后是功能编号。这是不正确的,而且已经过时了。实际上,MODERN (CURRENT) BIOS 和操作系统实际上是通过分段(select 使用 ECAM)、总线编号、设备编号,最后是功能进行扫描编号(在特定 ECAM 内应用偏移量)以在特定 PCIe 根端口(例如,在特定 PCIe 设备树上)之上和之下生成配置周期。
较旧的“PCI”机制(在为 PCIe 定义增强配置配置 Space 之前)无法识别 SEGMENT。当硬件平台支持时,较旧的 CF8/CFC 配置 space PCI 访问机制(不应再被任何新编写的软件使用)通常实现遗留的最佳实用解决方案 PCI-only(不是 PCIe-aware)感知操作系统,旧机制被硬编码到该机制的 SEGMENT 0。这意味着 PCI-only-aware 系统只能访问 SEGMENT 0 中的设备。所有主要操作系统都支持 PCIe ECAM 增强机制超过 10 年,并且软件对 CF8/CFC 机制的任何使用今天被认为是过时的、陈旧的和破损的,应该被现代使用的 ECAM 机制所取代,至少支持 MCFG table 和多个 ECAM,如果操作系统要求,补充通过 ACPI 规范名称space _SEG 和 _CBA 属性对象方法信息由操作系统为完全动态 hot-plug 情况摄取。如果 OS 没有将 ACPI 热插拔方法用于其他任务,几乎所有 non-hotplug 情况都可以由 MCFG 单独处理。如果 OS 对其他设备和名称space 操作使用 ACPI 热插拔,那么通常还需要支持 _SEG 和 _CBA,操作系统和 BIOS 才能生成这些 APCI 名称 space 对象以描述设备关联的方式分组到 SEGMENT,从而描述到支持该设备、根端口或根复合桥或设备的配置周期生成的特定 ECAM 硬件。现代软件使用 SEGMENT,只有损坏和不正确的软件会假定所有设备和桥都存在于 SEGMENT 0 中。现在这并不总是正确的,并且随着时间的推移越来越不正确。
SEGMENT 分组倾向于遵循硬件设计中的一些逻辑原理以及对该设计配置的限制。 (但并非总是如此,有时,它只是随意和奇怪。)例如,在 Intel 8 套接字系统(大型多处理器)上,“本机”一致性实现在大多数情况下往往限于 4 个套接字。当供应商构建一个 8 插槽系统时,通常是通过在它们之间的连贯互连上将两组 4 个插槽每组连接到一个集群交换机来完成的。这种类型的平台可能会实现两个 PCIe 段,每个 4 个插槽集群一个。但是对于平台可能希望如何使用多个 SEGMENT 和使用多个 ECAM 没有限制。一个双套接字系统可以实现多个 ECAM,每个 CPU 一个 SEGMENT,在 o每个 CPU 最多允许 256 个 PCIe 总线,总共 512 个。如果这样的平台改为将来自两个 CPU 的所有根端口映射到单个 SEGMENT(更常见),那么整个平台只能有 256 个总线用于整个平台。优化设计的平台(在 ECAM 硬件资源方面更昂贵)将为系统中的每个根端口提供一个 ECAM,并为平台中的每个根联合体设备提供一个 ECAM。一个有 8 个根端口的两个 CPU 系统,每个 CPU 上有 4 个,每个 CPU 上有 4 个根联合体,将实现 16 个段,其中 8 个(根端口段)将每个支持最多 256 个总线,8 个支持的 Root Complex 设备树将实例化足够的总线支持来映射 Root Complex 设备和桥。因此,如果在 2048+ 总线的高端提供总线支持,这样一个完全组成的双插槽系统将支持最多 8*256 + 内置 Root Complex 设备所需的总线。今天设计的任何“真实”服务器都应该这样设计。我还在等着看这个现代的“真正的”Intel 或 AMD 服务器,而不是这些天推出的玩具。
大多数操作系统软件不需要关心“如何”实现段关联,它们只需要考虑逻辑段值是配置的一部分这一事实 SPACE 寻址(不要编码你的东西只是总线、设备、功能,假设 SEGMENT=0) 它必须被编码为 (SEGMENT, BUS, DEVICE, FUNCTION) 除非你想被标记为 slacker-type,做错了,[=120= 】 低能。支持SEGMENT值!它们现在很重要,并且将来会变得越来越重要,因为总线编号 space 和平台 运行 受到更大的压力,因为限制在低级和限制性的 256 总线上存在于单个 SEGMENT 中。单个 SEGMENT 限制的发生是由于硬件设计,但也可能是因为软件没有为 multi-SEGMENT 平台正确编写和准备。不要成为创建错误 single-SEGMENT (SEGMENT =0) 假设软件。不要成为那个人!)不要以这种方式编写操作系统软件。不要以这种方式编写 BIOS 软件,不要编写可感知 Bus、Device、Function 但不感知 SEGMENT、BUS、DEVICE、FUNCTION 的应用程序。
平台操作系统软件(在 *nix 的内核中,或在 Windows 的 HAL 中)获取 SEGMENT 值,并将其用于 select 它将访问的 ECAM(例如哪个ECAM 基地址它将添加 BDF/offset 内存地址偏移量)。然后它使用总线、设备、功能值索引到该 ECAM 中的较高地址位,最后它使用配置 Space 设备寄存器偏移地址填充输入的内存地址的较低部分ECAM 配置 Space 交易生成器作为其内存地址交易输入。
在英特尔兼容平台(英特尔和 AMD 等)上,PCI 固件规范和 ACPI 规范描述了 BIOS 如何告诉操作系统(Linux、Windows , FreeBSD 为例) 关于一个 ECAM (单段) 或每个 ECAM (多段) 基地址位于内存地址中的位置 space.
段从不出现在 PCIe 或 PCI 的总线上。在 PCIe 中,RID(路由标识符)仅对发送方的 Bus# 和 Device/Func# 进行编码。同样在配置周期中,只有目标目标的 Bus# 和 Device#/Func# 在下游事务中编码。如果启用 ARI(替代路由 ID)模式,Device/Func# 可以在 PCIe 中获得修改处理。但是 SEGMENT 值没有出现(也没有出现在 PCI 总线序列中)。它本质上是一个软件构造,但具有平台硬件支持(CPU 和芯片组)形式的真实硬件实例,用于多个 ECAM(multi-SEGMENT)或仅单个 ECAM(single-segment).请注意,不同 SEGMENT 中的设备实际上仍然可以进行点对点直接通信。点对点事务使用内存寻址进行(这是所有段之间的单个全局共享 space,例如,所有段仍然共享一个统一的内存地址 space,至少在 IOMMU 转换和通过根传输之后端口,这是可能位于不同 SEGMENT 上的先决条件)。 SEGMENT 可以有冲突和重复的总线编号 spaces,但是当它们出现在不同的 SEGMENT 中时,它们描述了不同的总线。多个 ECAM 系统实际上可以实现单个共享总线地址 spaces 以及独立的重复总线编号 space。实际上这很少见,因为系统通常会使用单个 ECAM 和单个 SEGMENT 用于单个总线地址 space。然而,一些奇怪的硬件可能需要使用 single-segment、multi-ECAM、跨多个 ECAM 的共享单总线 运行,为 256 个最大有限总线 space 提供有些奇怪设计的简单性(通常与热插拔或动态配置相关。)
一个理论上的平台,其“chipset/uncore”组件中有大量内置设备,并且其设计中有两个 CPU 插座,如果需要,可以实现四段设计。它可以将所有内置 CPU 设备放在它们自己的段中(每个 CPU 一个),使用两个段,然后将每个 CPU 的 PCIe 根端口映射到它们自己的SEGMENT,又是每个 CPU 一个唯一的 SEGMENT,总共 4 个 SEGMENT。这将允许整个系统中有 4 * 256 = 1024 个总线。
一个不同的理论平台,具有相同的两个插槽数,可以将所有 CPU(在本例中只有两个)和所有内置设备的所有设备,以及所有现有的根端口映射到一个单一的ECAM,因此是单个 SEGMENT。这样的平台将只有一个 ECAM,因此整个系统将被限制为总共 256 条总线(因此,如果平台是加载了大而复杂的 multi-endpoint add-in 卡,带有 PCIe 开关以支持 multi-device 当前。例如,前置 AI 支持 GPU 卡,或者如果它有多个 fan-out 开关(以增加其插槽数量),或者该供应商是否正确使用和支持外部 PCIe 开关扩展器(到外部 PCIe 机箱)。
目前正在设计的“最佳”平台,未来将为每个根端口实现独立的 ECAM,允许每个根端口在其设备树中单独支持多达 256 条总线,独立于每个其他根端口。迄今为止,我仍在等待这个平台,它有大量的 PCIe 段对应大量的 PCIe 根端口。此类设计对于 Compose-able I/O 解决方案、共享内存解决方案、分层内存解决方案、compose-able 存储解决方案、大型外部 I/O 外壳解决方案、支持 CXL 的解决方案至关重要加速器等。换句话说,用于现代计算。当一个平台出来并说它的时钟比上一个多 5% 时,我打哈欠。当出现一个支持每个根端口 ECAM 的平台时,我会注意到,那个平台将获得我的金印。
总线数 space 的压力现在处于临界点,因此在不久的将来可能会使用更多的段(或者应该是,如果英特尔和 AMD 正在关注的话)。像 CXL(一种 PCIe 软件模型兼容的总线基础设施)这样的技术只会增加单个 SEGMENT 的 Configuration Space 总线数量限制的压力(如今 256 条总线并不多。)每个交换机在内部使用一条总线,每个 link 使用总线,因此插槽数大、扇出高的系统将消耗超过 256 条总线。 Multi-SEGMENT 设计现在就在这里,而且会越来越普遍。立即修复您的软件!
参见:
PCI Express Base Spec 5.0(或任何更早版本) 7.2. PCI Express 增强配置访问机制 (ECAM) http://www.pcisig.com
PCI 固件规范 3.2(或更新版本)http://www.pcisig.com 4.1.2 MCFG Table 说明
ACPI 规范“MCFG”定义http://uefi.org _SEG(段)名称space ACPI 名称space 描述中的限定符。
UEFI 规范 http://uefi.org 描述了 OS 如何在具有 UEFI 的现代 UEFI 平台中找到 MCFG table 和所有其他基于 ACPI 的 table BIOS(引导固件)。