PCIe實踐之路:DMA機制

一、PCIe DMA機制

PCIe控制器也提供DMA(Direct Memory access)功能,用來批量地異步數據傳輸。

1.1 DMA讀寫的發起和結束

假設現在RC要從EP mem space讀1MB數據,可以有這麼兩種方式:RC發起DMA讀;EP發起DMA寫。這兩種方式結果是等效的,對最後完成中斷的方式會不一樣,前者通過local interrupt表示自己DMA讀完了,後者需要EP發送一筆IMWr來表示DMA讀完成了。

1.2 DMA配置

這裏寫圖片描述

如圖表示本地控制器發起一筆1MB寫操作

1.2.1 SAR和DST

SAR表示DMA傳輸的數據源地址,如果RC發起從EP讀操作,那麼SAR必定是EP中某個BAR range內。目標地址DAR就是系統ddr中的地址。反之,如上圖所示的寫操作,DAR就是EP中mem space。

1.2.2 Max_Payload_Size

DMA讀寫本質上還是通過拆分成TLP來進行的,每次傳輸的size就是通過tlp header中的length來確定的,而length由控制器的Max_Payload_Size決定,這個值取EP和RC的capability中相應參數的最小值。

1.3、Linked List

對於大批量數據的傳輸,通常都會有所謂的Linked List Mode。試想一下,在Linux運行時要進行大批量數據傳輸的時候是很難分配到大塊連續的物理地址的,那麼勢必需要重複發起DMA傳輸,這樣的話DMA的異步傳輸功能豈不是被變相衰弱了。所以在硬件上要有這樣一種機制來避免這個問題,這就是LL DMA

這種機制廣泛存在於各種高速設備中,USB3.0傳輸的時候內部通過鏈接trb實現的就是Linked List DMA。

這裏寫圖片描述

如上圖所示,Linked List中每個配置塊稱作element,每個element中的內容就是前面DMA傳輸時候的配置,硬件在發起DMA傳輸的時候把這塊payload加載到指定的寄存器中。LL mode的結束通過CB來標誌,toggle一下即表示到了LL的末尾。

二、PCIe MSI機制

PCIe採用data path才傳遞interrupt,這就是Message Signal Interrupt。假如RC收到一筆對應的寫操作,那麼在硬件實現上就會自動轉換成中斷信號給中斷控制器,這筆寫請求並不會到任何ram區域。

2.1 硬件支持

2.1.1 Generic Interrupt Controller

https://developer.arm.com/products/system-ip/system-controllers/interrupt-controllers

從CoreLink GIC-500開始支持MSI/MSI-X。CoreLink GIC-400不支持,所以就算PCIe設備支持也無法實現MSI(-X)機制。

2.1.2 PCIe設備支持

每一個具有MSI capability的device都有一組對應的寄存器來表示MSI能力。

MSI Control Register中的multiple message capable(三個比特,假設值爲x)表示MSI可產生多少message,計算方法爲2的x此方。另外有三個比特multiple message enable,和message capable對應,表示實際使能了多少message。還有一個MSI data寄存器和MSI address寄存器,要結合中斷控制器配置,表示具體的message編碼和message的目標地址。

到這篇文章爲止涉及的知識已經能夠讓PCIe工作起來了,接下來開始寫些Linux PCIe驅動相關的文章。

發佈了146 篇原創文章 · 獲贊 81 · 訪問量 53萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章