一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

第六章 PCI

 WUCANADA 2013-07-01

第六章 PCI


外圍設(shè)備互連(PCI)是一種將系統(tǒng)中外部設(shè)備以結(jié)構(gòu)化與可控制方式連接到起來的總線標準,包括系統(tǒng)部件連接的電氣特性及行為。本章將詳細討論Linux核心對系統(tǒng)中的PCI總線與設(shè)備的初始化過程。


圖6.1 一個基于PCI的系統(tǒng)示意圖

圖6.1是一個基于PCI的系統(tǒng)示意圖。PCI總線和PCI-PCI橋接器在連接系統(tǒng)中設(shè)備到上起關(guān)鍵作用,在這個系統(tǒng)中CPU和視頻設(shè)備 被連到PCI bus 0上,它是系統(tǒng)中的主干PCI總線。而PCI-PCI橋接器這個特殊PCI設(shè)備將主干總線PCI bus 0與下級總線PCI bus 1連接到一起。PCI標準術(shù)語中,PCI bus 1是PCI-PCI橋接器的downstream而PCI bus 0是此橋接器的up-stream。SCSI和以太網(wǎng)設(shè)備通過二級PCI總線連接到這個系統(tǒng)中。而在物理實現(xiàn)上,橋接器和二級PCI總線被集成到一塊 PCI卡上。而PCI-ISA橋接器用來支持古老的ISA設(shè)備,圖中有一個高級I/O控制芯片來控制鍵盤、鼠標及軟盤設(shè)備。

6.1  PCI地址空間

CPU和PCI設(shè)備需要存取在它們之間共享的內(nèi)存空間。這塊內(nèi)存區(qū)域被設(shè)備驅(qū)動用來控制PCI設(shè)備并在CPU與PCI設(shè)備之間傳遞信息。最典型的共享內(nèi)存包括設(shè)備的控制與狀態(tài)寄存器。這些寄存器用來控制設(shè)備并讀取其 信息。例如PCI SCSI設(shè)備驅(qū)動可以通過讀取其狀態(tài)寄存器,找出已準備好將一塊數(shù)據(jù)寫入SCSI磁盤的SCSI設(shè)備。同時還可以在設(shè)備加電后,通過對控制寄存器寫入信息來啟動設(shè)備。

CPU的系統(tǒng)內(nèi)存可以被用作這種共享內(nèi)存,但是如果采用這種方式,則每次PCI設(shè)備訪問此內(nèi)存塊時,CPU將被迫停止工作以等待PCI設(shè)備完成此操作。這 種方式將共享內(nèi)存限制成每次只允許一個系統(tǒng)設(shè)備訪問。該策略會大大降低系統(tǒng)性能。但如果允許系統(tǒng)外設(shè)不受限制地訪問主存也不是好辦法。它的危險之處在于一 個有惡意行為的設(shè)備將使整個系統(tǒng)置于不穩(wěn)定狀態(tài)。

外設(shè)有其自身的內(nèi)存空間。CPU可以自由存取此空間,但設(shè)備對系統(tǒng)主存的訪問將處于DMA(直接內(nèi)存訪問)通道的嚴格控制下。ISA設(shè)備需要存取兩個地址空間:ISA I/O(輸入輸出)和ISA內(nèi)存。而PCI設(shè)備需要訪問三種地址空間:PCI I/O、PCI內(nèi)存和PCI配置空間。CPU則可以訪問所有這些地址空間。PCI I/O和 PCI內(nèi)存由設(shè)備驅(qū)動程序使用而PCI配置空間被Linux 核心中的PCI初始化代碼使用。

Alpha AXP處理器并不能象訪問系統(tǒng)地址空間那樣隨意訪問這些地址空間,它只能通過輔助芯片組來存取這些 地址空間,如PCI配置空間。Alpha AXP處理器使用稀疏地址映射策略來從系統(tǒng)巨大的虛擬內(nèi)存中"竊取"一部分并將其映射到PCI地址空間。

6.2  PCI 配置頭


圖6.2 PCI配置頭

