原來PCIe這麼簡單

2021-10-10 06:45:21 字數 4204 閱讀 8131

2019-03-10 06:30

硬碟是大家都很熟悉的裝置,一路走來,從hdd到ssd,從sata到nvme,作為nvme ssd的前端介面,pcie再次進入我們的視野。作為x86體系關鍵的一環,pcie標準歷經pci,pci-x和pcie,走過近30年時光。其中host發現與查詢裝置的方式卻一脈沿襲,今天我們先來聊一聊pcie裝置在乙個系統中是如何發現與訪問的。

首先我們來看一下在x86系統中,pcie是什麼樣的乙個體系架構。下圖是乙個pcie的拓撲結構示例,pcie協議支援256個bus, 每條bus最多支援32個device,每個device最多支援8個function,所以由bdf(bus,device,function)構成了每個pcie裝置節點的身份證號。

pcie體系架構一般由root complex,switch,endpoint等型別的pcie裝置組成,在root complex和switch中通常會有一些embeded endpoint(這種裝置對外不出pcie介面)。這麼多的裝置,cpu啟動後要怎麼去找到並認出它們呢? host對pcie裝置掃瞄是採用了深度優先演算法,其過程簡要來說是對每乙個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次。我們一般稱這個過程為pcie裝置列舉。列舉過程中host通過配置讀事物包來獲取下游裝置的資訊,通過配置寫事物包對下游裝置進行設定。

第一步,pci host主橋掃瞄bus 0上的裝置(在乙個處理器系統中,一般將root complex中與host bridge相連線的pci匯流排命名為pci bus 0),系統首先會忽略bus 0上的embedded ep等不會掛接pci橋的裝置,主橋發現bridge 1後,將bridge1 下面的pci bus定為 bus 1,系統將初始化bridge 1的配置空間,並將該橋的primary bus number 和 secondary bus number暫存器分別設定成0和1,以表明bridge1 的上游匯流排是0,下游匯流排是1,由於還無法確定bridge1下掛載裝置的具體情況,系統先暫時將subordinate bus number設為0xff。

第二步,系統開始掃瞄bus 1,將會發現bridge 3,並發現這是乙個switch裝置。系統將bridge 3下面的pci bus定為bus 2,並將該橋的primary bus number 和 secondary bus number暫存器分別設定成1和2,和上一步一樣暫時把bridge 3 的subordinate bus number設為0xff。

第三步,系統繼續掃瞄bus 2,將會發現bridge 4。繼續掃瞄,系統會發現bridge下面掛載的nvme ssd裝置,系統將bridge 4下面的pci bus定為bus 3,並將該橋的primary bus number 和 secondary bus number暫存器分別設定成2和3,因為bus3下面掛的是端點裝置(葉子節點),下面不會再有下游匯流排了,因此bridge 4的subordinate bus number的值可以確定為3。

第四步,完成bus 3的掃瞄後,系統返回到bus 2繼續掃瞄,會發現bridge 5。繼續掃瞄,系統會發現下面掛載的nic裝置,系統將bridge 5下面的pci bus設定為bus 4,並將該橋的primary bus number 和 secondary bus number暫存器分別設定成2和4,因為nic同樣是端點裝置,bridge 5的subordinate bus number的值可以確定為4。

第五步,除了bridge 4和bridge 5以外,bus2下面沒有其他裝置了,因此返回到bridge 3,bus 4是找到的掛載在這個bridge下的最後乙個bus號,因此將bridge 3的subordinate bus number設定為4。bridge 3的下游裝置都已經掃瞄完畢,繼續向上返回到bridge 1,同樣將bridge 1的subordinate bus number設定為4。

第六步,系統返回到bus0繼續掃瞄,會發現bridge 2,系統將bridge 2下面的pci bus定為bus 5。並將bridge 2的primary bus number 和 secondary bus number暫存器分別設定成0和5, graphics card也是端點裝置,因此bridge 2 的subordinate bus number的值可以確定為5。

至此,掛在pcie匯流排上的所有裝置都被掃瞄到,列舉過程結束,host通過這一過程獲得了乙個完整的pcie裝置拓撲結構。

