一、PCIe匯流排的基礎知識
與PCI匯流排不同,PCIe匯流排使用端到端的連線方式,在一條PCIe鏈路的兩端只能各連線一個裝置,這兩個裝置互為是資料傳送端和資料接收端。PCIe匯流排除了匯流排鏈路外,還具有多個層次,傳送端傳送資料時將通過這些層次,而接收端接收資料時也使用這些層次。PCIe匯流排使用的層次結構與網路協議棧較為類似。
1、端到端的資料傳遞
PCIe鏈路使用“端到端的資料傳送方式”,傳送端和接收端中都含有TX(傳送邏輯)和RX(接收邏輯),其結構如圖所示。
由上圖所示,在PCIe匯流排的物理鏈路的一個數據通路(Lane)中,由兩組差分訊號,共4根訊號線組成。其中傳送端的TX部件與接收端的RX部件使用一組差分訊號連線,該鏈路也被稱為傳送端的傳送鏈路,也是接收端的接收鏈路;而傳送端的RX部件與接收端的TX部件使用另一組差分訊號連線,該鏈路也被稱為傳送端的接收鏈路,也是接收端的傳送鏈路。一個PCIe鏈路可以由多個Lane組成。
高速差分訊號電氣規範要求其傳送端串接一個電容,以進行AC耦合。該電容也被稱為AC耦合電容。PCIe鏈路使用差分訊號進行資料傳送,一個差分訊號由D+和D-兩根訊號組成,訊號接收端通過比較這兩個訊號的差值,判斷髮送端傳送的是邏輯“1”還是邏輯“0”。
與單端訊號相比,差分訊號抗干擾的能力更強,因為差分訊號在佈線時要求“等長”、“等寬”、“貼近”,而且在同層。因此外部干擾噪聲將被“同值”而且“同時”載入到D+和D-兩根訊號上,其差值在理想情況下為0,對訊號的邏輯值產生的影響較小。因此差分訊號可以使用更高的匯流排頻率。
此外使用差分訊號能有效抑制電磁干擾EMI(Electro Magnetic Interference)。由於差分訊號D+與D-距離很近而且訊號幅值相等、極性相反。這兩根線與地線間耦合電磁場的幅值相等,將相互抵消,因此差分訊號對外界的電磁干擾較小。當然差分訊號的缺點也是顯而易見的,一是差分訊號使用兩根訊號傳送一位資料;二是差分訊號的佈線相對嚴格一些。
PCIe鏈路可以由多條Lane組成,目前PCIe鏈路可以支援1、2、4、8、12、16和32個Lane,即×1、×2、×4、×8、×12、×16和×32寬度的PCIe鏈路。每一個Lane上使用的匯流排頻率與PCIe匯流排使用的版本相關。
第1個PCIe匯流排規範為V1.0,之後依次為V1.0a,V1.1,V2.0和V2.1。目前PCIe匯流排的最新規範為V2.1,而V3.0正在開發過程中,預計在2010年釋出。不同的PCIe匯流排規範所定義的匯流排頻率和鏈路編碼方式並不相同,如表所示。
如上表所示,不同的PCIe匯流排規範使用的匯流排頻率並不相同,其使用的資料編碼方式也不相同。PCIe匯流排V1.x和V2.0規範在物理層中使用8/10b編碼,即在PCIe鏈路上的10 bit中含有8 bit的有效資料;而V3.0規範使用128/130b編碼方式,即在PCIe鏈路上的130 bit中含有128 bit的有效資料。
由上表所示,V3.0規範使用的匯流排頻率雖然只有4GHz,但是其有效頻寬是V2.x的兩倍。下文將以V2.x規範為例,說明不同寬度PCIe鏈路所能提供的峰值頻寬,如表所示。
由上表所示,×32的PCIe鏈路可以提供160GT/s的鏈路頻寬,遠高於PCI/PCI-X匯流排所能提供的峰值頻寬。而即將推出的PCIe V3.0規範使用4GHz的匯流排頻率,將進一步提高PCIe鏈路的峰值頻寬。
在PCIe匯流排中,使用GT(Gigatransfer)計算PCIe鏈路的峰值頻寬。GT是在PCIe鏈路上傳遞的峰值頻寬,其計算公式為匯流排頻率×資料位寬×2。
在PCIe匯流排中,影響有效頻寬的因素有很多,因而其有效頻寬較難計算,這部分內容詳見第8.4.1節。儘管如此,PCIe匯流排提供的有效頻寬還是遠高於PCI匯流排。PCIe匯流排也有其弱點,其中最突出的問題是傳送延時。
PCIe鏈路使用序列方式進行資料傳送,然而在晶片內部,資料匯流排仍然是並行的,因此PCIe鏈路介面需要進行串並轉換,這種串並轉換將產生較大的延時。除此之外PCIe匯流排的資料報文需要經過事務層、資料鏈路層和物理層,這些資料報文在穿越這些層次時,也將帶來延時。本書將在第8.4節詳細討論PCIe匯流排的延時與頻寬之間的聯絡。
在基於PCIe匯流排的裝置中,×1的PCIe鏈路最為常見,而×12的PCIe鏈路極少出現,×4和×8的PCIe裝置也不多見。Intel通常在ICH中集成了多個×1的PCIe鏈路用來連線低速外設,而在MCH中集成了一個×16的PCIe鏈路用於連線顯示卡控制器。而PowerPC處理器通常能夠支援×8、×4、×2和×1的PCIe鏈路。
PCIe匯流排物理鏈路間的資料傳送使用基於時鐘的同步傳送機制,但是在物理鏈路上並沒有時鐘線,PCIe匯流排的接收端含有時鐘恢復模組CDR(Clock Data Recovery),CDR將從接收報文中提取接收時鐘,從而進行同步資料傳遞。值得注意的是,在一個PCIe裝置中除了需要從報文中提取時鐘外,還使用了REFCLK+和REFCLK-訊號對作為本地參考時鐘,這個訊號對的描述見下文。
2、PCIe匯流排使用的訊號
PCIe裝置使用兩種電源訊號供電,分別是Vcc與Vaux,其額定電壓為3.3V。其中Vcc為主電源,PCIe裝置使用的主要邏輯模組均使用Vcc供電,而一些與電源管理相關的邏輯使用Vaux供電。在PCIe裝置中,一些特殊的暫存器通常使用Vaux供電,如Sticky Register,此時即使PCIe裝置的Vcc被移除,這些與電源管理相關的邏輯狀態和這些特殊暫存器的內容也不會發生改變。
在PCIe匯流排中,使用Vaux的主要原因是為了降低功耗和縮短系統恢復時間。因為Vaux在多數情況下並不會被移除,因此當PCIe裝置的Vcc恢復後,該裝置不用重新恢復使用Vaux供電的邏輯,從而裝置可以很快地恢復到正常工作狀狀態。
PCIe鏈路的最大寬度為×32,但是在實際應用中,×32的鏈路寬度極少使用。在一個處理器系統中,一般提供×16的PCIe插槽,並使用PETp0~15、PETn0~15和PERp0~15、PERn0~15共64根訊號線組成32對差分訊號,其中16對PETxx訊號用於傳送鏈路,另外16對PERxx訊號用於接收鏈路。除此之外PCIe匯流排還使用了下列輔助訊號。
「1 PERST#訊號」
該訊號為全域性復位訊號,由處理器系統提供,處理器系統需要為PCIe插槽和PCIe裝置提供該復位訊號。PCIe裝置使用該訊號復位內部邏輯。當該訊號有效時,PCIe裝置將進行復位操作。PCIe匯流排定義了多種復位方式,其中Cold Reset和Warm Reset這兩種復位方式的實現與該訊號有關。
「2 REFCLK+和REFCLK-訊號」
在一個處理器系統中,可能含有許多PCIe裝置,這些裝置可以作為Add-In卡與PCIe插槽連線,也可以作為內建模組,與處理器系統提供的PCIe鏈路直接相連,而不需要經過PCIe插槽。PCIe裝置與PCIe插槽都具有REFCLK+和REFCLK-訊號,其中PCIe插槽使用這組訊號與處理器系統同步。
在一個處理器系統中,通常採用專用邏輯向PCIe插槽提供REFCLK+和REFCLK-訊號,如圖4 2所示。其中100Mhz的時鐘源由晶振提供,並經過一個“一推多”的差分時鐘驅動器生成多個同相位的時鐘源,與PCIe插槽一一對應連線。
PCIe插槽需要使用參考時鐘,其頻率範圍為100MHz±300ppm。處理器系統需要為每一個PCIe插槽、MCH、ICH和Switch提供參考時鐘。而且要求在一個處理器系統中,時鐘驅動器產生的參考時鐘訊號到每一個PCIe插槽(MCH、ICH和Swith)的距離差在15英寸之內。通常訊號的傳播速度接近光速,約為6英寸/ns,由此可見,不同PCIe插槽間REFCLK+和REFCLK-訊號的傳送延時差約為2.5ns。
當PCIe裝置作為Add-In卡連線在PCIe插槽時,可以直接使用PCIe插槽提供的REFCLK+和REFCLK-訊號,也可以使用獨立的參考時鐘,只要這個參考時鐘在100MHz±300ppm範圍內即可。內建的PCIe裝置與Add-In卡在處理REFCLK+和REFCLK-訊號時使用的方法類似,但是PCIe裝置可以使用獨立的參考時鐘,而不使用REFCLK+和REFCLK-訊號。
在PCIe裝置配置空間的Link Control Register中,含有一個“Common Clock Configuration”位。當該位為1時,表示該裝置與PCIe鏈路的對端裝置使用“同相位”的參考時鐘;如果為0,表示該裝置與PCIe鏈路的對端裝置使用的參考時鐘是非同步的。
在PCIe裝置中,“Common Clock Configuration”位的預設值為0,此時PCIe裝置使用的參考時鐘與對端裝置沒有任何聯絡,PCIe鏈路兩端裝置使用的參考時鐘可以非同步設定。這個非同步時鐘設定方法對於使用PCIe鏈路進行遠端連線時尤為重要。
在一個處理器系統中,如果使用PCIe鏈路進行機箱到機箱間的互連,因為參考時鐘可以非同步設定,機箱到機箱之間進行資料傳送時僅需要差分訊號線即可,而不需要參考時鐘,從而極大降低了連線難度。
「3 WAKE#訊號」
當PCIe裝置進入休眠狀態,主電源已經停止供電時,PCIe裝置使用該訊號向處理器系統提交喚醒請求,使處理器系統重新為該PCIe裝置提供主電源Vcc。在PCIe匯流排中,WAKE#訊號是可選的,因此使用WAKE#訊號喚醒PCIe裝置的機制也是可選的。值得注意的是產生該訊號的硬體邏輯必須使用輔助電源Vaux供電。
WAKE#是一個Open Drain訊號,一個處理器的所有PCIe裝置可以將WAKE#訊號進行線與後,統一發送給處理器系統的電源控制器。當某個PCIe裝置需要被喚醒時,該裝置首先置WAKE#訊號有效,然後在經過一段延時之後,處理器系統開始為該裝置提供主電源Vcc,並使用PERST#訊號對該裝置進行復位操作。此時WAKE#訊號需要始終保持為低,當主電源Vcc上電完成之後,PERST#訊號也將置為無效並結束復位,WAKE#訊號也將隨之置為無效,結束整個喚醒過程。
PCIe裝置除了可以使用WAKE#訊號實現喚醒功能外,還可以使用Beacon訊號實現喚醒功能。與WAKE#訊號實現喚醒功能不同,Beacon使用In-band訊號,即差分訊號D+和D-實現喚醒功能。Beacon訊號DC平衡,由一組通過D+和D-訊號生成的脈衝訊號組成。這些脈衝訊號寬度的最小值為2ns,最大值為16us。當PCIe裝置準備退出L2狀態(該狀態為PCIe裝置使用的一種低功耗狀態)時,可以使用Beacon訊號,提交喚醒請求。
「4 SMCLK和SMDAT訊號」
SMCLK和SMDAT訊號與x86處理器的SMBus(System Mangement Bus)相關。SMBus於1995年由Intel提出,SMBus由SMCLK和SMDAT訊號組成。SMBus源於I2C匯流排,但是與I2C匯流排存在一些差異。
SMBus的最高匯流排頻率為100KHz,而I2C匯流排可以支援400KHz和2MHz的匯流排頻率。此外SMBus上的從裝置具有超時功能,當從裝置發現主裝置發出的時鐘訊號保持低電平超過35ms時,將引發從裝置的超時復位。在正常情況下,SMBus的主裝置使用的匯流排頻率最低為10KHz,以避免從裝置在正常使用過程中出現超時。
在SMbus中,如果主裝置需要復位從裝置時,可以使用這種超時機制。而I2C匯流排只能使用硬體訊號才能實現這種復位操作,在I2C匯流排中,如果從裝置出現錯誤時,單純通過主裝置是無法復位從裝置的。
SMBus還支援Alert Response機制。當從裝置產生一箇中斷時,並不會立即清除該中斷,直到主裝置向0b0001100地址發出命令。
上文所述的SMBus和I2C匯流排的區別還是侷限於物理層和鏈路層上,實際上SMBus還含有網路層。SMBus還在網路層上定義了11種匯流排協議,用來實現報文傳遞。
SMBus在x86處理器系統中得到了大規模普及,其主要作用是管理處理器系統的外部裝置,並收集外設的執行資訊,特別是一些與智慧電源管理相關的資訊。PCI和PCIe插槽也為SMBus預留了介面,以便於PCI/PCIe裝置與處理器系統進行互動。
在Linux系統中,SMBus得到了廣泛的應用,ACPI也為SMBus定義了一系列命令,用於智慧電池、電池充電器與處理器系統之間的通訊。在Windows作業系統中,有關外部裝置的描述資訊,也是通過SMBus獲得的。
「5 JTAG訊號」
JTAG(Joint Test Action Group)是一種國際標準測試協議,與IEEE 1149.1相容,主要用於晶片內部測試。目前絕大多數器件都支援JTAG測試標準。JTAG訊號由TRST#、TCK、TDI、TDO和TMS訊號組成。其中TRST#為復位訊號;TCK為時鐘訊號;TDI和TDO分別與資料輸入和資料輸出對應;而TMS訊號為模式選擇。
JTAG允許多個器件通過JTAG介面串聯在一起,並形成一個JTAG鏈。目前FPGA和EPLD可以借用JTAG介面實現線上程式設計ISP(In-System Programming)功能。處理器也可以使用JTAG介面進行系統級除錯工作,如設定斷點、讀取內部暫存器和儲存器等一系列操作。除此之外JTAG介面也可用作“逆向工程”,分析一個產品的實現細節,因此在正式產品中,一般不保留JTAG介面。
「6 PRSNT1#和PRSNT2#訊號」
PRSNT1#和PRSNT2#訊號與PCIe裝置的熱插拔相關。在基於PCIe匯流排的Add-in卡中,PRSNT1#和PRSNT2#訊號直接相連,而在處理器主機板中,PRSNT1#訊號接地,而PRSNT2#訊號通過上拉電阻接為高。PCIe裝置的熱插拔結構如圖所示。
如上圖所示,當Add-In卡沒有插入時,處理器主機板的PRSNT2#訊號由上拉電阻接為高,而當Add-In卡插入時主機板的PRSNT2#訊號將與PRSNT1#訊號通過Add-In卡連通,此時PRSNT2#訊號為低。處理器主機板的熱插拔控制邏輯將捕獲這個“低電平”,得知Add-In卡已經插入,從而觸發系統軟體進行相應地處理。
Add-In卡拔出的工作機制與插入類似。當Add-in卡連線在處理器主機板時,處理器主機板的PRSNT2#訊號為低,當Add-In卡拔出後,處理器主機板的PRSNT2#訊號為高。處理器主機板的熱插拔控制邏輯將捕獲這個“高電平”,得知Add-In卡已經被拔出,從而觸發系統軟體進行相應地處理。
不同的處理器系統處理PCIe裝置熱拔插的過程並不相同,在一個實際的處理器系統中,熱拔插裝置的實現也遠比圖4 3中的示例複雜得多。值得注意的是,在實現熱拔插功能時,Add-in Card需要使用“長短針”結構。
如圖4 3所示,PRSNT1#和PRSNT2#訊號使用的金手指長度是其他訊號的一半。因此當PCIe裝置插入插槽時,PRSNT1#和PRSNT2#訊號在其他金手指與PCIe插槽完全接觸,並經過一段延時後,才能與插槽完全接觸;當PCIe裝置從PCIe插槽中拔出時,這兩個訊號首先與PCIe插槽斷連,再經過一段延時後,其他訊號才能與插槽斷連。系統軟體可以使用這段延時,進行一些熱拔插處理。
3、PCIe匯流排的層次結構
PCIe匯流排採用了序列連線方式,並使用資料包(Packet)進行資料傳輸,採用這種結構有效去除了在PCI匯流排中存在的一些邊帶訊號,如INTx和PME#等訊號。在PCIe匯流排中,資料報文在接收和傳送過程中,需要通過多個層次,包括事務層、資料鏈路層和物理層。PCIe匯流排的層次結構如圖所示。
PCIe匯流排的層次組成結構與網路中的層次結構有類似之處,但是PCIe匯流排的各個層次都是使用硬體邏輯實現的。在PCIe體系結構中,資料報文首先在裝置的核心層(Device Core)中產生,然後再經過該裝置的事務層(Transaction Layer)、資料鏈路層(Data Link Layer)和物理層(Physical Layer),最終傳送出去。而接收端的資料也需要通過物理層、資料鏈路和事務層,並最終到達Device Core。
「1 事務層」
事務層定義了PCIe匯流排使用匯流排事務,其中多數匯流排事務與PCI匯流排相容。這些匯流排事務可以通過Switch等裝置傳送到其他PCIe裝置或者RC。RC也可以使用這些匯流排事務訪問PCIe裝置。
事務層接收來自PCIe裝置核心層的資料,並將其封裝為TLP(Transaction Layer Packet)後,發向資料鏈路層。此外事務層還可以從資料鏈路層中接收資料報文,然後轉發至PCIe裝置的核心層。
事務層的一個重要工作是處理PCIe匯流排的“序”。在PCIe匯流排中,“序”的概念非常重要,也較難理解。在PCIe匯流排中,事務層傳遞報文時可以亂序,這為PCIe裝置的設計製造了不小的麻煩。事務層還使用流量控制機制保證PCIe鏈路的使用效率。
「2 資料鏈路層」
資料鏈路層保證來自發送端事務層的報文可以可靠、完整地傳送到接收端的資料鏈路層。來自事務層的報文在通過資料鏈路層時,將被新增Sequence Number字首和CRC字尾。資料鏈路層使用ACK/NAK協議保證報文的可靠傳遞。
PCIe匯流排的資料鏈路層還定義了多種DLLP(Data Link Layer Packet),DLLP產生於資料鏈路層,終止於資料鏈路層。值得注意的是,TLP與DLLP並不相同,DLLP並不是由TLP加上Sequence Number字首和CRC字尾組成的。
「3 物理層」
物理層是PCIe匯流排的最底層,將PCIe裝置連線在一起。PCIe匯流排的物理電氣特性決定了PCIe鏈路只能使用端到端的連線方式。PCIe匯流排的物理層為PCIe裝置間的資料通訊提供傳送介質,為資料傳送提供可靠的物理環境。
物理層是PCIe體系結構最重要,也是最難以實現的組成部分。PCIe匯流排的物理層定義了LTSSM(Link Training and Status State Machine)狀態機,PCIe鏈路使用該狀態機管理鏈路狀態,並進行鏈路訓練、鏈路恢復和電源管理。
PCIe匯流排的物理層還定義了一些專門的“序列”,有的書籍將物理層這些“序列”稱為PLP(Phsical Layer Packer),這些序列用於同步PCIe鏈路,並進行鏈路管理。值得注意的是PCIe裝置傳送PLP與傳送TLP的過程有所不同。對於系統軟體而言,物理層幾乎不可見,但是系統程式設計師仍有必要較為深入地理解物理層的工作原理。
4、PCIe鏈路的擴充套件
PCIe鏈路使用端到端的資料傳送方式。在一條PCIe鏈路中,這兩個埠是完全對等的,分別連線傳送與接收裝置,而且一個PCIe鏈路的一端只能連線一個傳送裝置或者接收裝置。因此PCIe鏈路必須使用Switch擴充套件PCIe鏈路後,才能連線多個裝置。使用Switch進行鏈路擴充套件的例項如圖所示。
在PCIe匯流排中,Switch[2]是一個特殊的裝置,該裝置由1個上游埠和2~n個下游埠組成。PCIe匯流排規定,在一個Switch中可以與RC直接或者間接相連[3]的埠為上游埠,在PCIe匯流排中,RC的位置一般在上方,這也是上游埠這個稱呼的由來。在Switch中除了上游埠外,其他所有埠都被稱為下游埠。下游埠一般與EP相連,或者連線下一級Switch繼續擴充套件PCIe鏈路。其中與上游埠相連的PCIe鏈路被稱為上游鏈路,與下游埠相連的PCIe鏈路被稱為下游鏈路。
上游鏈路和下游鏈路是一個相對的概念。如上圖所示,Switch與EP2連線的PCIe鏈路,對於EP2而言是上游鏈路,而對Switch而言是下游鏈路。
在上圖所示的Switch中含有3個埠,其中一個是上游埠(Upstream Port),而其他兩個為下游埠(Downstream Port)。其中上游埠與RC或者其他Switch的下游埠相連,而下游埠與EP或者其他Switch的上游埠相連。在Switch中,還有兩個與埠相關的概念,分別是Egress埠和Ingress埠。這兩個埠與通過Switch的資料流向有關。其中Egress埠指傳送埠,即資料離開Switch使用的埠;Ingress埠指接收埠即資料進入Switch使用的埠。
Egress埠和Ingress埠與上下游埠沒有對應關係。在Switch中,上下游埠可以作為Egress埠,也可以作為Ingress埠。如圖4 5所示,RC對EP3的內部暫存器進行寫操作時,Switch的上游埠為Ingress埠,而下游埠為Egress埠;當EP3對主儲存器進行DMA寫操作時,該Switch的上游埠為Egress埠,而下游埠為Ingress埠。
PCIe匯流排還規定了一種特殊的Switch連線方式,即Crosslink連線模式。支援這種模式的Switch,其上游埠可以與其他Switch的上游埠連線,其下游埠可以與其他Switch的下游埠連線。
PCIe匯流排提供CrossLink連線模式的主要目的是為了解決不同處理器系統之間的互連,如圖所示。使用CrossLink連線模式時,雖然從物理結構上看,一個Switch的上/下游埠與另一個Switch的上/下游埠直接相連,但是這個PCIe鏈路經過訓練後,仍然是一個埠作為上游埠,而另一個作為下游埠。
處理器系統1與處理器系統2間的資料交換可以通過Crosslink進行。當處理器系統1(2)訪問的PCI匯流排域的地址空間或者Requester ID不在處理器系統1(2)內時,這些資料將被Crosslink埠接收,並傳遞到對端處理器系統中。Crosslink對端介面的P2P橋將接收來自另一個處理器域的資料請求,並將其轉換為本處理器域的資料請求。
使用Crosslink方式連線兩個拓撲結構完全相同的處理器系統時,仍然有不足之處。假設圖4 6中的處理器系統1和2的RC使用的ID號都為0,而主儲存器都是從0x0000-0000開始編址時。當處理器1讀取EP2的某段PCI匯流排空間時,EP2將使用ID路由方式,將完成報文傳送給ID號為0的PCI裝置,此時是處理器2的RC而不是處理器1的RC收到EP2的資料。因為處理器1和2的RC使用的ID號都為0,EP2不能區分這兩個RC。
由上所述,使用Crosslink方式並不能完全解決兩個處理器系統的互連問題,因此在有些Switch中支援非透明橋結構。這種結構與PCI匯流排非透明橋的實現機制類似,本章對此不做進一步說明。
使用非透明橋僅解決了兩個處理器間資料通路問題,但是不便於NUMA結構對外部裝置的統一管理。PCIe匯流排對此問題的最終解決方法是使用MR-IOV技術,該技術要求Switch具有多個上游埠分別與不同的RC互連。目前PLX公司已經可以提供具有多個上游埠的Switch,但是尚未實現MR-IOV技術涉及的一些與虛擬化相關的技術。
即便MR-IOV技術可以合理解決多個處理器間的資料訪問和對PCIe裝置的配置管理,使用PCIe匯流排進行兩個或者多個處理器系統間的資料傳遞仍然是一個不小問題。因為PCIe匯流排的傳送延時仍然是制約其在大規模處理器系統互連中應用的重要因素。