系統(tǒng)中每個PCI設(shè)備,包括PCI-PCI橋接器在內(nèi),都有一個配置數(shù)據(jù)結(jié)構(gòu),它通常位于PCI配置地址空間中。PCI配置頭允許系統(tǒng)來標 識與控制設(shè)備。配置頭在PCI配置空間的位置取決于系統(tǒng)中PCI設(shè)備的拓撲結(jié)構(gòu)。例如將一個PCI視頻卡插入不同的PCI槽,其配置頭位置會變化。但對系 統(tǒng)沒什么影響,系統(tǒng)將找到每個PCI設(shè)備與橋接器并使用它們配置頭中的信息來配置其寄存器。

典型的辦法是用PCI槽相對主板的位置來決定其PCI配置頭在配置空間中的偏移。比如主板中的第一個PCI槽的PCI配置頭位于配置空間偏移0處,而第二 個則位于偏移256處(所有PCI配置頭長度都相等,為256字節(jié)),其它槽可以由此類推。系統(tǒng)還將提供一種硬件相關(guān)機制以便PCI設(shè)置代碼能正確的辨認 出對應PCI總線上所有存在的設(shè)備的PCI配置頭。通過PCI配置頭中的某些域來判斷哪些設(shè)備存在及哪些設(shè)備不存在(這個域叫廠商標志域: Vendor Identification field)。對空PCI槽中這個域的讀操作將得到一個值為0xFFFFFFFF的錯誤信息。

圖6.2給出了256字節(jié)PCI配置頭的結(jié)構(gòu),它包含以下域:

廠商標識(Vendor Identification)
用來唯一標識PCI設(shè)備生產(chǎn)廠家的數(shù)值。Digital的PCI廠商標識為0x1011而Intel的為0x8086。
設(shè)備標識(Device Identification)
用來唯一標識設(shè)備的數(shù)值。Digital 21141快速以太設(shè)備的設(shè)備標識為0x0009。
狀態(tài)(Status)
此域提供PCI標準定義中此設(shè)備的狀態(tài)信息。
命令(Command)
通過對此域的寫可以控制此設(shè)備,如允許設(shè)備訪問PCI I/O內(nèi)存。
分類代碼(Class Code)
此域標識本設(shè)備的類型。對于每種類型的視頻,SCSI等設(shè)備都有標準的分類代碼。如SCSI設(shè)備分類代碼為0x0100。
基地址寄存器(Base Address Registers)
這些寄存器用來決定和分配此設(shè)備可以使用的PCI I/O與PCI內(nèi)存空間的類型,數(shù)量及位置。
中斷引腳(Interrupt Pin)
PCI卡上的四個物理引腳可以將中斷信號從插卡上帶到PCI總線上。這四個引腳標準的標記分別為A、B、C及D。中斷引腳域描敘此PCI設(shè)備使用的引腳 號。通常特定設(shè)備都是采用硬連接方式。這也是系統(tǒng)啟動時,設(shè)備總使用相同中斷引腳的原因。中斷處理子系統(tǒng)用它來管理來自該設(shè)備的中斷。
中斷連線(Interrupt Line)
本設(shè)備配置頭中的中斷連線域用來在PCI初始化代碼、設(shè)備驅(qū)動以及Linux中斷處理子系統(tǒng)間傳遞中斷處理過程。雖然本域中記錄的這個數(shù)值對于設(shè)備驅(qū)動毫無意義。但是它可以將中斷處理過程從PCI卡上正確路由到Linux操作系統(tǒng)中相應的設(shè)備驅(qū)動中斷處理代碼中。在interrupt一章中將詳細描敘Linux中斷處理過程。

6.3  PCI I/O和PCI內(nèi)存地址

這兩個地址空間用來實現(xiàn)PCI設(shè)備和Linux核心中設(shè)備驅(qū)動程序之間的通訊。例如DEC21141快速以太網(wǎng)設(shè)備的內(nèi)部寄存器被映射到PIC I/O空間上時,其對應的Linux設(shè)備驅(qū)動可以通過對這些寄存器的讀寫來控制此設(shè)備。PCI視頻卡通常使用大量的PCI內(nèi)存空間來存儲視頻信息。

