第3章 PCIe链路层协议:事务层、数据链路层、物理层归纳总结
做PCIe故障排查,不能只盯着示波器上的眼图。你得先把协议栈三层搞清楚——事务层、数据链路层、物理层各管各的,但它们配合出错时,故障现象往往是一团乱麻。我个人习惯是先把具体现象归到某一层,再顺着链路往下找,效率高很多。
3.1 事务层——PCIe的“上层大脑”
事务层处在协议栈最上面,直接跟软件打交道。它的核心产物就是TLP(事务层包)。说白了,CPU发一个读请求,到了事务层就被打包成Memory Read TLP,带上地址、长度、标签等信息,交给下层。
我记得有一次客户上报NVMe硬盘间歇性掉卡。看了链路没降速,但读性能就是上不去。后来用逻辑分析仪抓了TLP,发现请求标签被复用——同一标签的写事务还没完成,又被发出去。这就是典型的事务层排序违规。修正配置后问题消失。
事务层主要管三件事:
- TLP封装:请求、完成、消息三类包的生成与解析。
- 事务排序:遵守PCIe Base Spec中的排序规则(例如写必须优先于读)。
- 流量控制:通过Credits机制管理接收缓冲区,避免丢失TLP。
避坑提示: 流量控制Credits耗尽不会直接报错,但会导致TLP被滞留在发射端。排查传输延迟时别忽略这项,用PCIe分析工具直接读FC状态寄存器就行。
3.2 数据链路层——可靠传输的“保险杠”
数据链路层在中间夹着,它负责让TLP可靠地穿越物理链路。它的两个关键机制:Ack/Nak协议和CRC校验。TLP从上层下来,数据链路层会加上序列号(Sequence Number)和LCRC(链路CRC)。接收端收到后回DLLP(数据链路层包)表示确认或要求重传。
我踩过一个坑:某服务器在高温环境下持续发生链路重传。看上去物理层眼图还行,但数据链路层的Ack超时计数器频繁溢出。最终发现是参考时钟抖动超标,导致数据链路层CRC偶尔错误。温度降下来就好了。这告诉我——物理层“能用”不代表数据链路层“可靠”。
数据链路层的核心职责:
- TLP序列化:给每个TLP加序列号,并计算LCRC。
- DLLP交换:管理Ack/Nak、电源状态、Flow Control Update。
- 重传与丢弃:接收端发现CRC错误时Nak该TLP,发送端重传。
- 链路初始化与培训:配合物理层完成LTSSM状态跳转。
| 故障现象 | 可能原因 | 排查方向 |
|---|---|---|
| Ack超时 | 数据链路层缓冲区满或接收端卡住 | 检查DLLP接收超时寄存器 |
| 重传次数暴增 | 物理层BER偏高或CRC逻辑异常 | 抓取LCRC错误计数 |
| 链路反复训练 | DLLP丢失导致LTSSM回退 | 用示波器看LTSSM状态切换 |
3.3 物理层——信号的“翻译官”
物理层是协议栈的最底层,直接处理差分线上的串行信号。它分逻辑子层和电气子层。逻辑子层负责加扰、编码(Gen3以下是8b/10b,Gen3及以上是128b/130b)和链路均衡;电气子层管驱动电流、去加重、接收均衡这些模拟参数。
为什么链路均衡容易出问题?因为物理层需要发送端和接收端双方协商才能达到最佳信号质量。如果均衡系数没谈拢,眼图就会闭合,BER变高,然后数据链路层开始重传,最后可能触发LTSSM回退到低速率。
我自己调试过一个案例:Gen4链路在长走线(约25英寸)上始终只能跑Gen2。用示波器看,Preset值锁在默认的低预加重状态,接收端均衡也一直申请不到更高系数。最后发现是接收端PHY的均衡协商寄存器没有正确配置回读,强制硬件写即可解决。
小技巧: 排查物理层均衡故障时,先看LTSSM在哪个状态卡住(Polling.Config.Detect…)。如果是Config.Linkwidth.Start或Config.Linkwidth.Accept停留过久,多半是物理层的均衡手挽手没完成。
3.4 三层如何协同工作
一个完整的PCIe读写事务,从上到下的流程如下:
- 软件发起Memory Read请求(事务层)→ 打包成TLP。
- 数据链路层在TLP上加序列号和LCRC,然后通过DLLP发送。
- 物理层把TLP加扰、编码,再通过差分线串行发射。
- 接收端物理层解扰、解码、均衡恢复,把数据恢复给数据链路层。
- 数据链路层校验LCRC,确认无误后回复Ack DLLP,将TLP上抛给事务层。
- 事务层将TLP解析,返回给软件或者触发完成中断。
哪一层出问题,表现都不同。我的经验是:事务层问题常表现为软件超时或TSI码流异常;数据链路层问题常表现为链路重传计数持续增长;物理层问题常表现为链路降速或眼图闭合。
注意:不要把物理层的降速误判为数据链路层拥塞。先看LTSSM状态,再看DLLP错误计数,最后看TLP流量,三步定层。
3.5 本章小结(一张分层对比表)
为方便你快速对照,我把三层协议的关键差异放在下面。这张表我一直在手上存着,排查故障时随时翻翻,很实用。
| 协议层 | 主要数据单元 | 核心机制 | 典型故障定位手段 |
|---|---|---|---|
| 事务层 | TLP | 排序、流控、TLP封装 | 逻辑分析仪抓TLP头,检查标签、地址、长度 |
| 数据链路层 | DLLP | 序列号、LCRC、Ack/Nak、重传 | 读数据链路层寄存器(重传计数、CRC错误计数) |
| 物理层 | 有序符号集(OS)、加扰数据 | 编码解码、加扰、LTSSM、链路均衡 | 示波器测眼图、BER扫描、LTSSM状态机分析 |
分层清楚,排查不慌。后面几章我会带你看几个真实的链路均衡故障案例,用今天这三层的知识去套,你会发现其实没那么难。