PCIe 最关键的取舍:
保留 PCI 的软件模型(load-store、枚举、配置空间),只把"并行总线"换成"串行点对点 + 分组交换"的物理实现。
PCIe 之所以能"无缝替换 PCI",不是因为它物理上兼容 PCI,而是因为它在软件眼里长得跟 PCI 一模一样——操作系统和驱动完全感知不到下面是串行链路。
1.1 An Evolving I/O Interconnect
第一类:市场与经济性
第二类:软件兼容
- 用现有 PCI 配置软件就能枚举/配置,不用改
- 现有操作系统能直接启动,不用改
- 现有设备驱动直接能用,不用改
- 新功能通过 PCI 配置范式(configuration paradigm)来使能
这是怎么做到的?靠三样东西在 PCIe 里被原样保留:
- 配置空间:每个 Function 有一个 256 字节的、PCI 兼容的配置头(vendor ID / device ID / BAR / 中断引脚等字段位置不变),后面再接 PCIe 扩展能力(capability)链表。
- 枚举机制:软件还是按 "bus / device / function" 三级去扫描(扫 bus 0,读 header type 判断是不是 bridge,再往下扫……)。
- 地址模型:Memory-mapped I/O(通过 BAR 把设备寄存器映射进内存地址空间)+ I/O 空间。
因为这三样没变,老软件完全不知道自己在跟串行链路打交道。
第三类:性能
- 低开销、低延迟→ 最大化有效带宽和链路效率(header 小、协议栈薄)
- 每引脚高带宽→ 串行差分对(每方向一对差分线就是一个 Lane)比并行总线的引脚效率高得多
- 通过聚合 Lane 和提升速率来扩展性能→ 这就是你们熟悉的x1/x4/x8/x16(Lane 数)× Gen 速率(2.5/5/8/16/32/64 GT/s)两个可扩展维度
第四类:高级特性
① 数据类型与排序规则
- PCIe 事务分 Memory / IO / Configuration / Message 四类,再加 Posted / Non-Posted / Completion 三种属性
- 排序规则(ordering rules)保证同一生产者-消费者模型下数据一致性不被打乱。这是 PCI 的"编程模型"能在 PCIe 上成立的前提。
② 电源管理(PM)
- 识别某 Function 的电源能力(读 capability)
- 把 Device/Function 切到特定电源状态(D0–D3)
- 收到当前电源状态通知
- 从主电源关闭态发起唤醒(WAKE# / PME)
- 给设备上电排序(power budgeting,避免同时上电把系统电源拉垮)
③ QoS(差异化服务)这是 1.1 里较新、也较容易被忽略的一块,值得单独展开:
- 每个 QoS 数据流有专用链路资源→ 缓解head-of-line blocking(队头阻塞):一条低优先级的大流量堵在前面时,高优先级流量不必排队等它
- 每个组件内可配置仲裁策略(arbitration)
- 每个包都能打端到端的 QoS 标签→ 这就是TC(Traffic Class)字段,配合VC(Virtual Channel)实现物理/逻辑上的分流
- 能做**等时(isochronous)**传输,用注入速率控制来保证时延上界
④ 热插拔(Hot-Plug)
- 支持老的 PCI 热插拔方案(带 sideband 信号)
- 支持原生热插拔(不需要额外边带信号,用带内消息如 Presence Detect + 电气层检测)
- 支持异步拔出(设备突然被拔走,不通知系统)
- 所有形态统一一套软件模型
⑤ 数据完整性
- 链路级完整性:每个 TLP 带 CRC(LCRC)、DLLP 带自己的 CRC,覆盖所有交易层和数据链路层包 → 保护的是"这一跳链路上"不被破坏
- 端到端完整性:ECRC(End-to-End CRC),用于高可用系统,保护从发送端到接收端(可能跨 Switch)全程不被破坏
⑥ 错误处理
- 兼容 PCI 的错误处理(老的 parity/status 位)
- AER(Advanced Error Reporting):更细的故障定位和恢复,把错误分级(Correctable / Uncorrectable Non-Fatal / Fatal),这是做 RAS(Reliability/Availability/Serviceability)的基础
⑦ 工艺独立性
- 允许 TX 和 RX 用不同的 DC 共模电压。不同工艺节点/不同厂商的芯片,其发送端和接收端的直流偏置可能不一样,所以 PHY 要支持 AC 耦合,把 DC 共模隔离掉。这是为什么 PCIe 链路(和几乎所有 SerDes 互联)都要串一个 AC 耦合电容。
⑧ 易测试性
- 通过简单连到测试设备就能做电气一致性(electrical compliance)测试,不用复杂夹具。
1.2 PCIe Link
- Dual-simplex(双单工):这是 PCIe 的实现方式——用两条独立、单向的链路拼成一个双向链路,而不是一条能双向传的信道。
- PCIe没有单独的时钟线。接收端怎么知道每个比特的边界在哪?答案是:时钟藏在数据流里,靠编码方案保证有足够的信号跳变,接收端从这些跳变里恢复出时钟(CDR,Clock Data Recovery)。
链路宽度和速率是两端硬件在加电后自己"谈判"出来的(Link Training),全程不经过固件或操作系统。
- x16 = 每个方向 16 对差分线,不是"总共 16 对"。
- 所以一个 x16 Link 的物理引脚是16 对 TX + 16 对 RX = 32 对差分线 = 64 根信号线(再加边带信号)。
1.3 PCI Express Fabric Topology
1.3.1 RC
P2P路由
两个不同 Root Port 下面的设备(分属不同 hierarchy domain)要互相通信(P2P),数据得经过 RC。但 RC 怎么做这件事,规范说是可选的、实现相关的。两种合法做法:
"冒名顶替":
- RC 把 P2P 的 Request 拦下来,拆包/重组,让最终的 Completer 以为请求是 RC 自己发的。
- 收到 Completion 后,RC 再把它重组,送回真正的 Requester。
- 好处:RC 不用实现完整的 Switch 转发逻辑。
内嵌真/假 Switch:
- RC 在内部实现一个真实或虚拟的 Switch,做软件透明的完整 P2P 支持。
- 软件看起来就像数据经过了普通 Switch 一样。
拆包规则(RC 特有,Switch 没有这个权力)
RC 在 P2P 时可以把一个包拆成几个小包(Switch 不允许),例如把 256B payload 拆成 2×128B。但拆完要遵守规范里的成包规则(Max_Payload_Size、Read Completion Boundary / RCB等)。
- 警告:拆包可能有性能损失,尤其当目标设备在PCIe→PCI/PCI-X bridge后面时(老桥对拆包的容忍度差)。
- 例外 1:P2P 路由Deferrable Memory Write(Gen6 新事务)时不允许拆包。
- 例外 2:P2P 路由Vendor_Defined Message时不允许拆包,除非按 128 字节边界拆(即除最后一个包外,其余都是 128 字节整数倍)——这是为了保住消息能穿过 PCIe→PCI/PCI-X bridge 的能力。
RC的职责清单
三个要点:
- RC 必须能发配置请求——因为整个系统的枚举就是 RC 往下发 Config Read/Write 完成的。
- I/O 空间对 RC 是"可支持"——因为要兼容老 PCI 设备。
- Lock 语义:RC 不能"响应"别人的锁,但可以"发起"锁——这是为了兼容老软件对老 PCI 设备上锁(legacy 软件需求)。
1.3.2 EP
Endpoint 分三类:
- Legacy Endpoint(遗留端点):本质上是"老 PCI 设备披上 PCIe 外衣",为向后兼容保留了老行为。
- PCI Express Endpoint(原生端点):真正的 PCIe 原生设备,遵守更严格的新规则。
- RCiEP(Root Complex Integrated Endpoint,RC 集成端点):直接做在 RC 内部逻辑里的端点,没有物理 Link。
- 现代 PCIe 设备应该全用 Memory-mapped I/O(通过 BAR 映射进内存空间)。规范在引导整个生态抛弃 I/O 空间。所以原生 EP 禁止 I/O,而 Legacy EP 保留 I/O 是为了让老设备还能用。
- 现代系统内存已经远超 4GB,PCIe 设备作为 DMA 发起者(Requester)必须能寻址到 4GB 以上的内存。Legacy EP 是迁就老设备所以不强制;RCiEP 要求"≥ Host 能处理的地址"是因为它和 Host 一体,跟着 Host 能力走。
RCiEP 有一堆"不得/不适用"是因为它没有物理 Link(做在 RC 内部逻辑里),所以:
- 链路寄存器(Link Capabilities/Status/Control)没有意义 → 不得实现
- ASPM(链路的电源管理)没有意义 → 不实现
- 不能独立热插拔(它和 RC 长在一起,要插拔就得连 RC 一起)
- 不得出现在 hierarchy domain 里——因为它不在任何 Root Port "后面",而是和 Root Port 平级待在 RC 内部。这是它和另外两类端点最本质的区别。
- 只能通过Root Complex Event Collector上报 PME/错误(因为没链路可走),且只能关联一个。
1.3.3 Switch
一个 Switch 结构上就是:一个Upstream Port(朝上连 RC 或上层 Switch)+ 多个Downstream Port(朝下连 Endpoint 或下层 Switch),每个 Port 在配置空间里都表现为一个虚拟 PCI-to-PCI Bridge。所以配置软件看到 Switch = 看到 N+1 个桥(1 个上游 + N 个下游)。
Switch的转发规则
① Switch 不许拆包,RC 可以拆包。这是 Switch 和 RC 转发行为上最鲜明的区别。
② 基于地址的路由(address-based routing)。Switch 决定往哪个下游口转发,靠的是内存/IO 地址落在哪个桥的 base/limit 寄存器范围内。
③ 仲裁规则。多个 Ingress Port(入向链路)争同一个下游口、且在同一 Virtual Channel(VC)上发生竞争时,用round robin(轮询)或 weighted round robin(加权轮询)。
1.3.4 RCEC(RC Event Controller)
RCiEP 没有物理 Link,所以它没法像普通设备那样通过链路报错、报电源管理事件(PME)。那它的 error/PME 消息发给谁?RCEC 就是来收这些消息的。可以把 RCEC 理解成 RCiEP 的"消息终结者/接收站"——RCiEP 把 error 和 PME 消息发给它,由它来终结处理。
- 遵守 RCiEP 的所有规则——它本质上是 RCiEP 的一个特殊变体。
- 不要求解码任何内存/IO 资源——它不收普通事务,只收 error/PME 消息,所以不需要 BAR 映射地址空间。
- 通过Device/Port Type字段标识,并且Base Class 08h, Sub-Class 07h, Programming Interface 00h(这是软件识别它的类码)。
- 住在 RC 内的某条 Bus 上,一条 Bus 上可以有多个 RCEC。
- 通过RCEC Endpoint Association Extended Capability(关联扩展能力)显式声明它支持哪些 RCiEP。
- 整体是可选的(optional)。
1.4 PCIe layering Overview
1.4.1 Transaction Layer
职责:组装/拆解 TLP,管理基于信用的流控。
PCIe 里,"读"不是"CPU 占着总线等设备回数据"(老 PCI 是这样),而是拆成两个独立的事:
- Requester 发一个Request TLP(带唯一 Tag 标识),然后去干别的事。
- Completer 处理完,发一个Completion TLP(带同样的 Tag)。
每个包有唯一标识(Tag),这样多个请求可以outstanding,回来的完成包靠 Tag 对上号。这是 PCIe 能实现高并发、高吞吐的根基——总线不再被一个慢设备卡死。
TLP 的属性(attribute)
- No Snoop:告诉系统这个事务不需要做 cache 一致性(snoop)。
- Relaxed Ordering(RO):允许事务不严格按顺序完成,提升性能。
- ID-Based Ordering(IDO):基于 Requester ID 的排序扩展。
服务:
1.4.2 Data Link Layer
职责:链路管理 + 数据完整性(检错/纠错)。
发送侧:
- 接收 Transaction Layer 造好的 TLP
- 计算并附加 LCRC + 序列号
- 交给 Physical Layer 发出去
接收侧:
- 校验收到的 TLP 完整性(验 LCRC)
- 正确 → 交给 Transaction Layer
- 出错 →请求重传,直到收对,或判定链路失败
要点:
- 这里做的是链路级(link-level)完整性——保护的是"这一跳"不被破坏,不关心端到端(那是 ECRC,在 Transaction Layer,可选)。
- 重传机制是 Data Link Layer 的核心:发送端要把发出去的 TLP 存起来(Replay Buffer),收到对端 Ack 才丢掉,收到 Nak 就重发。
- DLLP 就是干这些活用的:Ack/Nak DLLP 做确认/重传,Flow Control DLLP 做流控更新,还有电源管理等。
服务:
- 初始化/PM:接受 Transaction Layer 的电源状态请求并传给 Physical Layer;把 active/reset/disconnected/power-managed 状态报给 Transaction Layer。
- 数据保护/检错/重传:CRC 生成、存储已发 TLP 供重传、错误检查、Ack/Nak 消息、错误上报。
1.4.3 Physical Layer
职责:所有物理电路 + 链路初始化和维护的逻辑功能。
电路层面:驱动器、输入缓冲、并串/串并转换(serdes)、PLL、阻抗匹配。 逻辑层面:链路初始化、宽度/速率协商、训练(LTSSM)。
服务: