2017年11月29日 星期三

PCI裝置掃描



PCI裝置有提供IO和MMIO的方式可以存取,但是在資源還沒有分配的時候,還是只能透過IO進行讀寫。

要從IO去存取PCI BUS上的裝置,需要透過PCI 的兩個 IO port,address port(0xcf8) and data port(0xcfc)。在address port 的位置寫入要存取的PFA(PCI function address),即可對目標的暫存器進行讀寫。


PFA由PCI裝置的BUS[23:16]、DEVICE[15:11]、FUNCTION[10:8]和REG offset[7:2]組成。[31]固定填1。

根據位元數決定最大支援多少BUS,或裝置。

Bit[31]: It is an enable flag for determining when accesses to CONFIG_DATA are to be translated to configuration transactions on the PCI bus.
Bit[30:24]: Reserved
Bit[23:16]: Bits 23 through 16 choose a specific PCI bus in the system.
Bit[15:11]: Bits 15 through 11 choose a specific device on the bus.
Bit[10:8]: Bits 10 through 8 choose a specific function in a device.
Bit[7:2]: Bits 7 through 2 choose a DWORD in the device's Configuration Space.
Bit[1:0]: Bits 1 and 0 are read-only and must return 0's when read.


31302928272625242322212019181716151413121110 9 8 7 6 5 4 3 2  1 0
 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0 0 0 0 0 1 1 1 1 0
 0

在PCI SCAN後要完成 Configuration setting 和 Linking list of PCI device的建立。在這個LIST裡面,每個NODE都是一個PCI device,SCAN的過程中就要去設置好PCI裝置的組態

2017年11月27日 星期一

PCI裝置-VGA

Register Overview

  1. IO空間:分成三塊,PCI介面、VGA空間、擴充IO空間
  2. 記憶體空間:分成三塊,Base 0是留給繪圖緩衝區的4M Bytes大小的記憶體、Base 1是保留給MMIO的128 K Bytes大小的記憶體、Base 2是保留給IO空間的128K Bytes大小的記憶體。
    • MB0開始於PCI組態表頭中偏移量10h的位址,4MB。
    • MB1開始於PCI組態表頭中偏移量14h的位址,128KB。
    • MB2開始於PCI組態表頭中偏移量18h的位址,128KB。
  3. 映射記憶體空間
    • 0~128k-1
    • 0x0000~0x00FF
    • 0x0500~0x05FF
PCI Controller

Device and Vendor ID Reg
Command and Status Reg
Class and Revision Reg
Miscellaneous Reg
BAR0
BAR1
BAR2
subsystem ID Reg
Expansion ROM BAR
capability Reg
Interrupt Reg
PCI PM capability Reg


2017年11月26日 星期日

PCI-to-PCI 橋接器

PCI to PCI 的 Class Code

強制要實作的。在DWORD 2的byte 0, byte 1, byte 2。
對PCI-to-PCI 橋接器而言,類別碼為06h,子類別04h,
程式介面:

  • 00h:正常的PCI-to-PCI橋接器
  • 01h:除了正常的PCI-to-PCI橋接器操作以外,還可以在橋接器主要端進行相減解碼的PCI-to-PCI橋接器。
還沒有組態橋接器之前,PCI Scan只會掃到BUS 0上看得到的PCI device與PCI橋接器。
EX: host/PCI橋接器(0600)、PCI/ISA橋接器(0601)、PCI-to-PCI橋接器(0604)。


可延展的匯流排架構

只含有一個PCI匯流排的機器受到很明顯的限制,EX:
  • 假如有太多電力負載被放在同一條PCI匯流排上,會無法正常運作。
  • 安裝在特定PCI匯流排上的裝置可能無法好好的共存。某些Master裝置可能需要大量匯流排時間,會降子系統效能。
  • 一條PCI匯流排只支援有限數量的PCI擴充連接器。

每一個PCI-to-PCI橋接器連接兩條PCI匯流排,被稱為它的主匯流排(Primary)與次(Secondary)匯流排。

  • Downstream(下游):當交易被起始,透過一或多個PCI-to-PCI橋接器被傳遞,並流向遠離主處理器的方向時,它就被稱為下游。
  • Upstream(上游):當交易被起始,透過一或多個PCI-to-PCI橋接器被傳遞,並流向主處理器時,它就被稱為上游。
  • 主匯流排(Primary bus):在橋接器的上游端之PCI匯流排。
  • 次匯流排(Secondary bus):在橋接器的下游端之PCI匯流排。[write to video memory]
  • 附屬匯流排(Subordinate bus):在橋接器的下游端號碼最大的PCI匯流排。


主匯流排號碼,被軟體以橋接器上游的PCI匯流排號碼初始化。由於host/PCI橋接器只會連接一個PCI匯流排,所以只有實作一個匯流排號碼暫存器。即host/PCI橋接器不需要實作次匯流排號碼暫存器。

次匯流排號碼,被軟體以橋接器下游的PCI匯流排號碼(換言之,第幾個BUS的編號)初始化。pci scan往下游找的時候,找到新的橋接器開始依序填值在次匯流排號碼中,新的橋接器代表下面又連了一個新的匯流排。每找到一個新的次匯流排,就往上回填附屬匯流排號碼。

匯流排號碼暫存器

剛開始作PCI SCAN的時候,要先掃出所有PCI裝置,掃到橋接器的時候要開始記錄號碼,並填入匯流排號碼。否則橋接器下游的裝置會看不到,往下游繼續找直到掃出所有裝置。

每一個PCItoPCI橋接器必須實作三個強制性的匯流排暫存器。它們都是可讀寫的,並且在重置時會被清除為0。在組態過程中,組態軟體會初始化這三暫存器,來指定匯流排號碼。這些暫存器是:

  • 主匯流排號碼暫存器(Primary Bus Number register)
  • 次匯流排號碼暫存器(Secondary Bus Number register)
  • 附屬匯流排號碼暫存器(Subordinate Bus Number register)

在主要端的Type 1組態讀取與寫入,它會被當作Type 0組態存取(假如target是在橋接器的次匯流排上)或是Type 1組態存取(假如Target是在附屬屬於橋接器次匯流排的匯流排上)。
在主要或次要端上接收到Type 1組態寫入,會被轉換成在指定的target匯流排上的特殊週期。

顯示器組態

可能有兩個顯示配接卡存在
假設一個平台安裝了兩張顯示配接卡,但是只有一個顯示器。其中一張配接卡是與VGA相容的ˊ,另一張是Advanced Graphics Adapter(進階圖形配接卡),或GFX。

兩張配接卡中都有DAC,用來驅動CRT,DAC含有一組調色盤暫存器集(color palette register set)。當每一個點(dot/pixel)被寫到顯示幕上時,圖形配接卡會提供資料給DAC。

兩個配接卡的識別
VGA配接卡的類別碼為03h,其子類別碼為00h,GFX配接卡的類別碼為03h,其子類別碼為08h。

BUS上可能的CASE

配接卡可能在相同或不同的匯流排上

對調色盤暫存器的IO寫入都必須同時更新在VGA和GFX這兩個配接卡DAC裡的調色盤暫存器。這兩個顯示配接卡會位於機器的何處有許多不同可能。

假如它們是在相同的PCI匯流排上,且IO寫入進行對調色盤暫存器寫入,除非有某件事情可以阻止它,否則在IO讀取或寫入在調色盤暫存器上進行時,兩個裝置都可以驅動DEVSEL#到低態來宣告交易。 >>>> 這會違反協定的現象。

假如配接卡在不同匯流排上,則是兩匯流排間的橋接器必須被程式規劃,以確保兩個配接卡都看到IO寫入交易,但是只有一個會當作交易的target來主動參與。

配接卡在不同BUS上的解決方案

  • 在顯示配接卡的指令暫存器裡的VGA調色盤監控(Palette Snoop)位元。
  • 在橋接器的橋接器控制暫存器裡的VGA致能位元。
  • 在橋接器的指令暫存器裡的VGA調色盤監控位元。

