PCIE training

时间:2023-03-09 08:53:14
PCIE training
在PCIe链路可以正常工作之前,需要对PCIe链路进行链路训练,在这个过程中,就会用LTSSM状态机。LTSSM全称是Link Training and Status State Machine。这个状态机在哪里呢?它就在PCIe总线的物理层之中。
 PCIE training
LTSSM状态机涵盖了11个状态,包括Detect, Polling, Configuration, Recovery, L0, L0s, L1, L2, Hot Reset, Loopback, Disable。这11个状态之间转换的逻辑,如下图,
PCIE training
这11个状态大致可以分为4大类:
(1) PCIe链路训练相关。正常的PCIe链路训练状态转换流程依次是,Detect->Polling->Configuration->L0. L0是PCIe链路可以正常工作的电源状态。
(2) PCIe链路重新训练相关。这个状态也称为Recovery。Recovery是一个非常重要的链路状态,进入这个状态的因素也很多,比如电源状态的变化,PCIe链路速率的变化等。
(3) 电源状态相关。PCIe总线的电源状态主要有两部分的内容。
 一是基于软件控制的PCI-PM电源管理机制,是系统软件通过修改寄存器中的电源管理字段,使PCIe设备进入D状态:D0,D1,D2,D3.
 
 
 二是基于硬件控制的ASPM(=Active State Power Management)电源管理机制,是基于硬件自主控制的链路电源管理机制,只有在PCIe设备处于D0状态是才可以启动ASPM机制,另外,与ASPM有关的链路状态有L0s,L1(包括L1.1和L1.2).
 
(4)其他相关。比如Hot Reset, Link Disable, Loopback等。
我们接下来对这11个状态分别作一个简单的介绍。
Detect
这是物理层的初始状态,仅在Gen1 2.5 GT/s速率下使用,或是从数据链路层转换而来,或是在reset之后,或者从其他状态(Disable, Polling, Configuration,Recovery等)转换。总之,Detect状态是PCIe链路训练的开端。此外,Detect,顾名思义,需要实现检测工作。因为在这个状态时,发送端TX需要检测接收端RX是否存在且可以正常工作,如果检测正常,才能进入其他状态。Detect状态主要包含了两个子状态:Detect.Quiet和Detect.Active.
(1)从其他状态或者Reset之后,物理层从Electrical Idle开始,此时,处于Detect.Quiet;
(2)当超过12ms或者所有Lane均退出Electrical Idle时,则从Dectect.Quiet转换进入Detect.Active。在这个状态就会开启检测RX工作。
 PCIE training
判断RX是否存在的逻辑比较简单,就是通过一个“Detect logic”电路比较RC时间常数的大小。
(1) 当RX不存在时,RC时间常数较小。
 PCIE training
(2) 当RX存在时,RC时间常数较大。
PCIE training

Polling

这个状态的目的是"对暗号",实现无障碍沟通。进入这个状态后,TX和RX之间通过发送TS1、TS2 OS序列来确定Bit Lock, Symbol Lock以及解决Lane极性反转的问题。
Bit Lock: 在Bit传输过程中,RX PLL锁定TX Clock频率,这个过程称为RX实现"Bit Lock"。
Symbol Lock: RX端串并转化器知道如何区别一个有效的10-bit Symbol,这个过程称为“Symbol Lock”. 这里用到的是COM控制符。
Polling状态主要包含了三个子状态:Polling.Active, Polling.Configuration, Polling.Compliance.
 PCIE training
(1) 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(1024*16*4ns).
(2) Polling.Configuration: 当发送端TX发送完至少1024个TS1并且接收端RX连续收到8个TS1或者TS2,此时TS1和TS2中的Link/Lane区域由PAD填充, 那么,链路进入Polling.Configuration状态。处于此状态,发送端停止发送TS1序列,改为发送TS2序列,此时Link/Lane区域仍然由PAD填充,这个过程也会完成极性反转的问题,为进入下一个状态作准备。
(3) Polling.Compliance: 这个状态主要是通过发送不同的Pattern来测试发送端以及设备连接是否符合Spec要求。
Configuration
这个状态工作内容很简单,就是通过发送TS1、TS2来确定Link/Lane number. 如下图,Configuration包含了6个子状态:Configuration.LinkWidth.Start,Configuration.LinkWidth.Accpet,Configuration.Lanenum.Wait,Configuration.Lanenum.Accpet,Configuration.Complete, Configuration.Idle.
 PCIE training
