Configuration 組態
組態表頭區域(Configuration Header Region)
除了 host/PCI 橋接器以外,每一個PCI功能都必須實作PCI組態空間,而PCI組態暫存器就是位於此空間中。host/PCI橋接器可以在PCI組態空間、在IO空間或在記憶體空間實做這些暫存器。PCI組態空間,透過這個區塊,設計程式的人可以先從這個表中,讀取某些唯讀的區塊,獲取硬體相關的資訊,因為只要是符合PCI規範的裝置,這個表的實作格式都會一樣。
每一個PCI功能擁有保留給實作其組態暫存器用的64個組態 dword區塊。前面16個dword的格式與使用是由PCI規格預先定義的。這區域被稱為裝置的組態表頭區域(或表頭空間(Header Space))。規格目前定義了三種表頭格式。
Header Type One 為 PCI to PCI 橋接器定義的。
Header Type Two 為 PCI to CardBus 橋接器定義的。在PC Card規格有完整的定義。
Header Type Zero 是給所有除了 PCI to PCI 與 CardBus橋接器以外的裝置使用的
Header Type Zero 在表頭內的佔存器可用通用的方式來確認裝置、控制其PCI功能、以及偵測其狀態。裝置組態空間的其他48個dword的使用是裝置特定的。64(PCI device)=16(header)+48(for device)。
強制實作的表頭暫存器
用來識別裝置驅動程式的暫存器
- OS使用下列這些強制暫存器的組合來決定載入哪一個裝置的驅動程式:
- 製造商識別碼(Vendor ID)
- 裝置識別碼(Device ID)
- 版本識別碼(Revision ID)
- 類別碼(Class Code)
- 子系統製造商識別碼(SubSystem Vendor ID)
- 子系統識別碼(SubSystem ID)
裝置識別碼(Device ID)暫存器
永遠強制的,這個16位元值由裝置製造商所指派,用來是別裝置的型態。裝置識別碼與製造商識別碼一起,可能再加上版本識別碼,可用來找出此裝置的裝置特定驅動程式。版本識別碼(Revision ID)暫存器
永遠強制的。這個8位元的值由裝置製造商所指派,用來識別裝置的版本號碼。假如製造商提供版本特定的驅動程式,這可以確保OS載入正確的驅動程式。類別碼(Class Code)暫存器
它是一個24位元、唯讀的暫存器,被分成三個欄位:基本類別(Base Class)、子類別(Sub Class)、及程式介面(Programming Interface)。用來確認裝置的基本功能,及一個更特定的裝置子類別,以及在某些情況下,一個暫存器特定的程式介面。- 較高的位元組定義功能的基本類別
- 中間的位元組定義在基本類別裡的子類別
- 較低的位元組定義程式介面
ex: class code: 03h 是顯示控制器
類別碼3:顯示控制器
00h,00h:與VGA相容的控制器,回應記憶體位址000A0000h到000BFFFFh(Video Frame Buffer,視訊畫面緩衝區),以及IO位址03B0h到03BBh,即03C0h到03DFh,還有這些位址的所有別名(alias)。
00h,01h:與8514相容的控制器。
01h,00h:XGA控制器。
02h,00h:3D控制器。
80h,00h:其他顯示控制器。
指令暫存器
永遠強制的。此暫存器提供基本裝置回應及/或進行PCI存取能力的控制。設計者只能實作對此裝置有意義的位元。EX:具有IO暫存器及,但沒有記憶體的裝置需要位元0,但不需要位元1。[0]:IO空間(IO space)。當此位元被設為1時,裝置的IO位址解碼器會回應PCI IO存取。
[1]:記憶體空間(Memory Space)。當此位元被設定為1時,裝置會回應PCI記憶體存取。
[5]:VGA調色盤監控(VGA Palette Snoop)。當設定為1時。此位元指示其VGA相容的裝置去監管對VGA Color Palette(調色盤)暫存器的IO寫入。
狀態暫存器
永遠強制的。狀態暫存器將功能的狀態當作一個PCI實體來追蹤。功能必須實作與功能相關的位元。基底位址暫存器(Base Address Register, BAR)
對於實作記憶體與/或IO解碼器的裝置來說是必要的。事實上,所有的裝置都實作若干的記憶體,及/或裝置特定的暫存器集,以便控制裝置。EX:
- 平行埠的狀態、指令及資料暫存器可以放在IO或記憶體映射IO空間中。
- 網路介面的控制暫存器(指令、狀態等等)可以放在IO或記憶體映射IO空間中。
- 網路介面也可以併入一個映射到系統記憶體空間的RAM記憶體緩衝器。
- 此外,內含裝置BIOS與中斷服務常式的裝置ROM可以放在裝置裡面。
BAR位於組態表頭空間的dword4到dword9,它是用來實作一個功能的可程式記憶體及/或IO解碼器。每一個暫存器為32位元寬(或64位元寬)。位元0是唯讀的位元,並指示了它是一個記憶體或是IO解碼器。
- 位元0=0,此暫存器是一個記憶體位址解碼器。
- 位元0=1,此暫存器是一個IO位址解碼器。
在PC環境裡,IO空間貝密集的佈植,而且以後只會越來越多。為了這個因素,並因為某些處理器只能進行記憶體交易,所以規格強烈建議,裝置設計者址提供把裝置暫存器映射到記憶體空間的記憶體基底位址暫存器(Base Address Register)。並可以選擇引進一個可以將它映射到IO空間的IO基底位址暫存器(IO Base Address Register)但是不建議這麼做。
這給予組態軟體將裝置暫存器集映射到記憶體空間,以及若提供IO基底位址暫存器,也能映射到IO空間的彈性。假如兩者皆被實作,則與裝置相關的裝置驅動程式可以選擇是透過記憶體或IO和裝置的暫存器集通訊。
基底位址欄位
對於32位元記憶體解碼器來說,此欄位是由位元[31:4]組成,而64位元記憶體解碼器則是位元[63:4]。它是用來:- 決定與此解碼器相關的記憶體大小,並
- 指定解碼器的起始(即基底)位址
IO基底位址暫存器
- 如何探測暫存器,已決定它是否存在。
- 如何決定與解碼器相關的IO暫存器集大小,並因此決定必須指定給它IO空間大小,以及
- 如何指定解碼器的基底位址
- IO區塊所需的大小,以及
- 設定它的起始位址。
與PC相容的IO解碼器
當裝置是特別給與PC相容的x86機器使用(因為Intel x86處理器不能產生超過64KB的IO位址)時,IO BAR較高的16位元可以用硬體接線方式設定為0。不過,裝置仍必須進行完整32位元IO位址解碼。傳統IO解碼器
傳統與PC相容的裝置像是,VGA及IDE控制器經常被預期在固定的傳統IO範圍內。這樣的裝置佈用實作基底位址暫存器。取而代之的是,組態軟體透過它們個別的類別碼,將它們視為傳統裝置,然後藉著設定在指令暫存器裡的IO空間位元為1,致能它們的IO解碼器。
區塊大小的決定與位址範圍的指定
如何運作
組態程式必須探測在功能每一個可能的基底位址暫存器,以決定:- 是否實作基底位址暫存器?
- 它是一個記憶體,還是IO位址解碼器?
- 假如它是記憶體解碼器的話,是32位元還是64位元的基底位址暫存器呢?
- 假如它是記憶體解碼器的話,與此暫存器相關的記憶體是可預讀的還是不可以預讀的?
- 它需要多少記憶體或位址空間,並且是以什麼單位來排列?
IO範例
將FFFFFFFFh寫入功能在組態dword位址05d的基底位址暫存器裡,然後再讀取它,所得的值為FFFFFF01h。位元0等於1表示這是一個IO位址解碼器。從位元2開始向上掃描,找到位元8是第一個被成功地更改成1的位元。此位元的二進位權值為256,表示此IO位址解碼器正在請求256個位元組的IO空間。如果先不透過寫入的方式,先讀取BAR的LSB的低4位元(read only, 唯讀),[0]可以知道此BAR是實作成IO解碼器或是記憶體空間,[2:1]是記憶體的時候,決定是多少位元的解碼器(00:32位元解碼器,01:在低於1MB的位置,10:64位元解碼器)。
沒有留言:
張貼留言