配接卡與橋接器的偵測與組態

用來偵測及設定VGA相容的控制器與非VGA,即GFX控制器的程序如下:
  1. 確認要在啟動程序中使用的VGA顯示裝置。這是藉著先掃描標準擴充匯流排(EX:ISA、EISA)的方式達成的。假如在擴充匯流排上找到顯示裝置的話,該顯示器會在啟動程序中使用,而且初始化程序完成。不用進行下列的步驟。假如在擴充匯流排上找不到VGA裝置,則從具有最大匯流排號碼的匯流排開始,掃描PCI匯流排。假如在PCI匯流排上找到的話,則儲存匯流排號碼,給在初始化程序的其餘步驟使用。
  2. 設定在裝置的指令暫存器裡的IO空間與記憶體空間致能位元,讓它可以回應VGA存取。
  3. 從啟動顯示裝置所在的PCI匯流排開始,掃描PCI匯流排階層的上游(到匯流排0為止)。在每一個偵測到的PCI-to-PCI橋接器裡,設定在其橋接器控制暫存器裡的VGA致能位元。
  4. 從啟動顯示器裝置所在的PCI匯流排開始,掃描PCI匯流排下游(所有附屬於此匯流排的匯流排),尋找GFX。當找到第一個GFX的案例時,中止掃描。設定GFX裝置指令暫存器的IO空間與VGA調色盤監控致能位元。
  5. 從GFX所在的匯流排往上游方向掃描回去,直到啟動顯示器所在的匯流排。在每一個所遇到的PCI-to-PCI橋接器裡,設定橋接器指令暫存器的VGA調色盤監控致能位元。
  6. 最後,設定在啟動顯示裝置的指令暫存器內的VGA調色盤監控致能位元。
PCI-to-PCI橋接器規格提供了兩個虛擬碼(pseudo-code),它們可以用來實作上述步驟的程序。

  • DispalyInit()。這是最頂層的程序。沒有輸入參數,並且它呼叫GFXScanR程序。
  • GFXScanR(BusNum)。此程序掃描附屬於啟動顯示器所在之匯流排的匯流排,以尋找第一個GFX裝置案例(Instance)







2017年11月24日 星期五

ROM之於PCI

ROM的目的:裝置可以在啟動程序中被使用

為了啟動OS到記憶體中,系統需要三個裝置:

  • 用來從其中載入OS的大量儲存媒體。這有時也稱為IPL(Initial Program Load,初始程式載入)裝置,通常是一個IDE或SCSI硬碟。
  • 在啟動過程中,用來顯示進行中訊息的顯示配接卡。通稱為輸出裝置。
  • 在啟動過程中,用來讓使用者與機器交談的鍵盤。通稱為輸入裝置。
OS必須同時找到這三個裝置,同時必須找到與每一個裝置有關的裝置驅動程式。這個階段還未從磁碟機載入任何可載入的裝置驅動程式到記憶體中。這是ROM存在的主因。它包含允許裝置在啟動過程中被使用的裝置驅動程式。

ROM偵測

當組態軟體正在組態PCI功能時,它會檢查設計者是否實作擴充ROM基底位址暫存器的方式,決定是否有功能特定的ROM存在。

程式執行裝置下列方式,確認裝置是否存在:

  • 指定一"基底位址"給暫存器的基底位址欄位,
  • 致能其解碼器(以設定暫存器的位元0為1的方式),
  • 設定功能指令暫存器的記憶體空間位元,
  • 然後嘗試去讀取ROM的前兩個位置。

假如前兩個位置包含ROM簽名,AA55h的話,則ROM存在。


ROM Shadowing的必要

  • PCI規格要求裝置ROM程式碼不能在原地執行(即在ROM裡面)。它必須被複製到主記憶體裡面。這稱為"Shadowing"ROM程式碼。這要求的存在有兩個原因:

ROM的存取時間通常很慢,每次讀取ROM程式碼來執行都會造成極差的效能。

  • 一旦在ROM裡裝置驅動程式的初始化程式碼部分被執行後,它就可以被丟棄,並且在主記憶體裡的程式碼影像(code image)可以被縮短到只剩執行期操作所需要的部分。配置給儲存程式碼的初始化部分之主記憶體可以被釋放,使得主記憶體的使用更有效率。
一旦發現裝置ROM存在,組態軟體必須複製程式碼影像到主記憶體中,然後關閉(Disable)ROM位址解碼器。在非PC環境裡,儲存程式碼影像副本的記憶體區域可以在4GB空間的任何一處。該環境所用的規格可以定義一個特定的區域給程式碼影像。

在PC環境裡,ROM程式碼影像必須被複製到主記憶體裡與裝置ROM在歷史上有相關聯的位址範圍內:000C0000h 到 000DFFFFh。假如類別碼表示這是一個VGA的裝置ROM,則其程式碼必須被複製到000C0000h位置最開始的地方。


BIOS呼叫不同匯流排環境的匯流排列舉器(Bus Enumerator)

一個機器架構裡面可以含有許多種不同的裝置環境。例如PCI、CardBus、EISA、Plug-and-Play、ISA等等。用來存取每一個與這些不同裝置種類相關的組態暫存器的方法彼此間有很大的差異。以外,其組態暫存器的配置和格式也有相當大的差異。

BIOS會含有每一個環境所需的一個單獨的、匯流排特定的程式。這程式經常被稱為匯流排列舉器(Bus Enumerator)。匯流排列舉器知道:

  • 如何存取特定型態裝置(例如:PCI裝置)裡的組態暫存器。
  • 如何找到在這環境裡的裝置。例如,在PCI環境裡,程式執行裝置讀取PCI功能製造商識別碼暫存器裡的製造商識別碼。任何非FFFFh的值代表有效的識別碼,而FFFFh代表在目前的定址的位置上沒有任何裝置存在。
  • 如何探測裝置的組態暫存器,以便找到裝置的資源需求。
  • 如何配置已選定的資源給裝置。

系統BIOS必須呼叫每一個所支援之平台匯流排環境的匯流排列舉器。每當特定的列舉器被呼叫時,它會找到所有其target環境裡的裝置,找到每一個裝置所需的資源,並且將不互相衝突的資源配置給每一個裝置。不過,它不會致能這些裝置。列舉器在記憶體內建立一個資料結構,列出它所找到屬於其形態的所有裝置。然後,它將指向該資料結構開頭的指標傳回給系統BIOS。

BIOS選擇啟動裝置並找到它們的驅動程式

接著,系統BIOS掃描資料結構,找出輸入裝置、輸出裝置、以及一個IPL裝置,以便在啟動OS到記憶體時使用。為了在啟動程序裡,使用這些裝置,因此需要有每一個裝置的裝置驅動程式。驅動程式可以內嵌在BIOS本身裡面,或是在所找到的每一個裝置的ROM裡面。

對這三個啟動裝置的每一個說,BIOS接下來會:
  • 呼叫在裝置驅動程式裡的初始化程式碼。接著,初始化程式碼完成使用裝置的準備
  • 然後,BIOS設定在組態指令暫存器裡適當的位元(EX記憶體空間;IO空間;Bus Master),致能此裝置,並讓它上線。

BIOS啟動隨插即用OS並將指標傳給它

然後,系統BIOS使用這三個裝置,啟動OS到記憶體內,並且將控制權傳給OS。它同時把指向這資料結構清單開頭的指標傳給OS,這資料結構用來確認所有OS必須操作的裝置。
OS找到並載入驅動程式,然後呼叫每一個裝置的初始化程式碼(Init Code)
請注意,Init Code(初始化程式碼)代表驅動程式的初始化部分。其次,OS找出每一個裝置在磁碟上的驅動程式,然後將它們一個接著一個地載入到記憶體內。每當它載入一個驅動程式時,它就會呼叫其初始化程式碼進入點,而驅動程式會完成裝置特定的設定,並且讓裝置上線。如此,機器便完成啟動並開始運作,從這一刻起,由OS來管理系統裝置。

2017年11月23日 星期四

關於 PCI Configuration 的認識

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)。