PCIe鏈路層訓練過程

驅動小白發表於2020-10-25

PCIe link 協議:

本部分主要目的是host在識別列舉PCIe裝置之前,裝置與主機在PCIe鏈路上都發生了什麼事情,,主要流程為上電後兩側根據PCIe匯流排協議進入LTSSM流程,主要分為以下幾個方面去介紹:

1,什麼是 symbol lock和bit lock

PCIe匯流排的的接收端鏈路上沒有時鐘,因此獲取時鐘的辦法是通過接收到傳送端發過來的報文資訊(帶有時鐘資訊)來獲取時鐘資訊,將此過程稱之為bit lock,同理symbol lock表示PCIe鏈路上獲取開始訓練的標記符COM字元的過程。

2,LTSSM流程介紹

PCIe匯流排在硬體訓練的過程中主要使用這幾個序列:TS1、TS2,這兩個序列主要作用是在LTSSM狀態機之間來回跳轉。FTS序列協助PCIe的鏈路獲取bit lock和symbol lock。SKIP序列負責處理各個lane上面的skew,使其保持一致,具體技術細節可參考elastic buffer技術。整個訓練過程pcie鏈路使用預設gen1速率進行傳輸,LTSSM狀態機精簡流程如下:

   detect <------->polling------config------L0狀態(主機可以列舉到device側裝置)
