3.1 PCI設備BAR空間的初始化
在PCI Agent設備進行數據傳送之前,係統軟件需要初始化PCI Agent設備的BAR0~5寄存器和PCI橋的Base、Limit寄存器。係統軟件使用DFS算法對PCI總線進行遍曆時,完成這些寄存器的初始化,即分配這些設備在PCI總線域的地址空間。當這些寄存器初始化完畢後,PCI設備可以使用PCI總線地址進行數據傳遞。
值得注意的是,PCI Agent設備的BAR0~5寄存器和PCI橋的Base寄存器保存的地址都是PCI總線地址。而這些地址在處理器係統的存儲器域中具有映像,如果一個PCI設備的BAR空間在存儲器域中沒有映像,處理器將不能訪問該PCI設備的BAR空間。
如上文所述,處理器通過HOST主橋將PCI總線域與存儲器域隔離。當處理器訪問PCI設備的地址空間時,需要首先訪問該設備在存儲器域中的地址空間,並通過HOST主橋將這個存儲器域的地址空間轉換為PCI總線域的地址空間之後,再使用PCI總線事務將數據發送到指定的PCI設備中。
PCI設備訪問存儲器域的地址空間,即進行DMA操作時,也是首先訪問該存儲器地址空間所對應的PCI總線地址空間,之後通過HOST主橋將這個PCI總線地址空間轉換為存儲器地址空間,再由DDR控製器對存儲器進行讀寫訪問。
不同的處理器係統采用不同的機製實現存儲器域和PCI總線域的轉換。如PowerPC處理器使用Outbound寄存器組實現存儲器域到PCI總線域間的轉換,並使用Inbound寄存器組實現PCI總線域到存儲器域間的轉換。
而x86處理器沒有這種地址空間域的轉換機製,因此從PCI設備的角度上看,PCI設備可以直接訪問存儲器地址;從處理器的角度上看,處理器可以直接訪問PCI總線地址空間。但是讀者需要注意,在x86處理器的HOST主橋中仍然有存儲器域與PCI總線域這個概念。隻是在x86處理器的HOST主橋中,存儲器域的存儲器地址與PCI總線地址相等,這種“簡單相等”也是一種映射關係。
3.1.1 存儲器地址與PCI總線地址的轉換
下文根據PowerPC和x86處理器的主橋,抽象出一個虛擬的HOST主橋,並以此為例講述PCI Agent設備之間,以及PCI Agent設備與主存儲器間的數據傳送過程。
我們假設在一個32位處理器中,其存儲器域的0xF000-0000~0xF7FF-FFFF(共128MB)這段物理地址空間與PCI總線的地址空間存在映射關係。
當處理器訪問這段存儲器地址空間時,HOST主橋將會認領這個存儲器訪問,並將這個存儲器訪問使用的物理地址空間轉換為PCI總線地址空間,並與0x7000-0000~0x77FF-FFFF這段PCI總線地址空間對應。
為簡化起見,我們假定在存儲器域中隻映射了PCI設備的存儲器地址空間,而不映射PCI設備的I/O地址空間。而PCI設備的BAR空間使用0x7000-0000~0x77FF-FFFF這段PCI總線域的存儲器地址空間。
在這個HOST主橋中,存儲器域與PCI總線域的對應關係如圖3?1所示。
當PCI設備使用DMA機製,訪問存儲器域地址空間時,處理器係統同樣需要將存儲器域的地址空間反向映射到PCI總線地址空間。假設在一個處理器係統中,如果主存儲器大小為2GB,其在存儲器域的地址範圍為0x0000-0000~0x7FFF-FFFF,而這段地址在PCI總線域中對應的“PCI總線地址空間”為0x8000-0000~0xFFFF-FFFF。
因此PCI設備進行DMA操作時,必須使用0x8000-0000~0xFFFF-FFFF這段PCI總線域的地址,HOST主橋才能認領這個PCI總線事務,並將這個總線事務使用的PCI總線地址轉換為存儲器地址,並與0x0000-0000~0x7FFF-FFFF這段存儲器區域進行數據傳遞。
在一個實際的處理器係統中,很少有係統軟件采用這樣的方法,實現存儲器域與PCI總線域之間的映射,“簡單相等”還是最常用的映射方法。本章采用圖3?1的映射關係,雖然增加了映射複雜度,卻便於讀者深入理解存儲器域到PCI總線域之間的映射關係。下文將以這種映射關係為例,詳細講述PCI設備BAR0~5寄存器的初始化。
3.1.2 PCI設備BAR寄存器和PCI橋Base、Limit寄存器的初始化
PCI橋的Base、Limit寄存器保存“該橋所管理的PCI子樹”的存儲器或者I/O空間的基地址和長度。值得注意的是,PCI橋也是PCI總線上的一個設備,在其配置空間中也有BAR寄存器,本節不對PCI橋BAR寄存器進行說明,因為在多數情況下透明橋並不使用其內部的BAR寄存器。下文以圖3?2所示的處理器係統為例說明上述寄存器的初始化過程,該處理器係統使用的存儲器域與PCI總線域的映射關係如圖3?1所示。
在PCI設備的BAR寄存器中,包含該設備使用的PCI總線域的地址範圍。在PCI設備的配置空間中共有6個BAR寄存器,因此一個PCI設備最多可以使用6組32位的PCI總線地址空間,或者3組64位的PCI總線地址空間。這些BAR空間可以保存PCI總線域的存儲器地址空間或者I/O地址空間,目前多數PCI設備僅使用存儲器地址空間。而在通常情況下,一個PCI設備使用2到3個BAR寄存器就足夠了。
為簡化起見,我們首先假定在圖3?2中所示的PCI總線樹中,所有PCI Agent設備隻使用了BAR0寄存器,其申請的數據空間大小為16M字節(即0x1000000字節)而且不可預讀,而且PCI橋不占用PCI總線地址空間,即PCI橋不含有BAR空間。並且假定當前HOST主橋已經完成了對PCI總線樹的編號。
根據以上假設,係統軟件該PCI總線樹的遍曆過程如下所示。
(1) 係統軟件根據DFS算法,係統軟件率先尋找到第一組PCI設備,分別為PCI設備31和PCI設備32,並根據這兩個PCI設備需要的PCI空間大小,從PCI總線地址空間中(0x7000-0000~0x77FF-FFFF)為這兩個PCI設備的BAR0寄存器分配基地址,分別為0x7000-0000和0x7100-0000。
(2) 當係統軟件完成PCI總線3下所有設備的BAR空間的分配後,將初始化PCI橋3的配置空間。這個橋片的Memory Base寄存器保存其下所有PCI設備使用的“PCI總線域地址空間的基地址”,而Memory Limit寄存器保存其下PCI設備使用的“PCI總線域地址空間的大小”。係統軟件將Memory Base寄存器賦值為0x7000-0000,而將Memory Limit寄存器賦值為0x200-0000。
(3) 係統軟件回朔到PCI總線2,並找到PCI總線2上的PCI設備21,並將PCI設備21的BAR0寄存器賦值為0x7200-0000。
(4) 完成PCI總線2的遍曆後,係統軟件初始化PCI橋2的配置寄存器,將Memory Base寄存器賦值為0x7000-0000,Memory Limit寄存器賦值為0x300-0000。
(5) 係統軟件回朔到PCI總線1,並找到PCI設備11,並將這個設備的BAR0寄存器賦值為0x7300-0000。並將PCI橋1的Memory Base寄存器賦值為0x7000-0000,Memory Limit寄存器賦值為0x400-0000。
(6) 係統軟件回朔到PCI總線0,並在這條總線上發現另外一個PCI橋,即PCI橋4。並使用DFS算法繼續遍曆PCI橋4。首先係統軟件將遍曆PCI總線4,並發現PCI設備41和PCI設備42,並將這兩個PCI設備的BAR0寄存器分別賦值為0x7400-0000和0x7500-0000。
(7) 係統軟件初始化PCI橋4的配置寄存器,將Memory Base寄存器賦值為0x7400-0000,Memory Limit寄存器賦值為0x200-0000。係統軟件再次回到PCI總線0,這一次係統軟件沒有發現新的PCI橋,於是將初始化這條總線上的所有PCI設備。
(8) PCI總線0上隻有一個PCI設備,PCI設備01。係統軟件將這個設備的BAR0寄存器賦值為0x7600-0000,並結束整個DFS遍曆過程。
最後更新:2017-04-03 16:48:37