2021年11月29日 星期一

原理PCI Express - LTSSM 狀態機推演 "Detect -> Polling -> Configuration -> L0"

在之前,我撰寫了一篇介紹PCIExpress: Link Training and Status State Machine(LTSSM)介紹有關LTSSM中各個state的介紹,接下來這篇文章會推演兩個端點之間的LTSSM是如何從Detect state演進到L0PCIe的優點就是point-to-point interconnects(點對點的連接),所以就算系統上多層PCIe bus所構成,每個component只要負責與他對面的component之間的link negotiation就可以了,大大的降低複雜程度。

■ 前言

PCIe spec當中有幾個名詞需要特別解釋一下,如Figure 1Upstream Component為上游的deviceDownstream Component為下游的device,而在Upstream Component下面所連接出去的port稱之為Downstream Port或者Downstream Lanes(簡稱DP)Downstream Component上面所連接出去的port稱之為Upstream Port或者Upstream Lanes(簡稱UP),所以在spec中提到的Downstream Port所指的是Upstream ComponentUpstream Port所指的是Downstream Component,在閱讀spec這點要特別注意。

Figure 1

■ Detect -> Polling -> Configuration -> L0推演

Downstream PortUpstream Port兩者的LTSSM狀態機是獨立的,所以有時候雙方並不是同一時間進入下一個state。接下來會使用類似時序圖的概念所做成的動畫來解釋LTSSM的演進。

=== 動畫1 ======


● Entry to Detect.Quiet
首先,如動畫1,雙方一開始link處於Electrical Idle的狀態,當雙方將要開始Link Training,雙方會離開Electrical Idle,直接進入Detect的substate Detect.Quiet,在Detect.Quiet state會以2.5 GT/s(Gen1)的速度作為初始速度,並且初始化所有registers,圖中的LinkUpdirected_speed_changeupconfigure_capableidle_to_rlock_transitioned可以視為Physical Layer內部的register(not visible to software)。

● Entry to Detect.Active
然後在離開Electrical Idle 12ms之後,雙方則會進入Detect.Active,並且開始Receiver Detection的程序,Receiver Detection的介紹請參考文章開頭所貼的文章,基本上就是偵測對方的存在。


=== 動畫2 ======


● Entry to Polling.Active
在偵測到對方的存在之後,雙方則會進入Polling.Active在Polling.Active state,會開始傳送TS1 Order Set(Training Sequence,詳細格式請參考文章開頭所附的文章),並且Link Number(Symbol 1)和Lane Number(Symbol 2)設為PAD,表示不帶任何數字,這裡表示為PAD/PAD。

● Entry to Polling.Configuration
(1) 在至少要傳送1024筆TS1之後且 (2) 接收到8個Link/Lane number都為PAD的TS1或TS2,(3) 並且所傳送出去和所收到TS1TS2都宣稱support相同的Data Rate Identifier(Symbol 4),則下一個state會進入Polling.Configuration

進入Polling.Configuration之後會開始傳送Link/Lane number為PAD/PAD的TS2。

註: 在Polling.Active進入到Polling.Configuration的條件中,顯示同時接受TS1或TS2,這是因為假如DP或UP其中一位已經先進入了Polling.Configuration並且開始傳送TS2,這樣另一位才會有機會進入Polling.Configuration 


● Entry to Configuration.Linkwidth.Start
(1)當接收到8Link/Lane 設為 PAD 的TS2 且 (2)所傳送出去和所收到TS2都宣稱support相同的Data Rate Identifier,並且 (3)至少傳送了16筆TS2,則下一個state將會進入Configuration.Linkwidth.Start

註: 進入Configuration state之後,spec將UP和DP分開來描述,意味著UP和DP在相同的substate中可能會使用不同的判斷條件。
 
進入Configuration.Linkwidth.Start之後,DP和UP,兩者所傳送的TS1內容不一樣。DP會在傳送出去的TS1中任意選擇Link number的數字(動畫中假設為0)且Lane number繼續維持PAD,這裡我們直接描述為0/PAD,而UP則是繼續傳送PAD/PAD。

=== 動畫3 ======


● Entry to Configuration.Linkwidth.Accept
UP:
UP當前處於Configuration.Linkwidth.Start,當UP接收到2個連續的TS1中Link number非PAD且Lane number為PAD,表示為0/PAD,則下一個state則進入Configuration.Linkwidth.Accept,並且開始傳送TS1,且Link/Lane設成和所收到的TS1一樣號碼,動畫假設為0/PAD。

DP:
DP當前處於Configuration.Linkwidth.Start當DP收到2個TS1中的Link number完全相符於DP所傳送出去的號碼,且Lane number為PAD,則下一個state則進入Configuration.Linkwidth.Accept

註: 由上面的判斷式得知,UP必須要比DP優先進入Linkwidth.Start,DP才能進行到下一個state。

=== 動畫4 ======



● Entry to Configuration.Lanenum.Wait
DP:
DP當前在Configuration.Linkwidth.Accept state,如果再次接收到2個連續0/PAD的TS1,DP就可以確立目前Link Width是多少(動畫中假設為x4),則下一個state會進入Configuration.Lanenum.Wait,並且在每個Lane上傳送不同的號碼,動畫中假設為0/0,1,2,3。

