几天前我们一篇文章《一文讲懂主机启动时是如何给每个PCIe外设分配BDF的》,有工程师留言问:电脑加电启动的时候,PCIe是全部训练完再枚举,还是训练一个枚举一个?
因为枚举需要稳定的 PCIe 拓扑结构(Topology),包括:
哪些设备存在
每个设备是哪个 Bus/Device/Function
每条链路最终的速度、宽度(Gen / Lanes)
下游设备是否连通
Switch 的下游 port 是不是 active
如果链路没有全部训练成功(进入 L0),根本无法构建完整拓扑。
因此 PCIe Base Spec 要求在枚举开始前,所有链路必须完成 LTSSM → L0。
链路训练包含:
Detect
Polling
Configuration
Recovery(必要时)
L0(链路正常状态)
这是PCIE PHY + MAC(硬件自动完成),极少需要 CPU 参与。
训练过程与设备枚举(RC 软件过程)完全独立。
枚举过程包括:
这一阶段属于 PCI Firmware Spec 定义的流程,在 BIOS 中由 RC(Root Complex)程序执行。
也就是说:
只有当所有链路都进入 L0,BIOS 才能完整看到整个 PCIe 拓扑,然后开始枚举。
正常 PC/服务器启动流程 —— 不会!
但是有两种特殊例外情况值得你关注:
Hot-plug port 上:
Link Training 在设备插入后发生
RC 会动态枚举新增设备
但这是运行时行为,不属于系统加电启动流程。
例如一些 Broadcom/PLX Switch 型号可能:
Port A 训练成功
内部 switch firmware 提前对下游 port 做一些预扫描
但这属于 Switch 内部行为,RC 枚举依然要等所有链路可用后才统一开始。
PHY 完成 LTSSM 流程
链路进入 L0 或失败进入 Recovery
你抓加电 trace 会看到:
例如:
Config Read Type 1 → 扫描 Bus
Config Read Type 0 → 针对 Endpoint
Memory Write → 写 BAR
这正是枚举开始的标志。
这很明确地说明:
枚举发生在所有链路训练之后。
PCIe 在系统加电启动时,所有链路必须先完成 Link Training(进入 L0),然后 Root Complex 才能进行统一的 Bus Enumeration。不会训练一个枚举一个。
例外仅在热插拔或某些 switch 的内部预处理流程,普通服务器/PC 不会边训练边枚举。
https://pan.baidu.com/s/18_c11aeFhSBe2qa-jUFs_Q?pwd=mm9y 提取码: mm9y
如果你有其任何关于PCIe5&6.0, CXL, NVMe/NVMoF, NAND, DDR5/LPDDR5以及UFS测试方面的我问题想咨询,请访问:访问www.saniffer.cn / www.saniffer.com 访问我们的相关测试工具和产品;或者添加点击左下角“阅读原文”留言,或者saniffer公众号留言,致电021-50807071 / 13127856862,sales@saniffer.com。