在PCI系統(tǒng)建立并通過用PCI配置頭中的命令域來打開這些地址空間前,系統(tǒng)決不允許對它們進行存取。值得注意的是只有PCI配置代碼讀取和寫入PCI配置空間,Linux設(shè)備驅(qū)動只讀寫PCI I/O和PCI內(nèi)存地址。

6.4  PCI-ISA 橋接器

這種橋接器通過將PCI I/O和PCI內(nèi)存空間的存取轉(zhuǎn)換成對ISA I/O和ISA內(nèi)存的存取來支持古老的ISA設(shè)備。市場上許多主板中同時包含幾個ISA總線槽和PCI槽。但今后對ISA設(shè)備的向后兼容支持將逐漸減弱,最終主板上只會有PCI槽。早期的Intel 8080 PC就將ISA設(shè)備的ISA地址空間固定了下來。即使在價值5000美圓的Alpha AXP 系統(tǒng)中其ISA軟盤控制器地址也和最早IBM PC上的相同。PCI標準將PCI I/O和PCI內(nèi)存的低端部分保留給系統(tǒng)中的ISA外設(shè),另外還使用PCI-ISA橋接器實現(xiàn)從PCI內(nèi)存訪問到ISA內(nèi)存訪問的轉(zhuǎn)換。

6.5  PCI-PCI 橋接器

PCI-PCI橋接器是一種將系統(tǒng)中所有PCI總線連接起來的特殊PCI設(shè)備。在簡單系統(tǒng)中只存在一條PCI總線,由于受電氣特性的限制,它所連接的 PCI設(shè)備個數(shù)有限。引入PCI-PCI橋接器后系統(tǒng)可以使用更多的PCI設(shè)備。對于高性能服務(wù)器這是非常重要的。Linux提供了對PCI-PCI橋接 器的全面支持。

6.5.1  PCI-PCI橋接器:PCI I/O和PCI 內(nèi)存窗口

PCI-PCI橋接器將PCI I/O和PCI內(nèi)存讀寫請求中的一個子集向下傳送。例如在圖6.1中,如果來自PCI 總線0請求是對SCSI或以太設(shè)備所擁有的PCI I/O或PCI內(nèi)存的讀寫,則此PCI-PCI橋接器將只需把請求從總線0傳遞到PCI總線1上;所有其它PCI I/O和內(nèi)存地址都將被它忽略。這個過濾使得這些地址信息不會在整個系統(tǒng)中擴散。為了實現(xiàn)這點,PCI-PCI橋接器必須編程為有某個PCI I/O及PCI內(nèi)存基址和上限,只有在這個地址范圍內(nèi)的PCI地址訪問才能從主干總線傳遞到二級總線。一旦系統(tǒng)中的PCI-PCI橋接器被設(shè)置成這樣,則只要當Linux設(shè)備驅(qū)動程序通過這個窗口訪問PCI I/O和PCI內(nèi)存空間時,此PCI-PCI橋接器就將變得透明。這樣也給Linux PCI設(shè)備驅(qū)動編寫者提供了方便。我們在稍后的討論中將看到Linux對PCI-PCI橋接器非常巧妙的配置。

6.5.2  PCI-PCI橋接器:PCI配置循環(huán)及PCI總線編號方式


圖6.3 0類型PCI配置循環(huán)


圖6.4 1類型PCI配置循環(huán)

為了讓CPU上運行的PCI初始化代碼能訪問位于分支PCI總線上的設(shè)備,必須為橋接器提供某種機制以便它可以決定是否將配置循環(huán)從主干接 口傳遞到其二級接口。循環(huán)是出現(xiàn)在PCI總線上的一個地址。PCI 標準定義了兩種PCI配置尋址格式;類型0和類型1;它們分別如圖6.3及6.4所示。類型0 PCI配置循環(huán)不包含總線序號,同時在此PCI總線上對應于這個PCI配置地址的所有PCI設(shè)備都會來對它們進行解釋。類型0 配置循環(huán)的11 位到31位用來進行PCI設(shè)備選擇。有種設(shè)計方式是讓每位代表系統(tǒng)中一個不同的設(shè)備。這時11位對應PCI槽0中的PCI設(shè)備而12位標識槽1中的設(shè)備等 等,如此類推。另外一種方式是直接將設(shè)備的槽號寫入到位31到11中。系統(tǒng)使用哪種機制依賴于系統(tǒng)PCI內(nèi)存控制器。

類型1 PCI配置循環(huán)包含一個PCI總線序號,同時這種配置循環(huán)將被除橋接器外的所有PCI設(shè)備所忽略。所有發(fā)現(xiàn)類型1 配置循環(huán)的PCI-PCI橋接器把它們看到的地址傳遞到各自的下級PCI總線。至于PCI-PCI橋接器是否忽略類型1 配置循環(huán)或?qū)⑵鋫鬟f到PCI總線則依賴于PCI-PCI橋接器的配置方式。每個PCI-PCI橋接器都擁有一個主干總線接口序號以及一個二級總線接口序 號。主干總線是那個離CPU最近的PCI總線而二級總線是離它稍遠的PCI總線。任何PCI-PCI橋接器還包含一個從屬總線序號,這是所有二級總線接口 所橋接的PCI總線中序號最大的那個?;蛘哒f這個從屬總線序號是PCI-PCI橋接器向下連接中PCI總線的最大序號。當PCI-PCI橋接器看到類型1 PCI配置循環(huán)時它將進行如下操作:

  • 如果此總線序號不在橋接器的二級總線序號和從屬總線序號之間則忽略掉它。

  • 如果此總線序號與橋接器的二級總線序號相同則將其轉(zhuǎn)換成類型0 配置命令。

  • 如果此總線序號位于橋接器的二級總線序號與從屬總線序號之間則將它不作改變的傳遞到二級總線接口中。

所以如果想尋址PCI-PCI配置例4中總線3上的設(shè)備1,我們繼續(xù)從CPU中產(chǎn)生一個類型1 配置命令。橋接器1將其傳遞給總線1。橋接器2雖然忽略它但會將其轉(zhuǎn)換成一個類型0 配置命令并送到總線3上,在那里設(shè)備1將作出相應反應。

PCI配置中總線序號由操作系統(tǒng)來分配。但是序號分配策略必須遵循對系統(tǒng)中所有PCI-PCI橋接器都正確的描敘:

“位于PCI-PCI橋接器后所有的PCI總線必須位于二級總線序號和從屬總線序號之間”。

如果這個規(guī)則被打破,則PCI-PCI橋接器將不能正確的傳遞與轉(zhuǎn)換類型1 PCI配置循環(huán),同時系統(tǒng)將找不到或者不能正確地初始化系統(tǒng)中的PCI設(shè)備。為了滿足這個序號分配策略,Linux以特殊的順序配置這些特殊的設(shè)備。PCI-PCI總線序號分配一節(jié)詳細描敘了Linux的PCI橋接器與總線序號分配策略。

6.6  Linux PCI 初始化過程

Linux中的PCI初始化代碼邏輯上可分成三個部分:

PCI 設(shè)備驅(qū)動
這個偽設(shè)備驅(qū)動程序?qū)目偩€0開始搜索PCI系統(tǒng)并定位系統(tǒng)中所有的PCI設(shè)備與橋接器。它將建立起一個描敘系統(tǒng)拓撲結(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)鏈表。另外它還為所有的橋接器進行編號。
 
PCI BIOS


這個軟件層提供了在bib-pci-bios定義中描敘的服務(wù)。即使Alpha AXP沒有BIOS服務(wù),Linux核心也將為它提供具有相同功能的代碼。
 
PCI Fixup
系統(tǒng)相關(guān)補丁代碼將整理PCI初始化最后階段的一些系統(tǒng)相關(guān)事物。

6.6.1  Linux 核心PCI數(shù)據(jù)結(jié)構(gòu)


圖6.5 Linux核心PCI數(shù)據(jù)結(jié)構(gòu)

Linux核心初始化PCI系統(tǒng)時同時也建立了反應系統(tǒng)中真實PCI拓撲的數(shù)據(jù)結(jié)構(gòu)。 圖6.5顯示了圖6.1所標識的PCI示例系統(tǒng)中數(shù)據(jù)結(jié)構(gòu)間關(guān)系。每個PCI設(shè)備(包括PCI-PCI橋接器)用一個pci_dev數(shù)據(jù)結(jié)構(gòu)來描敘。每個 PCI總線用一個pci_bus數(shù)據(jù)結(jié)構(gòu)來描敘。這樣系統(tǒng)中形成了一個PCI總線樹,每棵樹上由一些子PCI設(shè)備組成。由于PCI總線僅能通過PCI- PCI橋接器(除了主干PCI總線0)存取,所以pci_bus結(jié)構(gòu)中包含一個指向PCI-PCI橋接器的指針。這個PCI設(shè)備是PCI總線的父PCI總 線的子設(shè)備。

在圖6.5中沒有顯示出來的是一個指向系統(tǒng)中所有PCI設(shè)備的指針,pci_devices。系統(tǒng)中所有的PCI設(shè)備將其各自的pci_dev數(shù)據(jù)結(jié)構(gòu)加入此隊列中。這個隊列被Linux核心用來迅速查找系統(tǒng)中所有的PCI設(shè)備。

6.6.2  PCI設(shè)備驅(qū)動

PCI設(shè)備驅(qū)動根本不是真正的設(shè)備驅(qū)動,它僅是在系統(tǒng)初始化時由操作系統(tǒng)調(diào)用的一些函數(shù)。PCI初始化代碼將掃描系統(tǒng)中所有的PCI總線以找到系統(tǒng)中所有的PCI設(shè)備(包括PCI-PCI橋接器)。

它通過PCI BIOS代碼來檢查當前PCI總線的每個插槽是否已被占用。如果被占用則它建立一個pci_dev數(shù)據(jù)結(jié)構(gòu)來描敘此設(shè)備并將其連接到已知PCI設(shè)備鏈表中(由pci_devices指向)。

首先PCI初始化代碼掃描PCI總線0。它將試圖讀取對每個PCI槽中可能的PCI設(shè)備廠商標志與設(shè)備標志域。當發(fā)現(xiàn)槽被占用后將建立一個pci_dev 結(jié)構(gòu)來描敘此設(shè)備。所有這些PCI初始化代碼建立的pci_dev結(jié)構(gòu)(包括PCI-PCI橋接器)將被連接到一個單向鏈表pci_devices中。

如果這個PCI設(shè)備是一個PCI-PCI橋接器則建立一個pci_bus結(jié)構(gòu)并將其連接到由pci_root指向的pci_dev結(jié)構(gòu)和pci_bus樹 中。PCI初始化代碼通過類別代碼0x060400來判斷此PCI設(shè)備是否是一個PCI-PCI橋接器。然后Linux 核心代碼將配置此PCI-PCI橋接器下方的PCI設(shè)備。如果有更多的橋接器被找到則進行同樣的配置。顯然這個過程使用了深度優(yōu)先搜索算法;系統(tǒng)中PCI 拓撲將在進行廣度映射前先進行深度優(yōu)先映射。圖6.1中Linux將在配置PCI總線0上的視頻設(shè)備前先配置PCI設(shè)備1上的以太與SCSI設(shè)備。

由于Linux優(yōu)先搜索從屬的PCI總線,它必須處理PCI-PCI橋接器二級總線與從屬總線序號。在下面的pci-pci總線序號分配中將進行詳細討論。

配置PCI-PCI橋接器 - 指定PCI總線序號


圖6.6 配置PCI系統(tǒng):第一部分

為了讓PCI-PCI橋接器可以傳遞PCI I/O、PCI內(nèi)存或PCI配置地址空間,它們需要如下內(nèi)容:

Primary Bus Number:主干總線序號
位于PCI-PCI橋接器上方的總線序號
Secondary Bus Number:二級總線序號
位于PCI-PCI橋接器下方的總線序號
Subordinate Bus Number:從屬總線序號
在橋接器下方可達的最大總線序號
PCI I/O and PCI Memory Windows:PCI I/O與PCI內(nèi)存窗口
對于PCI-PCI橋接器下方所有PCI I/O地址空間與PCI內(nèi)存地址空間的窗口基址和大小。

配置任一PCI-PCI橋接器時我們對此橋接器的從屬總線序號一無所知。不知道是否還有下一級橋接器存在,同時也不知道指派給它們的序號是什么。但可以使 用深度優(yōu)先遍歷算法來對掃描出指定PCI-PCI橋接器連接的每條總線,同時將它們編號。當找到一個PCI-PCI橋接器時,其二級總線被編號并且將臨時 從屬序號0xff指派給它以便對其所有下屬PCI-PCI橋接器進行掃描與指定序號。以上過程看起來十分復雜,下面將提供一個實例以幫助理解。

PCI-PCI 橋接器序號分配:步驟1
考慮圖6.6所顯示的拓撲結(jié)構(gòu),第一個被掃描到的橋接器將是橋1。所以橋1下方的總線將被編號成總線1,同時橋1被設(shè)置為二級總線1且擁有臨時總線序號0xff。這意味著所有PCI總線序號為1或以上的類型1 PCI配置地址將被通過橋1傳遞到PCI總線1上。如果其總線序號為1則此配置循環(huán)將被轉(zhuǎn)換成類型0 配置循環(huán),對于其它序號不作轉(zhuǎn)換。這正是Linux PCI初始化代碼所需要的按序訪問及掃描 PCI總線1。


圖6.7 配置PCI系統(tǒng):第二部分

PCI-PCI 橋接器序號分配:第二步
由于Linux使用深度優(yōu)先算法,初始化代碼將繼續(xù)掃描PCI總線1。在此處它將發(fā)現(xiàn)一個PCI-PCI橋接器2。除此橋接器2外再沒有其它橋接器存在, 因此它被分配給從屬總線序號2,這正好和其二級接口序號相同。圖6.7畫出了此處的PCI-PCI橋接器與總線的編號情況。


圖6.8 配置PCI系統(tǒng):第三部分

PCI-PCI 橋接器序號分配:步驟三
PCI初始化代碼將繼續(xù)掃描總線1并發(fā)現(xiàn)另外一個PCI-PCI橋接器,橋3。橋3的主干總線接口序號被設(shè)置成1,二級總線接口序號為3,同時從屬總線序號為0xff。圖6.8給出了系統(tǒng)現(xiàn)在的配置情況。 帶總線序號1、2或者3的類型1 PCI配置循環(huán)將被發(fā)送到正確的PCI總線。


圖6.9 配置PCI系統(tǒng):第四部分

PCI-PCI 橋接器序號分配:步驟四
Linux開始沿PCI總線3向下掃描PCI-PCI橋接器。PCI總線3上有另外一個PCI-PCI橋接器(橋4), 橋4的主干總線序號被設(shè)置成3,二級總線序號為4。由于它是此分支上最后一個橋接器所以它的從屬總線接口序號為4。初始化代碼將重新從PCI-PCI橋接 器3開始并將其從屬總線序號設(shè)為4。 最后PCI初始化代碼將PCI-PCI橋接器1的從屬總線序號設(shè)置為4。圖6.9給出了最后的總線序號分配情況。

6.6.3  PCI BIOS 函數(shù)

PCI BIOS函數(shù)是一組適用于所有平臺的標準過程。在Intel和Alpha AXP系統(tǒng)上沒有區(qū)別。雖然在CPU控制下可以用它們對所有PCI地址空間進行訪問。但只有Linux核心代碼和設(shè)備驅(qū)動才能使用它們。

 

6.6.4  PCI 補丁代碼

在Alpha AXP平臺上的PCI補丁代碼所作工作量要大于Intel平臺。

基于Intel的系統(tǒng)在系統(tǒng)啟動時就已經(jīng)由系統(tǒng)BIOS完成了PCI系統(tǒng)的配置。Linux只需要完成簡單的映射配置. 非Intel系統(tǒng)將需要更多的配置:

  • 為每個設(shè)備分配PCI I/O及PCI內(nèi)存空間。
  • 為系統(tǒng)中每個PCI-PCI橋接器配置PCI I/O和PCI內(nèi)存地址窗口。
  • 為這些設(shè)備產(chǎn)生中斷連線值;用來控制設(shè)備的中斷處理。

下一節(jié)將描敘這些代碼的工作過程。

確定設(shè)備所需PCI I/O和PCI內(nèi)存空間的大小

系統(tǒng)要查詢每個PCI設(shè)備需要多少PCI I/O于PCI內(nèi)存地址空間。為了完成這項工作,每個基地址寄存器將被寫上全1并讀取出來。設(shè)備將把不必要的地址位設(shè)為0從而有效的定義所需地址空間。


圖6.10 PCI配置頭:基地址寄存器

有兩類基本的基地址寄存器,一類標識設(shè)備寄存器必須駐留的地址空間;另一類是PCI I/O或PCI內(nèi)存空間。此寄存器的0位來進行類型的區(qū)分。圖6.10給出了對應于PCI內(nèi)存和PCI I/O兩種不同類型的基地址寄存器。

確定某個基地址寄存器所需地址空間大小時,先向此寄存器寫入全1再讀取此寄存器,設(shè)備將在某些位填上0來形成一個二進制數(shù)表示所需有效地址空間。

以初始化DEC 21142 PCI快速以太設(shè)備為例,它將告訴系統(tǒng)需要0x100字節(jié)的PCI I/O空間或者PCI內(nèi)存空間。于是初始化代碼為其分配空間。空間分配完畢后,就可以在那些地址上看到21142的控制與狀態(tài)寄存器。

為PCI-PCI橋接器與設(shè)備分配PCI I/O與PCI內(nèi)存

象所有內(nèi)存一樣,PCI I/O和PCI內(nèi)存空間是非常有限甚至匱乏。非Intel系統(tǒng)的PCI補丁代碼(或者Intel 系統(tǒng)的BIOS代碼)必須為每個設(shè)備分配其所要求的內(nèi)存。PCI I/O和PCI內(nèi)存必須以自然對齊方式分配給每個設(shè)備。比如如果一個設(shè)備要求0xB0大小的PCI I/O空間則它必須和一個0xB0倍數(shù)的地址對齊。除此以外,對于任何指定橋接器,其PCI I/O和PCI內(nèi)存基址必須以在1M字節(jié)邊界上以4K字節(jié)方式對齊。所以在橋接器下方的設(shè)備的地址空間必須位于任意指定設(shè)備上方的PCI-PCI橋接器的內(nèi)存范圍內(nèi)。進行有效的空間分配是一件比較困難的工作。

Linux使用的算法依賴于由PCI設(shè)備驅(qū)動程序建立的描敘PCI設(shè)備的總線/設(shè)備樹,每個設(shè)備的地址空間按照PCI I/O內(nèi)存順序的升序來分配。同時再次使用遍歷算法來遍歷由PCI初始化代碼建立的pci_bus和 pci_dev結(jié)構(gòu)。從根PCI總線開始(由pci_boot指向)PCI補丁代碼將完成下列工作:

  • 使當前全局PCI I/O和內(nèi)存的基址在4K,邊界在1M上對齊。

  • 對于當前總線上的每個設(shè)備(按照PCI I/O內(nèi)存需要的升序排列)
    • 在PCI I/O和PCI內(nèi)存中為其分配空間

    • 為全局PCI I/O和內(nèi)存基址同時加上一個適當值

    • 授予設(shè)備對PCI I/O和PCI內(nèi)存的使用權(quán)

     

  • 為對于當前總線下方的所有總線循環(huán)分配空間。注意這將改變?nèi)諴CI I/O和內(nèi)存基址。

  • 使當前全局PCI I/O和內(nèi)存的基址和邊界分別在4K和1M對齊,以便確定當前PCI-PCI橋接器所需的PCI I/O和PCI內(nèi)存基址及大小。

  • 對此PCI-PCI橋接器編程,將其PCI I/O和PCI內(nèi)存基址及界限連接到總線上。

  • 打開PCI-PCI橋接器上的PCI I/O和PCI內(nèi)存訪問橋接功能。這時在此橋接器主干PCI總線上位于此橋接器PCI I/O和PCI內(nèi)存地址窗口中的任何PCI I/O或者PCI內(nèi)存地址將被橋接到二級PCI總線上。