![LTSSM流程圖](https://img-blog.csdnimg.cn/20201025140128398.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI0NzIyODkz,size_16,color_FFFFFF,t_70#pic_center)

2.1 detect狀態

此部分主要的作用是用來確認PCIe鏈路上可以正常工作的lane資源

 detect.quiet<----->detect.active------>polling

首先上電後PCIe兩端裝置同時進入detect.quiet狀態,首先host先將linkup 以及upconfig capblity 置0,同時PCIe鏈路處於靜默狀態,當其中一個或多個lane退出靜默狀態,或者經過12ms後,進入detect active狀態。此時host向對端“未經過配置的lane”傳送receive Detect 序列(通過DC共模電壓來識別對方是否存在,對應的lane是否正常工作)。若沒有一個存在則退回Detect.quiet狀態重新進行detect流程。否則經過12ms後再次傳送receive Detect序列來確認與上次正常工作的lane數目是否一致。若不一致則退回Detect.quiet狀態重新進行detect流程。若一致則進入下一個狀態polling狀態

2.2 polling狀態

該狀態主要功能為獲取bit/symbol lock 以及同步鏈路兩端使其進入下一個config狀態。 有基本有一下三個子狀態機組成,其實還有一個polling.compliance狀態機負責對pcie鏈路進行檢測是否存在故障

polling.active----->polling.config------>exit to config狀態

進入polling.active 狀態後首先PCIe兩端的TX會向對端傳送1024個TS1序列,用於獲取bit/symbol lock,由於pcie兩端裝置進入polling.active狀態的時機可能不同步因此只要滿足一下幾種情況就能進入polling.config狀態

1,同時RX會接收8個TS1序列(對端通過loopback傳過來),或者TS2序列(對端先進入polling.config狀態,從而生成TS2序列),
2,如果沒有接收到則經過20ms判斷RX是否接收8個TS1序列,或者從進入polling.active狀態時有至少一個lane是可以正常工作的。

滿足以上條件則進入polling.config狀態。否則進入polling.compliance狀態對鏈路進行修復,修復成功重新進入polling.active,修復不成功退回detect狀態。
進入polling.active狀態後,首先設定link control 2暫存器的transmit margin為0, 其次向對端傳送8個TS2序列表示已經成功進入polling.config狀態。最後要收到8個TS2序列(一共需要收到16個TS2序列),若在48ms之內完成以上操作則進入config狀態,否則退回到detect狀態重新訓練。

2.3 config狀態

該功能是pcie link 訓練中最重要的狀態,主要的作用為完成pcie鏈路的主要配置工作主要包括,link number 和 lane number,以及對各個lane通過設定FTS來進行deskew。然後進入L0狀態使PCIe鏈路正常工作 主要有以下幾個子狀態組成分別為:

cfg.linkwidth.start----->   cfg.linkwidth.accept----->  cfg.linknum.start <----->cfg.linknum.accept---->cfg.complete---->cfg.idle----->L0

**1、**cfg.linkwidth.start和cfg.linkwidth.accept 主要的作用是確定linknum(通過互相傳送TS1來確定PCIe下游埠的linknum拓撲結構)。
**2、**cfg.linknum.start和cfg.linknum.accept 主要的作用是確定lanenum 方法同上。
**3,**cfg.complete 狀態主要是確定完link/lane num後,再通過互發TS2序列來同步pcie鏈路兩端使其同步進入cfg.idle狀態 另一個作用是通過TS2序列來確定設定多少個FTS,來消除lane之間的skew。
**4,**cfg.idle 該狀態主要為pcie兩端會向對端傳送16個idle序列,同時接受端收到16個idle序列後,將自己的link_up暫存器設定為1,同時pcie鏈路的狀態有DL-inactive轉變為DL_init,進入L0狀態,PCIe鏈路可以正常工作。

2.4 L0狀態

該狀態為PCIe鏈路正常工作的狀態,host可以訪問device的配置空間以及與之進行資料互動。

2.5 recovery狀態

只有出現以下幾個情況,L0才會進入recovery狀態:
1、PCIe需要更改鏈路速率
pcie裝置中存在兩個狀態位,dircted_speed_change == 1表示pcie裝置希望更改傳輸速率,changed_speed_recovery1,表示pcie鏈路更改速率完成。軟體可以將dircted_speed_change == 1同時 changed_speed_recovery0 觸發裝置進入recovery狀態,注意pcie 鏈路兩邊需要同時進行該操作。
2、PCIe需要更改鏈路寬度
3、已經配置完成的lane又重新受到TS1或者TS2序列
4,、發現對端進入idle狀態(只有當對端進入idle是沒有傳送EIO序列,認為pcie鏈路出了故障

該狀態比較複雜,主要是L0,可以進入該狀態, L0s, L1等低功耗狀態也通過此狀態恢復到L0狀態(L0s可以直接回到L0狀態,只有在切回L0狀態時不能重新獲取bit/symbol lock時才進過recovery狀態), 該狀態一共分為以下幾個子狀態:recovery.rcvlock、recovery.speed、recovery.rcvcfg、recovery.idle

1,recovery.rcvlock:該狀態重新獲取bit/symbol lock 並處理lane之間的skew。
比如,switch 與 EP兩端都處於L0 狀態,EP想改變速率,
**1)**則軟體將dircted_speed_change 置1,同時將changed_speed_recovery 置0,進入recovery.rcvlock狀態,同時向switch傳送TS1 序列(該序列中的speed change 位為1),
**2)**當switch接收到TS1時直接進入recovery.rcvlock狀態並向對端傳送若干TS1序列(此時還沒有檢查接收TS1的speed change狀態位,所以傳送的TS1序列,speed change 仍然為0),當switch收到8個連續的TS1(speed change 位為1),將改變switch本地的dircted_speed_change 置1,此時再向EP傳送若干TS1序列(speed change 為1)。
**3)**當EP裝置收到8個 TS1序列中speed change 狀態和EP本地dircted_speed_change狀態一樣,則進入recovery.rcvcfg狀態。並向switch傳送TS2序列(其speed change 也為1).
**4)**當switch 接收到8個TS2序列中speed change 狀態和switch本地dircted_speed_change狀態一樣。則進入recovery.rcvcfg狀態。同時向EP傳送TS2 序列。
2,recovery.rcvcfg switch和ep 根據TS2序列中的speed change 狀態位來決定進入下個狀態機:
**1)**當TS2序列中speed change狀態位1 跳轉到recovery.rcvspeed狀態,同時向對端傳送32個TS2序列
**2)**當TS2序列中speed change狀態位0 跳轉到recovery.rcvidle狀態,同時向對端傳送16個TS2序列
3,recovery.rcvspeed 狀態,進入該狀態後根據TS2序列中的速率,向對方發出不同的EIO序列,同時兩端進入electrical idle狀態(TX和RX都進入idle狀態)。 pcie兩端都進入electrical idle 狀態後,需要判斷pcie鏈路兩端是否成功完成速率協商,等待800ns ~ 1ms 後判端 successful_speed_negotiation是否為1,然後將本地dircted_speed_change 置位0,跳轉到recovery.rcvlock用新的速率重新獲取bit/symbol lock 並處理lane之間的skew。若不能獲得symbol/bit lock 還得退回recovery.rcvspeed 進行降速,再次進入recovery.rcvlock狀態獲取bit/symbol lock 並處理lane之間的skew。
4,recovery.rcvsidle 鏈路兩端裝置TX向對端傳送16個idle序列,並且RX端接受到8個idle序列,則該裝置進入L0狀態。

2.6 LTSSM其他狀態

L0s 、L1、L2、disabled、hot reset、loopback狀態,

相關文章