UP:
UP當前在Configuration.Linkwidth.Accept state如果接收到2個連續TS1的Link number為0,且Lane number為任意的數字(非PAD),則下一個state則會進入Configuration.Lanenum.Wait,並且開始傳送來自於DP所傳送的TS1中,相同的Lane number,動畫中假設為0/0,1,2,3但如果UP在連接上如果有Lane Reversal,其實UP可以傳送相反方向的Lane number,如0/3,2,1,0


=== 動畫5 ======



● DP entry to Configuration.Lanenum.Accept
DP:
DP當前在Configuration.Lanenum.Wait state,DP如果要進入Lanenum.Accept,這裡會有兩個判斷式,(1) 如果收到2筆連續TS1的Lane number不同於DP目前所傳送出去的Lane number號碼,且不是PAD 或 (2) 收到2筆連續TS1的Lane number完全相同於DP所傳送出去的Lane number號碼,則下一個state將會進入Configuration.Lanenum.Accept,這裡假設是進入判斷式(2)。 

註: 因此無論UP傳送什麼Lane number數值,DP都會進入Lanenum.Accept。

UP:
此時UP還處於Configuration.Lanenum.Wait,並且持續傳送0/0,1,2,3的TS1。


=== 動畫6 ======



● UP entry to Configuration.Lanenum.Accept and DP entry to Configuration.Complete
DP:
DP當前在Configuration.Lanenum.Accept,如果接收到兩筆連續TS1 Link/Lane都符合自己所傳送出去的值,則DP會進入Configuration.Complete,並且開始傳送0/0,1,2,3的TS2。
 
UP:
UP當前還處於Configuration.Lanenum.Wait,這邊UP也有兩個判斷式,(1) 如果接收到2筆連續TS1 Lane number不同於UP目前所傳送出去的Lane number號碼 或 (2) 接收到兩筆TS2,則UP會進入Configuration.Lanenum.Accept。這裡假設是進入判斷式(2)。


=== 動畫7 ======



● UP entry to Configuration.Complete
DP:
DP當前仍然處於Configuration.Complete。

UP:
UP當前還處於Configuration.Lanenum.Wait,如果接收到兩筆連續TS2 Link/Lane都符合自己所傳送出去的值,則UP會進入Configuration.Complete,並且開始傳送0/0,1,2,3的TS2。


=== 動畫8 ======



● Entry to Configuration.Idle
DP & UP: 
目前DP和UP都處於Configuration.Complete,且所有的Link/Lane number都已經確立,此時 (1)當雙方都接收到8個連續的TS2的Link/Lane符合雙方所傳送出去的值 且(2)有相同的Data Rate Identifier(Symbol4) 且 (3)連續傳送16筆TS2,則雙方都會進入Configuration.Idle state並且開始傳送Idle Data,並且設定LinkUp為1。 


=== 動畫9 ======


● Entry to L0
DP & UP: 
目前DP和UP都處於Configuration.Idle,如果(1)接收到8筆連續的TS2 Link/Lane number都相符於自己所傳送的值 且 (2)已經傳送連續16筆TS2,則雙方都會進入L0 state。

綠色的時間軸代表當Link一進入L0,就會馬上Initial Flow ControlCredit,由於Flow Control是Data Link Layer的protocol,所以獨立出來描述,請參考下面動畫10。


=== 動畫10 ======


UP當前處於FC_INIT1 state,在LinkUp設為1之後,將Data Link Layer state從DL_Inative轉移到DL_Init,並且傳送InitFC1 DLLP。DP收到之後立即進入FC_INIT1 state,並且回應InitFC2 DLLP。UP接收到InitFC2之後立即進入FC_INIT2 state並且傳送InitFC2 DLLP。DP收到InitFC2之後,會傳送UpdateFC DLLP給UP。UP收到UpdateFC後也會回覆UpdateFC DLLP給DP。


總結:
到此Link已經處於L0 state並且Link speed為Gen1(2.5 GT/s),由於後面還有很多不同的故事,例如Lane Reversal在Configuration State會怎樣解決,或者是雙方都支援Gen3 Data Rate Identifier,則會進入到Recovery State做Equalization(EQ)等等,之後再用另外一篇文章來講解。

Reference:PCI Express® Base Specification Revision 3.0

6 則留言:

  1. 講解清楚,感謝分享!

    回覆刪除
  2. 請問PCIE 6有support 從GEN1可以直接跳到GEN6,請問第一次改變速度時需要先確認GEN5沒問題後再train成GEN6嗎?

    回覆刪除
    回覆
    1. 目前還沒玩過Gen6的device,但目前gen4 device的LTSSM都是從Gen1->Gen3->Gen4,原因可能是因為Gen3以上要做Equalization,所以我猜之後Gen6 device應該也是會從Gen1->Gen3->Gen4->Gen5->Gen6,這是個人猜測

      刪除

解析 NVM Express - 透過Linux OS 解析M.2 NVMe SSD

在之前,我撰寫了三篇有關NVMe的文章 ,分別是" 原理NVM Express - NVMe Submission Queue & Completion Queue (SQ & CQ) "、" 原理NVM Express - Admi...