PCIE training


在PCIe鏈路可以正常工作之前,需要對PCIe鏈路進行鏈路訓練,在這個過程中,就會用LTSSM狀態機。LTSSM全稱是Link Training and Status State Machine。這個狀態機在哪里呢?它就在PCIe總線的物理層之中。
 
LTSSM狀態機涵蓋了11個狀態,包括Detect, Polling, Configuration, Recovery, L0, L0s, L1, L2, Hot Reset, Loopback, Disable。這11個狀態之間轉換的邏輯,如下圖,

 

 

 

這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工作。
 

 


判斷RX是否存在的邏輯比較簡單,就是通過一個“Detect logic”電路比較RC時間常數的大小。

(1) 當RX不存在時,RC時間常數較小。
 

 

 
(2) 當RX存在時,RC時間常數較大。
 

 


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.
 

 


(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.
 

 

由於Configuration狀態下,發送端和接收端已經確認可以正常通信,所以,我們結合實例來看一下Downstream和Upstream的狀態轉換過程。
(1) Link Number Negotiation
Downstream在TS1中設定Link number, 此時Lane number=PAD,並發送給Upstream.
 

 

而Upstream回的第一個TS1中,Link num仍然是PAD。此時,Upstream也處於Configuration.LinkWidth.Start狀態。
 

 

之后Upstream回的TS1中Link number則是設定值,此時, Upstream率先進入Configuration.LinkWidth.Accept狀態。
 

 

到這里,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都已設定。
 

 

當Upstream收到Downstream設定Lane number的TS序列之后,也很快進入了Configuration.LaneNum.Accept狀態。
 

 

與Lane number相關的三個狀態之間相互轉換邏輯如下:Downstream Vs Upstream.
 
 

 

 

到這里,雙方Lane number協議就完成了。
(3) Confirm Lane/Link Number
最后一步,過程就很簡單了,雙方通過發送TS2序列,對之前設定的Link/Lane number進行確認,這個過程,LTSSM處於Configuration.Complete. 確認沒有問題之后,就准備進入下一個狀態。
 

 

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子狀態轉換邏輯如下圖:
 
 
我們結合一個上電過程中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鏈路就可以回到正常工作狀態。

L0s/L1/L2
這三個狀態,主要是低功耗電源管理狀態,在這里不再展開了,具體可以參考Spec.
Hot Reset
當某個PCIe設備發生錯誤時,我們有時候需要通過軟件的方式對設備進行復位,這個方式就是Hot Reset。可以通過設置Bridge Control寄存器中的Secondary Bus Reset來觸發Hot Reset.
 
Hot Reset的指令是在TS1序列中體現,如下圖,
 

 

 

Hot Reset觸發之后,LTSSM會進入Recovery和Hot Reset狀態,之后會到Detect狀態,PCIe鏈路開始重新訓練。
 

 

Disabled
用戶可以通過設置修改Link Control寄存器,讓PCIe鏈路出於Disabled狀態。
 

 

另外,如果我們把設備移除之后,同樣也進入Disabled狀態。
當退出Disabled狀態后,LTSSM回到Dectect,PCIe鏈路重新訓練。
 

 

Loopback
這個狀態僅用於debug測試,一般情況不會遇到,在這里不再展開,有興趣的話可以參考PCIe Spec


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM