1. 程式人生 > >PCIe實踐之路:匯流排結構與配置空間

PCIe實踐之路:匯流排結構與配置空間

把有限的精力花在真正有價值的事情上。

每個PCIe裝置都位於一個匯流排架構中(RC、SW和EP共同組成了一個PCIe網路),如何組織這些裝置,以及如何訪問這些裝置呢?

一、網路拓撲與裝置埠

上一篇已經講到構成PCIe網路的三個角色:RC、SW和EP。其實這整個網路給人感覺就像樂高積木,上一級裝置的下游埠接下級裝置的上游埠,然後埠不但能看出連結狀態,還提供包傳輸的鏈路。

這裡有兩個常見的概念:DSP(Down Stream Port)和USP(Upper Stream Port)。對每個功能裝置來講,用來連線上下游裝置的埠統稱為DSP或者USP。

整個網路的拓撲如圖[1]所示

螢幕快照 2017-06-29 23.05.43.png

上面有這麼多的裝置,自然而然想到的第一個問題是:怎麼來標記各個裝置呢?答案是通過匯流排號和裝置號。

舉例如下:第一級RC所在的層級,定義為Bus 0,這個沒有什麼問題。那麼下一級bus怎麼定義的呢?通過bridge或者switch裝置來定義,每個bridge或者switch代表一級bus。對於同樣連線在RC上的bridge和switch,根據深度優先搜尋來定義bus,譬如上圖中,如果最下面的switch是RC上的第一個device,那麼這個switch就代表了Bus 1。連在這個switch DSP上的裝置都屬於Bus 1。

關於匯流排,裝置和功能:PCIe規範規定,一個PCIe裝置網路中,最多支援256級Bus,每條Bus下面可以掛32個device,每個device最多擁有8個function。如果一個device存在,那麼必須存在function 0。這樣的話,通過Bus、Device和Function就能唯一匹配到特定的功能裝置。

二、配置空間

上一節說到定義Bus的問題,根據深度優先搜尋,我們知道了應該給每一級bridge分配的匯流排號,具體到操作上講,其實就是往對應裝置(一定是bridge或者switch)的配置空間的0x18位置寫匯流排號。配置空間是針對function而言的,每個function都有其配置空間(說白了其實就是一堆配置暫存器)。

如果一個device是bridge或者switch,那麼其function的配置空間[2]是這個樣子的。

螢幕快照 2017-06-30 00.12.32.png

每個PCIe裝置下的function都要實現4KB的配置空間,從裝置內部地址0開始,注意這裡是在裝置內部的。因此訪問PCIe配置空間不能通過直接讀寫系統匯流排實現,因為系統總線上看到的是CPU地址。在PCIe標準中,訪問PCIe配置空間的是cfg tlp(configuration transaction layer packet)。cfg tlp又分為type 0和type 1,type 1用來訪問PCIe橋,type 0訪問端點裝置。綜上所述,要訪問SW的配置空間,就要發起cfg type1 tlp;要訪問EP配置空間,就要發起cfg type0 tlp。每種cfg tlp又分read(rd)和write(wr),排列組合一下,cfg tlp就有四種形式:type 0 rd、type 0 wr、type 1 rd、type 1 wr。

綜合地址編碼和配置空間的介紹,這裡給出每個function在PCI域的配置基址:cfg_base[27:20] = Bus Number,cfg_base[19:15] = Device Number,cfg_base[14:12] = Function Number。

這裡遺留了兩個問題:

  1. 既然PCIe裝置配置空間是內部的,和外部匯流排地址有什麼關係呢?每個function在PCI域的配置地址是怎麼被應用的?
  2. 如何發起cfg type0 tlp或者cfg tpe1 tlp?

這兩個問題留待下篇文章解決吧。

下篇預告:PCIe地址空間與tlp

[1] PCI_Express_Base_Specification_Revision_4.0.Ver.0.3
[2] DWC_pcie_reference