在之前,我撰寫了一篇介紹PCIExpress: Link Training and Status State Machine(LTSSM)介紹有關LTSSM中各個state的介紹,接下來這篇文章會推演兩個端點之間的LTSSM是如何從Detect state演進到L0。PCIe的優點就是point-to-point interconnects(點對點的連接),所以就算系統上由多層PCIe bus所構成,每個component只要負責與他對面的component之間的link negotiation就可以了,大大的降低複雜程度。
■ 前言
在PCIe spec當中有幾個名詞需要特別解釋一下,如Figure 1,Upstream Component為上游的device,Downstream Component為下游的device,而在Upstream Component下面所連接出去的port稱之為Downstream Port或者Downstream Lanes(簡稱DP),Downstream Component上面所連接出去的port稱之為Upstream Port或者Upstream Lanes(簡稱UP),所以在spec中提到的Downstream Port所指的是Upstream Component,Upstream Port所指的是Downstream Component,在閱讀spec這點要特別注意。
Figure 1
■ Detect -> Polling -> Configuration -> L0推演
Downstream Port和Upstream 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,圖中的LinkUp、directed_speed_change、upconfigure_capable和idle_to_rlock_transitioned可以視為Physical Layer內部的register(not visible to software)。
● Entry to Detect.Active
然後在離開Electrical Idle 12ms之後,雙方則會進入Detect.Active,並且開始Receiver Detection的程序,Receiver Detection的介紹請參考文章開頭所貼的文章,基本上就是偵測對方的存在。
然後在離開Electrical Idle 12ms之後,雙方則會進入Detect.Active,並且開始Receiver Detection的程序,Receiver Detection的介紹請參考文章開頭所貼的文章,基本上就是偵測對方的存在。
● 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) 並且所傳送出去和所收到TS1或TS2都宣稱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)當接收到8個Link/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。
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 Control的Credit,由於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)等等,之後再用另外一篇文章來講解。
謝謝分享,獲益良多~
回覆刪除感謝支持!!
刪除講解清楚,感謝分享!
回覆刪除謝謝!!
刪除請問PCIE 6有support 從GEN1可以直接跳到GEN6,請問第一次改變速度時需要先確認GEN5沒問題後再train成GEN6嗎?
回覆刪除目前還沒玩過Gen6的device,但目前gen4 device的LTSSM都是從Gen1->Gen3->Gen4,原因可能是因為Gen3以上要做Equalization,所以我猜之後Gen6 device應該也是會從Gen1->Gen3->Gen4->Gen5->Gen6,這是個人猜測
刪除写的很不错
回覆刪除有几个地方建议优化下可能会更容易让读者理解:
1.則DP會進入Configuration.Complete,並且開始傳送0/0,1,2,3的TS2。
这里建议增加DP输出的TS2的link number和lane number需要和从UP获取的TS1的保持一致,这样才能保证UP从Configuration.Lanenum.Accept跳转到Configuration.Complete的条件被触发
2.在支持lane reversal的场景下,即使接收到的link number(3,2,1,0)和输出的link number(0,1,2,3)翻转也不影响DP从Configuration.Lanenum.Accept跳转到Configuration.Complete。这样可以和前面的lane reversal对应起来