3. PCIe协议概览
PCIe 不是一条“单纯的高速串行线”,而是一套严格分层的互连协议。理解 PCIe,最有效的方式是把它看成一条从软件请求到物理电信号、再逐层返回完成状态的“垂直数据通路”。同一笔内存读请求,会依次穿过事务层、数据链路层和物理层;对端收到后,再逐层向上还原。分层带来的好处是:软件只关心事务语义,链路可靠性由数据链路层保证,电气与时序细节由物理层处理。
事务层:TLP 是 PCIe 的“业务语言”
事务层负责把软件请求翻译成事务层包(TLP)。TLP 由 Header、可选 Data Payload 和可选 ECRC 组成。Header 中携带 Requester ID、Tag、地址或目标 ID、TLP 类型、长度等关键字段。PCIe 常见事务类型包括 Memory Read/Write、I/O Read/Write、Configuration Read/Write、Message 以及 Completion。事务层还负责路由:根据地址或 ID 决定 TLP 往哪个端口转发。
事务层同时承担流量控制与排序职责。发送端通过 Flow Control Credits 判断对端是否还有缓冲空间,避免盲目发送导致丢包;接收端则依据排序规则处理 Posted、Non-Posted 和 Completion 三类事务,保证内存一致性与完成顺序符合预期。
数据链路层:让链路“可靠”
数据链路层在 TLP 前后增加序列号和 LCRC,形成 DLLP 帧。接收端校验 LCRC,若正确则回 ACK,若错误则回 NAK,发送端据此重传。它还负责链路初始化、链路训练状态机、电源管理 DLLP 以及错误上报。可以说,事务层关心“做什么”,数据链路层关心“是否可靠送达”。
物理层:从比特到差分信号
物理层完成字节条带化、加扰、编码(如 8b/10b 或 128b/130b)、串并转换和差分发送/接收。它管理链路宽度(x1/x2/x4/x8/x16)和链路速率(Gen1~Gen5 甚至更高),并通过 LTSSM 完成链路训练与均衡。物理层还处理电气空闲、 Beacon、复位和热插拔信号。
配置空间与枚举流程
每个 PCIe 功能都有 4KB 配置空间。前 256 字节兼容 PCI,包含 Vendor ID、Device ID、Command、Status、BAR、Capability 等。Type 0 Header 用于端点设备,Type 1 Header 用于桥设备。枚举时,系统从 Host Bridge 开始,逐级扫描总线号、设备号和功能号,读取 Vendor ID 判断设备是否存在,再分配总线号、写 BAR、设置命令寄存器,最终让设备进入可用状态。
| 层次 | 核心单元 | 关键字段/机制 | 典型问题 |
|---|---|---|---|
| 事务层 | TLP | Requester ID、Tag、地址、ECRC | UR、CA、完成超时 |
| 数据链路层 | DLLP | 序列号、LCRC、ACK/NAK | 重传、LCRC 错误 |
| 物理层 | LTSSM、SerDes | 链路宽度、速率、均衡 | 链路降速、训练失败 |
| 配置空间 | Type 0/1 Header | BAR、Capability、Bus Number | BAR 未分配、枚举失败 |
案例:一次配置读的完整路径
CPU 发起配置读:
1. 软件写 0xCF8/0xCFC 或 MMIO 配置窗口
2. 事务层生成 CfgRd0 TLP,目标 Bus/Dev/Func
3. 数据链路层加序列号与 LCRC
4. 物理层编码并串行发送
5. 对端 PHY 恢复,DLL 校验并回 ACK
6. 事务层解析,读取配置寄存器
7. 生成 CplD TLP 返回数据
8. 软件获得 Vendor ID / BAR 信息
误区与复盘
- 误区一:把 PCIe 当成“透明总线”。实际上它是点对点、基于包的互连,必须经过枚举和路由。
- 误区二:只关注速率,忽略链路宽度和编码效率。Gen3 x4 与 Gen1 x8 的可用带宽可能接近,但延迟和均衡策略不同。
- 误区三:看到设备不识别就重装驱动。应先确认链路是否训练成功、配置空间是否可读、BAR 是否分配。
- 复盘方法:从物理层误码计数、DLL 重传计数、TLP 完成状态、配置空间枚举日志四个层面逐级排查。
掌握 PCIe 分层架构后,后续分析 UFS 与 PCIe 的互连、DMA 路径、中断机制和性能瓶颈时,就能准确定位问题发生在哪一层。事务层决定语义,数据链路层保证可靠,物理层决定电气与速率,配置空间与枚举则让软件“看见”设备。四者协同,才构成完整的 PCIe 互连体系。