针对PCIe link training做了分步解析,本文介绍原理,下一篇介绍波形分析,链接如下:
PCIe链路训练link training–举例波形分析
PCIe总线中的链路初始化与训练(Link Initialization & Training)是一种完全由硬件实现的功能,处于PCIe体系结构中的物理层。整个过程由链路训练状态机(Link Training and Status State Machine,LTSSM)自动完成,也就说基本没有数据链路层和事务层啥事。
在系统复位后,会自动进行链路训练,以达成以下目标:位锁定(Bit Lock)、字符锁定(Symbol Lock,Gen1 & Gen2 Only)、块锁定(Block Lock,Gen3 Only)、确定链路宽度(Link Width)、通道位置翻转(Lane Reversal)、信号极性翻转(Polarity Inversion)、确定链路的数据率(Data Rate)和通道对齐(Lane-to-Lane De-skew)等功能。
前面的文章中提到过,PCIe总线采用了一种嵌入式时钟的机制,即发送端只向接收端发送数据信号,并不发送时钟信号(时钟信号隐藏在数据信号中)。接收端可以通过CDR(Clock and Data Recovery)逻辑将时钟从数据流中恢复出来,然后再用恢复出来的时钟对数据信号进行采样。当然,时钟恢复需要一定的时间,才能保证时钟信号与数据信号的相位对应关系符合要求。一旦CDR完成了时钟的恢复,我们就说PCIe总线完成了位锁定。
完成了位锁定之后,只是能够准确地识别出数据流中的0和1,还是不知道发送的内容是个啥。对于Gen1&Gen2来说,采用的8b/10b编码,即传输的数据是以10bit为一个字符。LTSSM可以引导物理层相关逻辑通过识别COM(K28.5)等控制字符来确定每个字符的开始与结束为止,即字符锁定。
由于PCIe允许将x1的PCIe卡插入x4、x8甚至是x16的PCIe插槽中。因此在链路训练与初始化过程中,相邻的两个PCIe设备需要相互通信来确定其支持的最大链路宽度。
注:实际上PCIe Spec还允许采用动态带宽的机制,即允许链路宽度和数据率动态调整,以实现降低功耗等功能。
有的时候两个PCIe设备的通道排列位置可能不太一致,PCIe Spec允许对默认的通道排列位置重新排列,如下图所示。但是,从大部分的PCIe设备(PCIe卡和插槽等)都是按照统一的标准实现的,一般不会出现这种情况,因此这一功能是可选的。
前面的文章中介绍过,PCIe收发的都是差分信号,有的时候Link两端的设备的对应信号的极性可能是相反的。因此,PCIe Spec允许在链路训练与初始化的时候,对其进行调整,如下图所示。和通道位置翻转(Lane Reversal)不一样的是,信号极性翻转(Polarity Inversion)并不是一个可选项,而是所有标准PCIe设备都应支持的。
系统刚复位的时候,链路训练和初始化都是基于2.5G T/s的速率的。如果Link两端的设备都支持更高的速率,则会自动进入Re-training状态,以重新切换速率。
注:PCIe Spec规定,高速率的PCIe设备必须能够向下兼容。即Gen2必须同时支持2.5G T/s和5G T/s。
PCIe链路完成字符锁定后,还需要进行通道对齐。因为有的通道的信号可能先到达,有的可能后到达。PCIe Spec规定PCIe链路应有能力对一定范围了的Lane-to-Lane Skew进行移除,使得各个Lane上的信号是同步的。关于通道对齐,会在后续的博文中详细地介绍。
PCIe进行链路训练时要发送一些特殊的字符序列,这些序列也被称为PLP(Physical Layer Packet)物理层数据包。这些字符序列主要有:
TS1和TS2有序集
为了简化说明,我们以gen1、gen2格式来描述。 它们由16个symbol组成。
LTSSM有11个状态(其中又有多个子状态),分别是Detect、Polling、Configuration、Recovery,L0、L0s、L1、L2(L3是可选的)、Hot Reset、Loopback和Disable状态。系统进行复位操作(Cold, Hot or Warm Reset)后,会自动进入Detect状态。
这11个状态又可以被分为以下五个类别:
链路训练状态(Link Training State);
重训练状态(Re-Training(Recovery) State);
软件驱动功耗管理状态(Software Driven Power Management State);
活动状态功耗管理状态(Active-State Power Management State,ASPM State);
其他状态(Other State);
Detect状态:当PCIe链路被复位或者数据链路层通过寄存器操作会是的LTSSM进入该状态,在这个状态中,PCIe设备会去检测自己Link的另一端是否存在其他PCIe设备。换句话说,就是检测有没有其他的PCIe设备与其相连接。如果有就进入到Polling状态的过程。
Polling状态:
在该状态中,PCIe设备会依次发送TS1序列和TS2序列以实现以下目标:
Polling.Active: 这是链路从Detect退出后进入的状态,在这个状态下,发送端需要在所有Lane至少发送1024个TS1序列,因为接收端需要通过接收到的TS1序列来实现Bit/Symbol Lock. 由于发送端和接收端不是同时退出Detect状态,所以,TS1序列交流可能不会同步。此时,链路出于Gen1(2.5GT/s), Symbol time=4ns(10b/2.5Gb/s), 发送1024个TS1序列(16 symbols)至少需要64us(1024164ns).
Polling.Configuration: 当发送端TX发送完至少1024个TS1并且接收端RX连续收到8个TS1或者TS2,此时TS1和TS2中的Link/Lane区域由PAD填充, 那么,链路进入Polling.Configuration状态。处于此状态,发送端停止发送TS1序列,改为发送TS2序列,此时Link/Lane区域仍然由PAD填充,这个过程也会完成极性反转的问题,为进入下一个状态作准备。
Polling.Compliance: 这个状态主要是通过发送不同的Pattern来测试发送端以及设备连接是否符合Spec要求。
在该状态中,PCIe设备会依次发送TS1和TS2, 用来确定下面的条目:
确定链路宽度(Link Width);
分配通道(Lane)号;
通道位置翻转(Lane Reversal),如果需要的话;
通道对齐(Lane-to-Lane De-skew)。
该状态是LTSSM状态机最重要的状态,值得注意的是PCIe链路在进行初始化时,链路两端统一使用2.5GT/s的数据传送率,直到进入到L0状态。如下图,Configuration包含了6个子状态:
Configuration.LinkWidth.Start,Configuration.LinkWidth.Accpet,Configuration.Lanenum.Wait,
Configuration.Lanenum.Accpet,Configuration.Complete, Configuration.Idle.
L0状态:它表示PCIe的链路进入正常工作状态,在这个状态下,PCIe链路可以正常的收发TLP、DLLP、PLP。 PCIe链路可以从该状态进入到Recovery 状态,以改变数据传送率。
当PCIe链路需要重新训练时,进入Recovery状态。主要有以下几种情况:
我们结合一个上电过程中Gen1提速至Gen3的时序来解读一下Recovery状态的转换,如下图:
a. Downstream率先进入Recovery.RcvrLock状态, 之后向Upstream持续发送TS1并且将speed_change bit设置为1;
b. Upstream端看到TS1进来之后,也跟着进入Recovery.RcvrLock状态,同时回传TS1序列,不过此时,speed_change bit仍为0. 当Upstream接收达到连续8个TS1且speed_change bit设置为1,这时,Upsteam回传的TS1、TS2中speed_change bit设置为1,并告诉Downstream建议工作速率,接着进入Recovery.RcvrCfg状态;
c. Downstream收到Upstream建议的速率反馈之后,也返回TS2序列,并发送EIOS序列,准备进入Electrical Idle. 此时,LTSSM处于Recovery.RcvrCfg状态;
d. 之后,Downstream和Upstream相继进入Electrical Idle, LTSSM处于Recovery.Speed状态;
e. 经过一段时间timeout(Spec要求至少800ns, 小编这个Trace中是~8us),Upstream发送EIEOS, 退出Electrical Idle, 尝试跑最高速率8GT/s;
f. 接着Downstream也退出Electrical Idle, 尝试跑试跑最高速率8GT/s;
g. 最后,双方开始进行EQ。EQ之后,PCIe链路就可以回到正常工作状态。
这是一种ASPM低功耗状态,退出到L0时延迟最短,设备可自动管理进出该状态,无需更高级软件的参与。
在总线空闲的时候可以进入该状态,且从该状态可以迅速地重新切换回L0状态。当在L0状态时,链路上出现EIOS时,则表明即将进入L0s状态。当在L0s状态时,链路上出现FTS时,链路会迅速地完成位锁定和符号锁定,并进入L0状态。
L0s发送器状态机如下图:
相对于L0s状态,L1状态下的功耗更低。进入L1状态需要链路两端的PCIe进行“沟通”,只有双方都“同意”进入该状态,链路才会进入该状态。一般有以下两种方式:
第一种是由ASPM引导,硬件自动完成的。发送端发现链路上长时间没有TLP或者DLLP时,便通过ASPM建议接收端进入L1状态。如果接收端“同意”了,则链路进入L1状态;如果接收端“不同意”,则链路进入L0s状态。
第二种是有软件引导的,软件发送一系列的命令让链路进入低功耗状态(D1,D2,or D3 Hot)。随后,链路的上端设备会通知下端设备进入L1状态,收到来自下端设备的应答后,链路进入L1状态。
L2状态下的链路功耗更低,因为其只保留了Vaux,关闭了链路的其他功能。此时,需要Beacon信号或者WAKE#边带信号来唤醒系统。其中Beacon信号是一种低频信号(30KHz~500MHz),其波形图如下图所示:
注:此外,还有一个L3状态,不过其实际上已经不属于LTSSM了。由于L3状态连Vaux都关闭了,一旦进入L3状态,实际上和直接关闭PCIe设备的电源没有什么太大的差别了。
Hot复位是由软件所触发的带内传送的复位, 如下图描述了Hot 复位状态的进入和退出。
也可以通过设置Bridge Control寄存器offset 3Eh中的Secondary Bus Reset来触发Hot Reset.
Hot Reset触发之后,LTSSM会进入Recovery和Hot Reset状态,之后会到Detect状态,PCIe链路开始重新训练。
状态中链路被禁止,此时发送端处于电气空闲状态(Electrical Idle State),而接收端处于低阻状态(Low Impedance State)。进入该状态的原因可能是链路连接不稳定,或者链路中的某个设备被移除,如PCIe卡从插槽中拔出。
用户可以通过设置修改Link Control寄存器,让PCIe链路出于Disabled状态。
当退出Disabled状态后,LTSSM回到Dectect,PCIe链路重新训练。
回环是一种测试和调试功能,并不用于正常运行中,将回环设备连接到设备的链路(处于回环状态中时,接受测试的设备是回环从设备),即可将链路和回环从设备置于回环状态,方法是发送已声明回环比特的TS1有序集,回环主设备作为内置测试引擎。
下图展示了链路功能寄存器Offset 0Ch:
最高链路速度(Maximum Link Speed)[3:0]:
该字段被硬连线为0001b, 表明其所支持的速度是第一代2.5Gbit/s
0001b Supported Link Speeds Vector field bit 0
0010b Supported Link Speeds Vector field bit 1
0011b Supported Link Speeds Vector field bit 2
0100b Supported Link Speeds Vector field bit 3
0101b Supported Link Speeds Vector field bit 4
0110b Supported Link Speeds Vector field bit 5
0111b Supported Link Speeds Vector field bit 6
最大链路宽度(Max Link Width)[9:4]:
该字段表明了PCI Express 链路的最大宽度。其值定义如下:
00 0000b:保留
00 0001b: x1
00 0010b: x2
00 0100b: x4
00 1000b: x8
00 1100b: x12
01 0000b: x16
10 0000b: x32
所有其他值均保留
该寄存器是硬连线的,或者在通过LTSSM的检测状态后由硬件自动更新,软件无法清楚或者写入各个bit。
下图为链路功能寄存器Offset 12h:
链路速度(Link Speed)[3:0]:
该字段为只读,表明了PCI Express 链路已协商的链路速度,在LTSSM的轮询状态期间更新该字段,当前唯一定义的编码是0001b 表明链路速度为2.5Gbit/s。
协商链路宽度(Negotiate Link Width)[9:4]:
该字段表明了链路宽度协商结果,可能的宽度有七种,所有其他编码保留,已定义的编码有:
00 0001b: x1
00 0010b: x2
00 0100b: x4
00 1000b: x8
00 1100b: x12
01 0000b: x16
10 0000b: x32
所有其他值均保留
链路定向错误[10]:
出现链路定向错误时由硬件设置该bit, 链路已进入L0(活动)状态时即表明链路定向成功。此时硬件清除该bit, 仅在上游设备中支持该比特,如根联合体或交换器下游端口。
链路训练(Link Training)[11]:
这个只读位表示物理层LTSSM在配置或恢复状态,或说1b已写入Retrain Link位,但Link训练尚未开始。当LTSSM退出Configuration/Recovery状态时,硬件将清除此位。此位不适用于端点、PCI Express到PCI/PCI- x桥接和上行交换机的接口,必须硬连线到0b。
链路控制寄存器Offset 10h , 如下图:
链路禁用(Link Disable)[4]:
设置为1,链路被禁用。写入该bit会导致设备发送16个声明有链路禁用bit的TS有序集。
重定向链路(Retrain Link):
该bit允许软件初始化链路重定向,这可用于错误恢复中,将其设置为1时, 在返回配置写入请求完成之前会使LTSSM进入恢复状态。
扩展同步(Extended Sync):
该bit用于在进入L0状态前,强制在L0s状态中发送4096个FTS(快速定向序列)有序集,然后在发送单个SKIP有序集,它还强制在进入恢复状态前发送1024个TS1有序集,该扩展同步允许外置工具监控链路时间,以便在链路进入L0或恢复状态并恢复正常的通信前实现比特和符号锁定。