系統上電以後,host會自動完成上述的裝置列舉過程。除一些專有系統外,普通系統只會在開機階段進行進行裝置的掃瞄,啟動成功後(列舉過程結束),即使插入乙個pcie裝置,系統也不會再去識別它。

在linux作業系統中,我們可以通過lspci –v -t命令來查詢系統上電階段掃瞄到的pcie裝置,執行結果會以乙個樹的形式列出系統中所有的pcie裝置。如下圖所示,其中黃色方框中的pcie裝置是北京憶芯科技公司(bejing starblaze technology co., ltd.)推出的star1000系列nvme ssd主控晶元,圖中顯示的9d32是starblaze在pci-sig組織的註冊碼,1000是裝置系列號。

star1000裝置的bdf也可以從上圖中找出,其中bus是0x3c,device是0x00,function是0x0,bdf表示為3c:00.0,與之對應的上游埠是00:1d.0。

當然也可以使用lspci –vvv –s 3c:00.0命令來檢視裝置特性,初學者看到下面的列表也就一目了然了。

host在列舉裝置的同時也會對裝置進行配置,每個pcie裝置都會指定一段cpu memory訪問空間,從上面的圖中我們可以看到這個裝置支援兩段訪問空間,一段的大小是1m byte,另一段的大小是256k byte,系統會分別指定它們的基位址。基位址配置完成以後,host就可以通過位址來對pcie memory空間進行訪問了。

pcie memory空間關聯的是pcie裝置物理功能,對於star1000系列晶元而言,物理功能是nvme,memory中存放的是nmve的控制與狀態資訊,對於nmve的控制以及工作狀態的獲取,都需要通過memory訪問來實現。

下面以nvme命令下發為例簡單描述pcie裝置的memory訪問。nvme命令下發的基本操作是1)host寫doorbell暫存器,此時使用pcie memory寫請求。如下圖所示,host發出乙個memory write(mwr)請求,該請求經過switch到達要訪問的nvme ssd裝置。

這個請求會被端點裝置接收並執行2)nvme讀取命令操作。如下圖所示,此時nvme ssd作為請求者,發出乙個memory read(mrd)請求,該請求經過switch到達host,host作為完成者會返回乙個完成事物包(cpld),將訪問結果返回給nvme ssd。

這樣,乙個nvme的命令下發過程就完成了。同樣,nvme的其他操作比如各種佇列操作,命令與完成,資料傳輸都是通過pcie memory訪問的方式進行的,此處不再詳述。

通過上面的描述,相信能夠幫助大家了解pcie的裝置列舉和memory空間訪問。以後會繼續與大家**pcie的其他內容,比如pcie的協議分層,鏈路建立,功耗管理等等。目前pcie協議還正在不斷的快速演進中,2023年發布的pcie gen4標準,每條serdes支援的速率已經達到16gbps,gen5也在加速制定中,其速率會再翻一倍達到32gbps。starblaze會緊跟技術的發展趨勢,提供速率更高,效能更好更穩定的nvme ssd系列產品

軟體測試入門,原來這麼簡單

人非聖賢,孰能無過。每個組織的最終目標都有其自己的一套期望。對於某些企業而言,成功的實際結果與預期結果相匹配的頻率很高,這表明了成功。但是,在達到最終目標之前,每個公司都必須面對人為錯誤的後果。任何企業都不能以人為錯誤為藉口提供受損產品。為了確保高質量的產品,必須有一些地方可以找出錯誤。對於軟體開發...

原來生成函式這麼簡單

在正式介紹生成函式的計算之前我們要現引入泰勒公式,以便在之後我們使用。一些泰勒公式 emmmm第乙個公式打錯啦,應該是 那在我們有了泰勒公式之後我們開始正式踏上我們的探索生成函式之旅.part 1 了解生成函式 對於乙個數列 我們將他們整體表示成形如 的函式,然後將這個函式化簡為封閉形式,最後所得的...

設計模式原來這麼簡單 命令模式

1.什麼是命令模式wiki 它把在稍後執行的乙個動作或觸發的乙個事件所需要的所有資訊封裝到乙個物件中。2.例項例如假如有乙個萬能遙控可以對任何東西發出任何命令 3.程式示例public inte ce command 目標 public inte ce target 電視類 public abstr...