PCIe协议基础:分层模型、事务层、数据链路层、物理层

聊聊PCIe这个“三层汉堡”

做Protocol Analyzer抓包分析,逃不开PCIe协议栈。

我个人习惯,是把PCIe协议栈比作一个高效的快递系统。从上到下,一共三层:事务层、数据链路层、物理层。每层干各层的活,分工明确。你想想看,这样分层有个好处:某一层出了问题,不会把整个系统拖垮。

一个数据包从发送端到接收端, 流程是这样的:先由事务层封装,交给数据链路层加校验和序列号,最后物理层把它变成比特流发出去。接收端反过来,层层剥离。嗯,这就是分层通信的精髓——每一层只和相邻的层打交道。

我的小习惯: 看Packet Analyzer日志时,先看物理层的训练状态,再看数据链路层的ACK/NAK,最后才分析事务层的TLP。按这个顺序排查问题,能省一半时间。

我在项目中遇到过好几次,明明是链路层有CRC错误,结果大家围在一起争论TLP格式对不对。查了半天才发现是物理层的信号完整性问题。所以,你看,理解这个分层模型,不仅仅是为了考试,更是为了实战中快速定位问题。

PCIe协议栈分层模型与数据封装流程 PCIe协议栈 – 分层模型与数据封装 事务层(Transaction Layer) 生成 TLP,处理内存/IO/配置请求 数据链路层(Data Link Layer) 添加序列号、LCRC,处理ACK/NAK重传 物理层(Physical Layer) 8B/10B或128B/130B编码,串行收发 数据 流 向 发送 端 TLP 接口 DLLP

事务层:TLP 是主角

事务层是离软件最近的一层。说白了,它负责把软件发起的读写请求,打包成一种标准格式——TLP(Transaction Layer Packet)。

TLP 的核心: 包含包头(Header)、数据负载(Payload,可选)和可选的摘要(Digest)。Header 里藏着事务类型、地址、长度、标签等关键字段。

常见的 TLP 类型有哪些?

  • Memory Read/Write: 最常见,读写内存空间。我抓包分析ASPM时,一半以上的流量都是这个。
  • IO Read/Write: 读写IO空间,老设备还在用,新平台逐渐不玩了。
  • Configuration Read/Write: 读配置空间,像枚举设备、设置BAR地址,都靠它。
  • Message: 中断通知(MSI/MSI-X)、错误报告、电源管理事件等。ASPM的L1/ L2状态切换,就靠Message通信。

我举个例子。假设CPU要读显卡的BAR0寄存器。事务层会生成一个Memory Read TLP,带上目标地址、请求长度、一个唯一的Tag。显卡收到后回复Completion with Data TLP。整个请求-完成过程,在抓包文件里看得清清楚楚。

我曾经踩过的坑: 在分析CXL.cache协议时,没注意TLP的Processing Hint位,导致把Cacheable和Non-Cacheable请求搞混了。后面查出来是TLP包头里的Tn属性没解析对。TLP一个字节都不能放过。

数据链路层:可靠的搬运工

数据链路层在事务层下面。它的任务很明确:保证TLP从发送端完整、有序地传到接收端。如果出错,就重传。

每个TLP从事务层下来,数据链路层会给它加上两样东西:

  • 序列号(Sequence Number): 初始值是0,每发一个TLP加1。接收端靠它检测丢包和乱序。
  • LCRC(Link CRC): 32位冗余校验码,覆盖整个TLP(包括包头和Payload)。接收端算一遍,不一致就扔NAK。

ACK/NAK是怎么工作的?

  1. 发送端发TLP(带Seq Num和LCRC),并保留副本在重传缓冲区。
  2. 接收端收到后,校验LCRC。正确,发ACK(应答序列号)。错误,发NAK(请求重传序列号)。
  3. 发送端收到NAK或超时未收到ACK,立即重传。

数据链路层还有一个核心东西——DLLP(Data Link Layer Packet)。它不是传递数据的,而是用于管理链路的:ACK/NAK、电源管理状态切换、流控信息更新等。抓包时,DLLP同样会被记录。

分析抓包的经验之谈: 如果你看到大量重复的TLP,那数据链路层可能在疯狂重传。检查LCRC错误率和接收端缓冲区是否满了。我有个案例,PCIe Gen3的信号抖动过大,导致LCRC错误率飙升到0.1%,系统吞吐直接腰斩。

物理层:比特的舞台

物理层是最底层的。它把数据链路层下来的字节,变成电信号或光信号,在PCIe通道上飞。

物理层的主要工作:

  • 编码/解码: Gen1/Gen2用8B/10B编码,每10位传递8位数据,多了20%的开销。Gen3/Gen4/Gen5改用128B/130B编码,效率更高。
  • 串行化/解串行化: 把并行数据转成串行,在单根差分线上发送。一根线传完,另一根线收,全双工。
  • 链路训练与状态管理(LTSSM): 物理层的状态机。上电、复位、降功耗、唤醒,全是LTSSM在管。

LTSSM状态机有几个关键状态,和你抓ASPM时序强相关:

LTSSM 状态 说明 ASPM 相关性
L0 正常全速运行,数据传输中 ASPM的L0s和L1都是从L0进入的
L0s 轻量级省电,恢复快(几纳秒到微秒) 由物理层自主进入,不需要软件参与
L1 深度省电,恢复慢(几微秒到几十微秒) 必须由事务层/软件协商,ASPM L1是重点分析对象
L2 几乎断电,主电源关闭,只留漏电电流 通常只在系统休眠或关机时进入

为什么理解物理层对ASPM很重要? 因为ASPM的省电效果和退出延迟,最终都体现在物理层的状态切换上。你抓包看到的PHY电气状态变化(如电气空闲 Electrical Idle),就是物理层在L0和L1之间跳来跳去。

总结一句: 整个PCIe协议栈,从上到下,事务层管内容,数据链路层管可靠性,物理层管传输。三层配合,才能实现高效、可靠的高速互联。而ASPM,是这三层协作的典型场景——上层决定何时省电,中层保证不丢数据,底层实际执行切换。

我习惯在Protocol Analyzer里同时开这三层的日志。事务层看TLP类型,数据链路层看ACK/NAK,物理层看LTSSM状态。三张图一对照,ASPM的时序行为就无所遁形了。嗯,这个习惯帮我解决了不止一个疑难杂症。