大話PCIe BAR空間和TLP

2021-08-08 08:23:10 字數 2602 閱讀 8440

關於位址相關的問題,搞清楚這三個位址之間的關係就可以了:

儲存器位址,就是cpu,dma等裝置直接讀寫的位址。 tlp中的位址。 bar空間位址。

如果兩兩組合的話,能夠形成三種關係,但是事實上,這三者之間的關係其實就兩部分:

儲存器位址和tlp位址欄位的關係。 tlp位址欄位和bar空間位址的關係。

解決這兩個問題,位址相關的問題就應該都清楚了。

首先要知道bar有什麼用?通過bar暫存器,我們首先知道這個基址對應的空間屬性,然後給這段空間分配乙個基址(這個基址只是用來路由定址用的,不能和儲存器空間的位址搞混,很多軟體實現上會把兩個位址設定成一樣,但是本質上沒有任何關係,只是tlp定址的時候用的!)。這樣的話,tlp就能根據位址被路由到對應裝置的bar空間中去。比如說現在有乙個mem read request,如果路由位址(位址資訊包含在tlp中)是0x71000000,而有乙個裝置func0的mem空間範圍是0x70000000~0x80000000,那麼這個tlp就會被這個func處理。從func0的0x71000000對應的位址讀取相應資料。

這就是tlp中的位址欄位和bar空間的位址之間的關係。還有乙個問題是關於儲存器位址和tlp位址欄位的關係,有個硬體單元非常重要,那就是atu,見第二節。這裡詳細介紹一下bar的配置問題。

bar位置:

對於ep來講,配置空間的對映是這樣的:

從上圖中看到,bar是從配置空間0x10到0x24的連續6個32位暫存器。關於bar每個欄位的解釋可以參考dwc_pcie_reference[1]

bar配置過程:

通過cfg write request向bar位址寫入全1。 通過cfg read request讀取bar。 根據讀取的bar值進行如下判斷:

從高位開始讀取連續的1,說明這些位元位是可寫的,表徵該space的size,譬如讀到的bar為0x11100000,那麼這個space的size為0x100000 bytes,同時由於第0位為0,表示memory bar,否則為i/o bar。bits[2:1]和bits[3]的含義如下圖所示

tlp中的位址**來?atu轉換過來的。這個問題就是這麼的簡單。atu是什麼?是乙個位址轉換單元,負責將一段儲存器域的位址轉換到pcie匯流排域位址,除了位址轉換外,還能提供訪問型別等資訊,這些資訊都是atu根據匯流排上的訊號自己做的,資料都打包到tlp中,不用軟體參與。軟體需要做的是配置atu,所以如果atu配置完成,並且能正常工作,那麼cpu訪問pcie空間就和訪問本地儲存器空間方法是一樣的,只要讀寫即可。

這就解釋了儲存器位址和tlp位址欄位的關係了。至此,位址相關的問題就解決了。

atu配置舉例:以kernel 4.4中designware pcie host驅動為例?

12

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

staticvoiddw_pcie_prog_outbound_atu(struct pcie_port *pp,intindex,

inttype, u64 cpu_addr, u64 pci_addr, u32 size)

tlp(transaction layer packet)應該算是pcie中最重要的概念了。可以說tlp是使用者程式和pcie裝置互動的唯一渠道(edma和msi本質上還是通過tlp)。tlp的構成如下圖所示,具體每個欄位的含義參見pci_express_base_specification_revision_4.0.ver.0.3第2.2節

因為軟體不需要顯示的配置tlp,所以這裡就沒有tlp的配置了,取而代之的是相關硬體的配置(譬如atu)。這裡有個了解就行,等到除錯的時候就需要仔細的了解了。

這篇文章總結了pcie裝置位址空間的知識,搞明白了這個之後應該能上手開始寫pcie驅動了,至少能列舉了。下篇就詳細介紹pcie裝置列舉過程,也是對這些知識的乙個應用。

棧空間和堆空間

乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 又編譯器自動分配釋放,存放函式的引數值,區域性變數的值等,其操作方式類似於資料結構的棧。2 堆區 heap 一般是由程式設計師分配釋放,若程式設計師不釋放的話,程式結束時可能由os 值得注意的是他與資料結構的堆是兩回事,分配...

棧空間和堆空間

乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 又編譯器自動分配釋放,存放函式的引數值,區域性變數的值等,其操作方式類似於資料結構的棧。2 堆區 heap 一般是由程式設計師分配釋放,若程式設計師不釋放的話,程式結束時可能由os 值得注意的是他與資料結構的堆是兩回事,分配...

棧空間和堆空間

一直都把堆疊放一起,所以很多人會誤以為他們的組合是乙個詞語,就像 衣服 一樣簡單,其實不然,今天在下就將最近學習總結的一些與大家分享。乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 又編譯器自動分配釋放,存放函式的引數值,區域性變數的值等,其操作方式類似於資料結構的棧。2...