一、概述
CPU如何訪問PCIe配置空間;
CPU能夠通過寄存器訪問配置空間,為什么還需要映射PCIe配置空間;
如何掃描PCIe樹并且為PCIe分配ID;
如何將pcie域地址映射到存儲器域地址空間。
通過本篇文章將對問題1、2、3做出解答。
二、統一編址于獨立編址
CPU編址是程序指令與物理地址線建立鏈接的方式,在CPU內部有專門的地址集合,編址過程是由CPU體系架構所決定的,參考示意圖如圖 1所示(僅僅代表示意圖,講解一種邏輯結構,不代表實際電路)。CPU編址時就已經指定了0x8000_0000~0xFFFF_FFFF這個地址空間為連接到圖中內存的地址線,內存如何連接到CPU需要當參考CPU的datasheet,當CPU程序指令對0x8000_0000這個物理地址地址發起訪問時,等價于是在訪問圖中2G內存的首地址。
圖1
內存通過CPU地址總線來尋址定位,然后通過CPU數據總線讀寫數據。CPU的地址總線位數是CPU設計時確定,因此一款CPU所能尋址的地址范圍是一定的,而內存是需要占用CPU的尋址空間的,內存與CPU采用總線直接連接。
IO指的是與CPU連接的各種外設,CPU訪問各種外設有兩種方式:一種是類似于訪問內存的方式,即把外設的寄存器當成內存地址讀寫,從文可以以訪問內存方式操作外設寄存器。這時,IO與內存統一編址,IO地址與內存地址在同一個地址空間下,這種編址方式叫做IO與內存統一編址。
另外一種編址方式是IO地址與內存地址分開獨立編址,這種編址方式叫做獨立編址,此時,CPU訪問外設寄存器需要通過CPU特定的指令去訪問外設寄存器,而不能通過地址直接訪問外設寄存器。常見的ARM、PowerPc、MIPS架構都是采用統一編址,X86架構采用獨立編址。
三、訪問PCIe配置空間256bytes
PCI總線規定訪問配置空間總線事務,使用ID號進行尋址。PCI設備ID號由總線號(Bus Number)、設備號(Device Number)和功能號(Function Number)。其中總線號在HOST主橋遍歷PCI總線樹時確定,在一顆PCI總線樹上,總線號由系統軟件決定,通常與HOST主橋直接相連接的PCI總線編號為0,系統軟件使用DFS(Depth-First Search)算法掃描PCI總線樹上的所有PCI總線,并依次編號。
一條PCI總線的設備號由PCI設備的IDSEL信號與PCI總線地址線的連接關系確定,功能號與PCI設備的具體設計有關。一個PCIe系統最多有256條Bus,每條Bus上最多可以掛在32個設備,每個PCIe設備最多有8個功能設備。
在XX處理器中的HOST主橋中,與PCIE設備配置相關的寄存器由CFG_ADDR、CFG_DATA等組成。系統軟件使用CFG_ADDR(CFG_ADDR寄存器結構如圖 2所示)和CFG_DATA寄存器訪問PCIe設備的配置空間,這些寄存器都是采取同一編址(所有內存寄存器都使用存儲器映射方式進行尋址)。
當處理器訪問PCIe配置空間時,首先需要在CFG_ADD寄存器中設置這個PCIe設備對應的總線號、設備號、功能號和寄存器偏移,然后使能Enable位,之后當處理器對CFG_DATA讀寫訪問時,HOST主橋將這個存儲器讀寫訪問轉換成PCIe配置讀寫請求,并且發送到PCIe總線上。如果Enable位沒有使能,那么CPU對寄存器的訪問也就是一個普通IO的訪問,而不能讓HOST轉換成總線請求訪問,訪問PCIe配置空間時按照PCIe總線標準配置TLP請求,CFG_DATA是讀取的數據或者待寫入的數據。
圖2
31位:Enable位,為1時,對CFG_DATA讀寫才能轉換成PCIe總線配置請求。
30~24位:保留。
23~16位:總線號,最多=256個。
15~11位:設備號,最多=32個。
10~8位:功能號,最多=8個。
7~2位:寄存器偏移,最多訪問寄存器=64個地址,這里一個地址是DW,那么能干訪問的PCIe配置空間大小為64*4=256Byte,所以訪問PCIe配置空間都是以4字節對齊訪問的。
走到這里很多讀者可能就會有這樣的疑問,既然CPU能夠直接通過寄存器訪問配置空間,為啥還會出現配置空間在存儲域地址的映射這一說法呢?下面給出詳細解答。
訪問PCIe配置空間寄存器的方法需要追溯到原始的PCI規范。為了發起PCI總線配置周期,Intel(Intel是PCIe龍頭老大,最新的PCIe的規范總是它最先嘗試的)實現的PCI規范使用IO空間的CF8h和CFCh來分別作為索引和數據寄存器,這種方法可以訪問所有PCI設備的255 bytes配置寄存器。Intel Chipsets目前仍然支持這種訪PCI配置空間的方法。
PCIe規范在PCI規范的基礎上,將配置空間擴展到4K bytes,至于為什么擴展到4K,具體可以參考PCIe規范,這些配置CFG_ADDR和CFG_DATA寄存器方法仍然可以訪問所有PCIe設備配置空間的頭255 bytes,但是該方法訪問不了剩下的(255B~4K)配置空間。怎么辦呢?Intel外一種PCIe配置空間訪問方法。Intel Chipset通過將配置空間映射到內存地址空間,PCIe配置空間可以像對映射范圍內的內存進行read/write來訪問了。這種映射是由北橋芯片來完成的,但是不同芯片的映射方式也是不同的。目前我查看了ARM芯片的datasheet,確實是這樣的方式。
PCIe規范為每個PCIe設備添加了更多的配置寄存器,空間為4K,盡管CFG_ADDR和CFG_DATA寄存器方法仍然能夠訪問lower 255 bytes,但是必須提供另外一種方法來訪問剩下的(255B~4K)range寄存器。Intel的解決方案是使用了預留256MB內存地址空間,對這段內存的任何訪問都會發起PCIe 配置cycle。
由于4K的配置空間是directly mapped to memory的,那么PCIe規范必須保證所有的PCIe設備的配置空間占用不同的內存地址,按照PCIe規范,支持最多256個bus,每個Bus支持最多32個PCIe devices,每個device支持最多8個function,也就是說:占用內存的最大值為:256 * 32 * 8 * 4K = 256MB。圖 3是ARM Cortex-A9 datasheet內存地址分配局部圖。被PCIe配置空間占用的256M內存空間會屏蔽掉DRAM使用該段內存區,這些地址都由CPU出廠時已經固化好了。
圖3
四、PCIe配置空間的內存映射對32bit系統的影響
由于PCIe配置空間占用了256M內存空間,而且該被占用空間對DRAM來說是不可用的,這意味著256M空間消失于系統內存,這在32bit系統中更為明顯。比如,在32 bit winxp中(作者目前電腦還是用的XP系統,電腦用了七八年了),理論上可以訪問到的內存是4G,如果4G空間都被DRAM給占用,由于PCIe的存在,被PCIe占用的那部分內存空間對OS來說是不可用的,莫名的消失了最多256M內存,其實還有其他外設寄存器需要映射到內存,如果是獨立編址就不存在寄存器占用內存。
所以在XP系統中實際能夠訪問DRAM空間最大值為3.2G。64位CPU尋址不存在這個情況,個地址目前來說應該用不完,這里讀者需要注意的是CPU有32和64位尋址方式,同樣操作系統也有32和64位之分,在Linux系統中主要體現在庫文件上。
有些CPU沒有直接指定PCIe配置空間的地址范圍,需要讀取某個寄存器的值BaseAddr,這個值就說PCIe配置寄存器在內存區域映射的基地址。訪問PCIe設備配置空間時候需要手動計算訪問PCIe配置空間的地址。計算發放如下:
SIZE_PER_FUNC = 4K = 1000h
SIZE_PER_DEVICE = 4K * 8 = 8000h
SIZE_PER_BUS = 4K *8* 32 = 100000h
訪問總線號為busNo,設備號為DevNo,功能號為funcNo的offset寄存器的計算公式是:
Memory Address = BaseAddr+ busNo * SIZE_PER_BUS+ devNo * SIZE_PER_DEVICE+ funcNo * SIZE_PER_FUNC+ offset
訪問PCIe配置空間就需要通過總線號、設備號、功能號、寄存器偏移進行轉換成內存地址。轉換函數如圖 2所示。
圖 4
問題4和5在下篇文章中講解,介于作者實力有限。如有錯誤,望讀者給出寶貴的意見。
-
cpu
+關注
關注
68文章
10868瀏覽量
211844 -
PCIe
+關注
關注
15文章
1239瀏覽量
82674
原文標題:從CPU角度理解PCIe
文章出處:【微信號:SSDFans,微信公眾號:SSDFans】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論