2. PCIe分层架构:事务层、数据链路层、物理层的职责与交互
各位同学,咱们今天聊聊PCIe的分层架构。说实话,我刚入行那会儿,总觉得这三层架构挺唬人的。后来做项目多了才发现,搞懂它,你就能看懂PCIe一半的协议了。
PCIe的分层模型,说白了就是三个兄弟各司其职。我习惯这么记:事务层管“说什么”,数据链路层管“怎么说才靠谱”,物理层管“怎么传过去”。咱们一层一层拆开看。
2.1 事务层(Transaction Layer)—— 应用的“翻译官”
事务层是离软件最近的一层。它的核心任务,就是把上层发来的读写请求,打包成PCIe能认的“事务层包”(TLP)。
你想想看,CPU要读一个外设的寄存器,它不会直接说“我要读地址0x1000”。事务层会把它翻译成一个Memory Read TLP,带上地址、长度、标签等信息,然后往下扔。
事务层主要干三件事:
- TLP的组装与解析:把请求变成包,或者把包还原成请求
- 事务排序与管理:保证多个请求不乱套,该先完成的先完成
- 流量分类(VC):给不同业务分优先级,比如把中断请求插到普通数据前面
我记得有一次调试一个NVMe SSD,死活读不到数据。抓了PCIe的trace一看,TLP的地址字段居然多了一个字节偏移。嗯,就是事务层打包时的一个小bug。从那以后,我每次看TLP都会盯着地址字段多看两眼。
2.2 数据链路层(Data Link Layer)—— 可靠的“快递员”
数据链路层,我管它叫“靠谱担当”。事务层把TLP丢给它,它得保证这个包能完整、无错地送到对端。
怎么做呢?它给每个TLP加了一个序列号(Sequence Number)和CRC校验(LCRC)。然后它自己还会生成一种叫DLLP(数据链路层包)的控制包,用来做应答和流控。
一个小技巧: 当你看到链路训练成功了但数据传输老出错,十有八九是数据链路层的CRC校验出了问题。我习惯先看LCRC错误计数,这个寄存器在PCIe配置空间里,很好找。
数据链路层还有一个重要机制——重传(Replay)。如果对端说“我没收到”或者“校验错了”,它就会重新发一次。我曾经遇到过一个案例,因为信号质量差,重传次数飙升,性能直接腰斩。排查到最后,发现是PCB走线阻抗不匹配。
| 数据链路层核心功能 | 说明 |
|---|---|
| TLP序列化与校验 | 给TLP加序列号和CRC,保证顺序和完整性 |
| DLLP管理 | 处理链路层的控制信息,如流控、确认 |
| 重传机制 | 检测到错误后自动重发,对上层透明 |
| 链路状态跟踪 | 监控链路是否正常,配合物理层做状态切换 |
2.3 物理层(Physical Layer)—— 信号的“搬运工”
物理层是最底层的,它直接跟铜线打交道。它的任务就是把数据链路层送来的包,变成电信号,从差分对上传出去。
物理层又分两个子层:逻辑子层和电气子层。逻辑子层负责编解码(比如8b/10b或128b/130b编码),电气子层负责驱动差分信号。
这里有个关键点——链路训练(Link Training)。物理层在初始化时,会通过LTSSM状态机,一步步协商速率、宽度、极性等参数。我见过不少工程师,链路训练失败就慌了,其实大部分问题都出在物理层:比如时钟不准、信号衰减太大、或者REFCLK没对上。
避坑指南: 我曾经遇到过一块板子,Gen3死活训练不上,但Gen2就正常。查了半天,发现是TX端的去加重(De-emphasis)设置不对。物理层的参数配置,一定要跟对端芯片的datasheet对一遍,别想当然。
2.4 三层如何交互?—— 一个TLP的“奇幻漂流”
咱们用一个实际的读请求,看看这三层是怎么配合的。
- 事务层:收到CPU的读请求,生成一个Memory Read TLP。包里有地址、长度、请求者ID等。然后把它交给数据链路层。
- 数据链路层:拿到TLP后,给它加上序列号和CRC。同时,它还会检查流控信用,确保对端有足够的缓冲区接收。然后封装成一个数据链路层帧,交给物理层。
- 物理层:把帧进行编码(比如128b/130b),加上帧起始和结束标志,然后通过差分对串行发送出去。
接收端反过来:物理层解码,数据链路层校验CRC和序列号,事务层解析TLP并交给上层。
整个过程,对上层软件是完全透明的。你写一个MMIO读操作,根本不用操心底层是怎么传的。这就是分层架构的魅力——各层只管自己的事,接口清晰,互不干扰。
2.5 知识体系总览
下面这张图,是我自己画的一个分层架构交互图。你可以看到TLP、DLLP、以及物理层的Ordered Set是怎么流转的。
这张图我建议你存下来。每次调试PCIe问题,先定位是哪一层出的问题,再往下深挖。比如TLP格式错了,那就是事务层的事;CRC报错,查数据链路层;链路训练失败,直奔物理层。
我的经验: 刚接触PCIe的工程师,容易一上来就扎进物理层的细节里。其实我建议你先搞懂事务层,因为大部分驱动开发和调试都在这一层。物理层的问题,通常硬件工程师会更擅长。
好了,这一章的内容就到这儿。分层架构是PCIe的骨架,后面咱们讲链路训练、讲错误处理,都离不开这三层的概念。你先把这张图刻在脑子里,后面会越学越顺。
公众号:蓝海资料掘金营,微信deep3321