以圖6.1中的PCI系統(tǒng)為例,PCI補丁代碼將以如下方式設(shè)置系統(tǒng):

對齊PCI基址
PCI I/O基址為0x4000而PCI內(nèi)存基址為0x100000。這樣允許PCI-ISA橋接器將此地址以下的地址轉(zhuǎn)換成ISA地址循環(huán)。
視頻設(shè)備
我們按照它的請求從當前PCI內(nèi)存基址開始分配0x200000字節(jié)給它,這樣可以在邊界上對齊。PCI內(nèi)存基址被移到0x400000同時PCI I/O基址保持在0x4000。
PCI-PCI 橋接器
現(xiàn)在我們將穿過PCI-PCI橋接器來分配PCI內(nèi)存,注意此時我們無需對齊這些基址,因為它們已經(jīng)自然對齊。
以太網(wǎng)設(shè)備
它需要0xB0字節(jié)的PCI I/O和PCI內(nèi)存空間。這些空間從PCI I/O地址0x4000和PCI內(nèi)存地址 0x400000處開始。PCI內(nèi)存基址被移動到0x4000B0同時PCI I/O基址移動到0x40B0。
SCSI 設(shè)備
它需要0x1000字節(jié)PCI內(nèi)存,所以它將在自然對齊后從從0x401000處開始分配空間。PCI I/O基址仍然在0x40B0而PCI內(nèi)存基址被移動到0x402000。
PCI-PCI 橋接器的PCI I/O和內(nèi)存窗口
現(xiàn)在我們重新回到橋接器并將其PCI I/O窗口設(shè)置成0x4000和0x40B0之間, 同時其PCI內(nèi)存窗口被設(shè)置到0x400000和0x402000之間。這樣此PCI-PCI橋接器將忽略對視頻設(shè)備的PCI內(nèi)存訪問但傳遞對以太網(wǎng)設(shè)備 或者SCSI設(shè)備的訪問。

 


File translated from TEX by TTH, version 1.0.
Top of Chapter, Table of Contents, Show Frames, No Frames
1996-1999 David A Rusling copyright notice.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    亚洲欧美日韩国产综合在线| 久七久精品视频黄色的| 欧美欧美日韩综合一区| 欧美日韩国产精品第五页| 91超精品碰国产在线观看| 欧美国产精品区一区二区三区| 极品少妇嫩草视频在线观看| 中文日韩精品视频在线| 日韩欧美综合中文字幕| 欧美日韩国产二三四区| 国产又粗又猛又长又黄视频| 亚洲中文字幕熟女丝袜久久| 欧洲日韩精品一区二区三区| 国产精品九九九一区二区| 国产精品日本女优在线观看| 亚洲少妇一区二区三区懂色| 国产日韩在线一二三区| 亚洲国产成人精品福利| 日韩精品区欧美在线一区| 欧美尤物在线观看西比尔| 国产自拍欧美日韩在线观看| 东京干男人都知道的天堂| 欧美整片精品日韩综合| 日本不卡视频在线观看| 午夜福利直播在线视频| 高中女厕偷拍一区二区三区| 日本高清不卡在线一区| 在线观看中文字幕91| 日韩精品综合免费视频| 国产视频在线一区二区| 国产免费人成视频尤物| 亚洲国产成人精品福利| 欧美午夜色视频国产精品| 久久国产成人精品国产成人亚洲| 91国自产精品中文字幕亚洲| 国产又大又黄又粗又免费| 久热久热精品视频在线观看| 麻豆果冻传媒一二三区| 国产成人国产精品国产三级| 久久天堂夜夜一本婷婷| 久久综合亚洲精品蜜桃|