9.11 RCD 枚举 (RCD Enumeration)
核心设计问题:如何将 CXL 设备“无缝”地集成到现有系统中?
在 CXL 诞生之初,设计者面临一个核心挑战:如何让一个采用全新协议的 CXL 内存或加速器设备,能够被那些不认识 CXL 的传统操作系统(Legacy OS)所接受和使用?如果要求所有系统立即升级才能使用 CXL,那将极大地阻碍其推广。
解决方案:RCD (受限 CXL 设备) 模式。
RCD 模式的全部设计,都是为了解决这个问题。它的核心思想是“隐藏复杂性,提供简单抽象”。它通过一系列机制,让 CXL 设备“伪装”成一个简单的、标准的 PCIe 设备,并将所有复杂的 CXL 相关配置工作,都交由万能的系统固件 (System Firmware) 在幕后完成。
分步解析:RCD 枚举中的“问题”与“解决方案”
问题一:如何向传统操作系统“隐藏”CXL 链路?
- 挑战: 一条 CXL 链路有自己的上游端口和下游端口,如果像标准 PCIe 交换机那样暴露给操作系统,传统 OS 会不认识这些 CXL 特有的端口类型,导致枚举失败或行为异常。
- 解决方案: 抽象为 RCIEP (根联合体集成端点)。
- 规范规定,在 RCD 模式下,CXL 链路两端的端口(RCH 下游端口和 RCD 上游端口)对传统 OS 的标准 PCIe 枚举流程是不可见的。
- 整个 RCH-RCD 物理结构,在 OS 看来被打包成了一个标准的 ACPI 主机桥 (Host Bridge),而 CXL 设备本身则表现为一个根联合体集成端点 (RCIEP)。
- 这样,OS 就像看到了一个直接集成在 CPU 上的设备,它只需要使用标准的 PCIe 流程来处理这个 RCIEP 即可,完全无需理解背后的 CXL 协议。
图 9-4 直观地展示了这种隐藏机制
问题二:如果 OS 看不见链路,由谁来配置它?
- 挑战: 既然链路被隐藏了,那么链路的训练、参数配置等初始化工作必须有人完成。
- 固件拥有“上帝视角”,它可以通过内存映射 I/O (MMIO) 的方式,直接访问和配置那些被隐藏的 RCH/RCD 端口寄存器。
- 整个枚举流程在 OS 启动前由固件主导完成,包括两个关键阶段:
- 中继器 (Retimer) 检测: 固件通过一个“试错-校准-重试”的软件流程,来精确地配置链路中的中继器数量,以确保物理链路的稳定。
- RCD 功能配置: 固件解析设备的 CXL 能力,并进行配置。
问题三:固件如何处理耗时长的内存初始化,而又不拖慢整个开机过程?
- 挑战: DRAM 内存初始化(如 training)可能需要很长时间。如果固件在开机自检(POST)阶段死等这个过程,会大大延长用户的开机等待时间。
- 解决方案: 提供两种内存初始化模式 (
Mem_HwInit_Mode
)。
- *硬件初始化模式 (
Mode=1
):* 这是简单直接的模式。设备硬件自己负责初始化。固件的责任就是等待硬件发出 Memory_Active
(内存已激活)信号。这种模式适用于初始化速度快的设备。
- 软件初始化模式 (
Mode=0
): 这是更灵活的模式,用于解决耗时长的初始化问题。
- 固件在 POST 阶段不等待内存初始化完成。它仅为内存规划好地址空间,然后就继续引导操作系统。
- 此时的内存是“离线”状态,无法访问。
- 真正的初始化任务被推迟到更高层的软件阶段,由 UEFI 驱动或操作系统驱动来接管。
- 这些驱动在后台慢慢执行初始化,完成后再通过特定命令激活内存。这样,用户可以先进系统,而内存则在后台“准备就绪”。
问题四:如何处理更复杂的物理拓扑(如多链路)?
- 挑战: 一个设备可能通过多条链路连接到一个或多个 CPU,如何向 OS 呈现这种复杂性?

- 单 CPU,双链路: 这种物理结构被抽象为两个独立的主机桥。这为固件提供了架构选择:可以将内存配置为两个独立区域,或者为了追求极致性能,配置为在两条链路间交织的单个高速内存区域。

- 双 CPU,双链路: 同样抽象为两个主机桥。但这里有一个严格的性能约束:为了避免昂贵的跨 CPU 缓存窥探,内存绝不跨链路交织。每个内存区域都被严格地视为其直连 CPU 的“本地内存”。
问题五:如何让为动态 VH 模式设计的设备,在静态 RCD 模式下工作?
- 挑战: 设备厂商可能希望设计一款能同时兼容动态 VH 模式和静态 RCD 模式的设备。但这两种模式的寄存器布局和访问方式完全不同,如何解决这个矛盾?
设备足够“智能”,当它检测到自己工作在 RCD 模式下时,会主动重映射 (Remap) 自己的内部寄存器,使其布局和访问方式完全符合固件对原生 RCD 设备的预期。固件无需任何特殊操作,即可正常使用。
设备保持其 VH 模式的寄存器布局不变。当固件尝试访问 RCD 模式下“预期”的寄存器地址时,设备会返回一个特殊的“无效”值——FFFFFFFFh
。这个值像一个暗号,告诉固件:“我不是原生 RCD,请用别的方法来找我的真实寄存器。”
- 固件的应对: 固件通过读取一个特定地址,检查返回值是否为
FFFFFFFFh
,就能轻松判断设备采用了哪种方案,并采取相应的后续操作。
通过上述一系列精心设计的“问题-解决方案”,RCD 模式成功地在确保对旧系统向后兼容性的同时,为 CXL 设备的静态集成提供了一条清晰、稳健且可行的路径。