第2章:PCIe体系结构简介

聊LTSSM之前,我建议大家先把PCIe的整体架构摸清楚。你想想看,链路训练说白了就是让两边的设备能对上话,但你连对话的双方是谁、中间有什么角色、消息怎么传递都不清楚,那学状态机就只能死记硬背了。

记得我最早接触PCIe时,上来就啃LTSSM的12个状态,结果越看越晕。后来一位老前辈跟我说:“你先别管状态机,先把PCIe这棵树长什么样画出来。”从那以后,我才算真正入了门。

2.1 从并行到串行:PCIe的诞生

早期的PCI总线是并行架构,32位或64位数据线一起走。听起来很美好对吧?但实际上,并行信号有个大麻烦——信号偏移(Skew)。

每条线的传播延迟稍微不一样,频率一高,数据就乱了。PCI/PCI-X最高跑到533 MHz,再往上就上不去了。我在一个老项目中修过PCI-X的时序问题,那叫一个痛苦——换了几版PCB都没搞定,最后只能降频。

PCIe换了个思路:串行差分信号。一对差分线(TxP/TxN或RxP/RxN)就是一个Lane,数据一位一位传。频率可以拉得非常高,而且没有Skew问题。PCIe 1.0单Lane就到了2.5 GT/s,比PCI-X快多了。

2.2 PCIe系统拓扑结构

一个典型的PCIe系统长什么样?我用一张图给你讲清楚。

PCIe体系结构框架图 PCIe 体系结构概览 Root Complex (RC) CPU / 主存 交换器 (Switch) 端点 EP 1 端点 EP 2 端点 EP 3 PCIe-PCI 桥 传统 PCI 设备 注意:实际系统中交换器可以级联,端点数量远超上图;RC内部也集成了多个虚拟PCI-PCI桥。

你看这张图,从上到下分成了几个层次:

  • Root Complex (RC):CPU和内存的接口,是整个PCIe层次结构的根。我习惯把它想象成“交通指挥中心”。
  • 交换器 (Switch):负责把RC的一个端口扩展成多个端口。它由多个虚拟PCI-PCI桥组成,数据包在这里做转发。
  • 端点 (Endpoint, EP):实际的功能设备,比如网卡、GPU、NVMe SSD。EP只消费或产生事务,不转发。
  • 桥 (Bridge):用来连接PCIe和传统PCI总线,做协议转换。

要点提醒:LTSSM只存在于物理层(PHY),但它管理的是整个链路的建立和维护。你看到上图每两个设备之间的那条线,就是LTSSM要管的事。

2.3 层次化架构:三层分工

PCIe使用层次化架构,从顶到底分为三层。每层只跟相邻层打交道,职责非常清晰。

层级 核心职责 关键数据单元
事务层 (Transaction Layer) 生成和接收事务层包(TLP),管理事务排序、流量控制、虚拟通道 TLP(Transaction Layer Packet)
数据链路层 (Data Link Layer) 提供可靠传输,包括CRC校验、ACK/NAK重传、链路管理 DLLP(Data Link Layer Packet)
物理层 (Physical Layer) 串并转换、比特传输、链路初始化与训练(LTSSM就在这里!) PLP(Physical Layer Packet)、有序集合(Ordered Sets)

三层各有各的包格式,但它们之间不是孤立的。物理层发的有序集合(比如TS1/TS2),直接驱动LTSSM的状态跳转。

2.4 深入各层:看看它们干了什么

2.4.1 事务层——PCIe通信的“内容”

事务层负责跟软件打交道。你的驱动程序要读取设备寄存器,或者把内存中的数据发到网卡,这些请求都由事务层打包成TLP。

TLP有四种主要类型:Memory、IO、Configuration、Message。我建议你重点记住Memory读写,因为日常开发中90%的事务都是它。

避坑提示:我曾经遇到一个GPU驱动挂死的问题。调了一周,最后发现是TLP中的Length字段填错了——驱动代码里把字节数写成了DWord数。事务层要的数据跟物理层实际传输的数据不匹配,链路直接挂起。

2.4.2 数据链路层——可靠的“搬运工”

数据链路层在TLP外面套了一个帧头,加上一个32位的CRC(LCRC),然后发给物理层。它还会等接收端回复ACK或NAK。

  • 收到ACK:TLP发送成功,从重发缓冲区里清除。
  • 收到NAK:TLP发送失败,必须重新发送。
  • 超时没收到回复:也重新发送。

这个机制叫ACK/NAK重传协议。说白了,就是物理层只管发,数据链路层要确认对方真的收到了。我手头有个项目,刚开始测试时偶尔出现丢包,追到最后发现是接收端LCRC校验逻辑里的一个时序问题。

2.4.3 物理层——LTSSM的大本营

物理层分为两个子层:逻辑子层和电气子层。

  • 逻辑子层:包含LTSSM、加扰/解扰、8b/10b编码(PCIe 1.0/2.0)或128b/130b编码(PCIe 3.0+)、弹性缓冲区。
  • 电气子层:包含SerDes(串化器/解串器)、差分驱动器和接收器、PLL时钟恢复电路。

LTSSM是逻辑子层的核心,它管理着链路从复位到正常工作的每一个步骤。

一个小技巧:当你用协议分析仪抓取PCIe流量时,物理层的有序集合(如TS1/TS2、SKP、FTS)会在逻辑子层被剥离,所以你看到的抓包数据直接就是TLP。但如果链路训练失败了,你只能看到反复出现的TS1/TS2,不会有任何TLP。——记住这个现象,实际抓debug时很有用。

2.5 一个重点概念:Lane与链路宽度

PCIe的Lane是一对差分发送和一对差分接收构成的双向通道。每个Lane是独立的,但多个Lane可以绑在一起,形成一个链路(Link)。

链路宽度 x1 x2 x4 x8 x16
Lane数 1 2 4 8 16
常见用途 网卡、Wi-Fi模块 SSD(少数) NVMe SSD、RAID卡 显卡(中端) 显卡(旗舰)

LTSSM在训练时,会做一件关键的事——宽度协商。两端设备先各自声明“我能支持x16”,然后通过交换训练序列确定最终的宽度。如果一个x16的显卡插到x8的插槽上,LTSSM最终就会协商成x8。

经验之谈:我调试过一块主板,x16插槽只能跑x1。用示波器量着量着发现,有一对差分线的过孔处阻抗不连续。LTSSM在宽度协商时会检测到某些Lane的电气质量不达标,自动降级。硬件工程师看到这种问题,千万不要直接怀疑LTSSM的软件实现——先查信号完整性。

哦对了,还有一点要注意:LTSSM对每个Lane是独立训练的,但链路作为一个整体进入某状态。举个例子,在Polling状态,每个Lane各自检测接收器是否工作,但所有Lane都完成后,整个链路才一起进入Configuration。

好了,PCIe体系结构的骨架已经有了。下一层要往里边填充的,就是LTSSM这个真正驱动链路“跑起来”的状态机。别着急,咱们一章一章来拆。