由于Configuration状态下,发送端和接收端已经确认可以正常通信,所以,我们结合实例来看一下Downstream和Upstream的状态转换过程。
(1) Link Number Negotiation
Downstream在TS1中设定Link number, 此时Lane number=PAD,并发送给Upstream.
 PCIE training
而Upstream回的第一个TS1中,Link num仍然是PAD。此时,Upstream也处于Configuration.LinkWidth.Start状态。
 PCIE training
之后Upstream回的TS1中Link number则是设定值,此时, Upstream率先进入Configuration.LinkWidth.Accept状态。
 PCIE training
到这里,Link Number Negotiation就完成了。
(2) Lane Number Negotiation
当Downstream看到Upstream返回的TS1中Link number已经是设定值,那么就认为Link num已经协商成功,然后就开始准备设定Lane number,此时Downstream链路也接着进入Configuration.LinkWidth.Accept状态. 由于在录这个Trace时有过滤重复的TS序列,所以,我们看到一个TS1序列对应了三个状态:Configuration.LinkWidth.Accept,Configuration.LaneNum.Wait,Configuration.LaneNum.Accept. 这个三个状态发送的TS1序列一样,Link number和Lane number都已设定。
 PCIE training
当Upstream收到Downstream设定Lane number的TS序列之后,也很快进入了Configuration.LaneNum.Accept状态。
 PCIE training
与Lane number相关的三个状态之间相互转换逻辑如下:Downstream Vs Upstream.
 PCIE training
PCIE training
到这里,双方Lane number协议就完成了。
(3) Confirm Lane/Link Number
最后一步,过程就很简单了,双方通过发送TS2序列,对之前设定的Link/Lane number进行确认,这个过程,LTSSM处于Configuration.Complete. 确认没有问题之后,就准备进入下一个状态。
 PCIE training
L0
当进入这个状态时,PCIe链路就可以愉快的开始正常工作了。这个状态可以传输TLP,DLLP等报文。
Recovery
当PCIe链路需要重新训练时,进入Recovery状态。主要有以下几种情况:
(1) PCIe链路信号发现error,需要调整Bit Lock和Symbol Lock;
(2) 从L0s或者L1低功耗电源状态退出;
(3) Speed Change。因为第一次进入L0状态时,速率是2.5GT/s. 当需要进行速率调整5.0GT/s或者8.0GT/s时,需要进入Recovery状态进行Speed Change. 这个阶段,Bit Lock、Symbol Lock等都需要重新获取;
(4) 需要重新调整PCIe链路的Width;
(5) 软件触发retrain操作;
(6) 仅在Gen3和Gen4,需要重新进行Equalization。
Recovery子状态转换逻辑如下图:
 PCIE training
我们结合一个上电过程中Gen1提速至Gen3的时序来解读一下Recovery状态的转换,如下图:

PCIE training

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链路就可以回到正常工作状态。
L0s/L1/L2
这三个状态,主要是低功耗电源管理状态,在这里不再展开了,具体可以参考Spec.
Hot Reset
当某个PCIe设备发生错误时,我们有时候需要通过软件的方式对设备进行复位,这个方式就是Hot Reset。可以通过设置Bridge Control寄存器中的Secondary Bus Reset来触发Hot Reset.
 PCIE training
Hot Reset的指令是在TS1序列中体现,如下图,
 PCIE training
Hot Reset触发之后,LTSSM会进入Recovery和Hot Reset状态,之后会到Detect状态,PCIe链路开始重新训练。
 PCIE training
Disabled
用户可以通过设置修改Link Control寄存器,让PCIe链路出于Disabled状态。
 PCIE training
另外,如果我们把设备移除之后,同样也进入Disabled状态。
当退出Disabled状态后,LTSSM回到Dectect,PCIe链路重新训练。
 PCIE training
Loopback
这个状态仅用于debug测试,一般情况不会遇到,在这里不再展开,有兴趣的话可以参考PCIe Spec