Linux Kernel 核心中文手冊(6)--PCI

PCI
    Peripheral Component Interconnect ( PCI ),好像它的名字暗示的一樣,是描
述如何通過一個結構化和可控制的方式把系統中的外設組件連接起來的一個標準。標準
的 PCI Local Bus 規範描述了系統組件電氣連接的方法和它們行爲的方法。本章探討
Linux 核心如何初始化系統的 PCI 總線和設備。
    圖 6.1 是一個 PCI 基礎的系統的邏輯圖。 PCI 總線和 PCI-PCI 橋( bridge )
是系統組件聯繫在一起的粘合劑。 CUP 和 video 設備連在主要的 PCI 總線, PCI 總
線 0 。一個特殊的 PCI 設備, PCI-PCI 橋把主總線連接到次 PCI 總線, PCI 總線
1 。按照 PCI 規範的術語, PCI 總線 1 描述成爲 PCI-PCI 橋的下游而 PCI 總線 0
是橋的上游。連接在次 PCI 總線上的是系統的 SCSI 和以太網設備。物理上橋、次要
PCI 總線和這兩種設備可以在同一塊 PCI 卡上。系統中的 PCI-ISA 橋支持老的、遺留
的 ISA 設備,本圖顯示了一個超級 I/O 控制芯片,控制鍵盤、鼠標和軟驅。


6.1 PCI Address Space ( PCI 地址空間)
    CPU 和 PCI 設備需要訪問它們所共享的內存。這些內存讓設備驅動程序控制這些
PCI 設備並在它們之間傳遞信息。一般地共享的內存包括設備的控制和狀態寄存器。這
些寄存器用於控制設備和讀取它的狀態。例如: PCI SCSI 設備驅動程序可以讀取 SCS
I 設備的狀態寄存器,判斷它是否可以向 SCSI 磁盤寫一塊信息。或者它可以寫入控制
寄存器讓它關閉的設備開始運行。
    CPU 的使用的系統內存可以用作這種共享內存,但是如果這樣的話,每一次 PCI 設
備訪問內存, CPU 都不得不停頓,等待 PCI 設備完成。對於內存的訪問通常有限制,
同一時間只能有一個系統組件允許訪問。這會使得系統速度降低。允許系統的外部設備
在一個不受控的方式下訪問主內存也不是一個好主意。這會非常危險:一個惡意的設備
會讓系統非常不穩定。
    外部設備由它們自己的內存空間。 CPU 可以訪問這些空間,但是設備對於系統內存
的訪問受到嚴格的控制,必須通過 DMA ( Direct Memory Access 直接內存存取)通道
。 ISA 設備可以訪問兩種地址空間: ISA I/O (輸入 / 輸出)和 ISA 內存。 PCI 由
三中: PCI I/O 、 PCI 內存和 PCI 配置空間( configuration space )。 CPU 可以
訪問所有的地址空間其中 PCI I/O 和 PCI 內存地址空間由設備驅動程序使用而 PCI 配
置空間由 Linux 和心中的 PCI 初始化代碼使用。
    Alpha AXP 處理器沒有對於除了系統地址空間之外的地址空間的天生的訪問模式。
它需要使用支持芯片來訪問象 PCI 配置空間這樣的其他地址空間。它使用了一個地址空
間的映射方案,從巨大的虛擬地址空間中偷出一部分映射到 PCI 地址空間。
6.2 PCI Configuration Headers ( PCI 配置頭)
    系統中的每一個 PCI 設備,包括 PCI-PCI 橋都由一個配置數據結構,位於 PCI 配


置地址空間中。 PCI 配置頭允許系統識別和控制設備。這個頭位於 PCI 配置地址空間
的確切位置依賴於設備使用的 PCI 拓撲。例如,插在 PC 主板一個 PCI 槽位的一個 P
CI 顯示卡配置頭會在一個位置,而如果它被插到另一個 PCI 槽位則它的頭會出現在 P
CI 配置內存中的另一個位置。但是不管這些 PCI 設備和橋在什麼位置,系統都可以發
現並使用它們配置頭中的狀態和配置寄存器來配置它們。
    通常,系統的設計使得每一個 PCI 槽位的 PCI 配置頭都有一個和它在板上的槽位
相關的偏移量。所以,舉例來說,板上的第一個槽位的 PCI 配置可能位於偏移 0 而第
二個槽位的在偏移 256 (所有的頭都一樣長度, 256 字節),依此類推。定義了系統
相關的硬件機制使得 PCI 配置代碼可以嘗試檢查一個給定的 PCI 總線上的所有可能的
 PCI 配置頭,試圖讀取頭中的一個域(通常是 Vendor Identification 域)得到一些
錯誤,從而知道那些設備存在而那些設備不存在。 PCI Local Bus 規範描述了一種可能
的錯誤信息:試圖讀取一個空的 PCI 槽位的 Verdor Identification 和 Device Inde
ntification 域時候返回 0xFFFFFFFF 。
圖 6.2 顯示了 256 字節的 PCI 配置頭的佈局。它包括以下域:
參見 include/linux/pci.h
Vendor Identification 唯一的數字,描述這個 PCI 設備的發明者。 Digital 的 PCI
 Vendor Identification 是 0x1011 而 Intel 是 0x8086 。
Device Identification 描述設備自身的唯一數字。例如 Digital 的 21141 快速以太
網設備的設備標識符是 0x0009 。
Status 此域給除了設備的狀態,它的位的含義由 PCI Local Bus 規範規定。
Command 系統通過寫這個域控制這個設備。例如:允許設備訪問 PCI I/O 內存。
Class Code 標識了設備的類型。對於每一種設備都有標準分類:顯示、 SCSI 等等。對


於 SCSI 的類型編碼是 0x0100 。
Base Address Registers 這些寄存器用於確定和分配設備可以使用的 PCI I/O 和 PCI
 內存的類型、大小和位置。
    Interrupt Pin PCI 卡的物理管腳中的 4 個用於向 PCI 總線傳遞中斷。標準中把
它們標記爲 A 、 B 、 C 和 D 。 Interrupt Pin 域描述了這個 PCI 設備使用那個管
腳。通常對於一個設備來說這時硬件決定的。就是說每一次系統啓動的時候,這個設備
都使用同一個中斷管腳。這些信息允許中斷處理子系統管理這些設備的中斷。
    Interrupt Line PCI 配置頭中的 Interrupt Line 域用於在 PCI 初始化代碼、設
備驅動程序和 Linux 的中斷處理子系統之間傳遞中斷控制。寫在這裏的數字對於設備驅
動程序來講是沒有意義的,但是它可以讓中斷處理程序正確地把一箇中斷從 PCI 設備發
送到 Linux 操作系統中正確的設備驅動程序的中斷處理代碼處。 Linux 如何處理中斷
參看第 7 章。
6.3 PCI I/O and PCI Memory Address ( PCI I/O 和 PCI 內存地址)
    這兩種地址空間用於設備和 CPU 上運行的 Linux 核心的它們的設備驅動程序通訊
。例如: DECchip 21141 快速以太網設備把它的內部寄存器映射到了 PCI I/O 空間。
然後它的 Linux 設備驅動程序通過讀寫這些寄存器來控制設備。顯示驅動程序通常使用
大量的 PCI 內存空間來放置顯示信息。
    直到 PCI 系統建立起來並使用 PCI 配置頭中的 Command 域打開了設備對於這些地
址空間的訪問爲止,設備都無法訪問這些空間。應該注意的是隻有 PCI 配置代碼讀寫
PCI 配置地址, Linux 的設備驅動程序只是讀寫 PCI I/O 和 PCI 內存地址。
6.4 PCI-ISA Bridges ( PCI-ISA 橋)
    這種橋把對於 PCI I/O 和 PCI 內存地址空間的訪問轉換成爲 ISA I/O 和 ISA 內


存訪問,用來支持 ISA 設備。現在銷售的多數系統都包括幾個 ISA 總線插槽和幾個 P
CI 總線插槽。這種向後的兼容的需要會不斷減少,將來會有隻有 PCI 的系統。在早期
的 Intel 8080 基礎的 PC 時代,系統中的 ISA 設備的 ISA 地址空間( I/O 和內存)
就被固定下來。甚至一個 S5000 Alpha AXP 基礎的計算機系統的 ISA 軟驅驅動器的 I
SA I/O 地址也會和第一臺 IBM PC 一樣。 PCI 規範保留了 PCI I/O 和 PCI 內存的地
址空間中的較低的區域保留給系統中的 ISA 外設並使用一個 PCI-ISA 橋把所有對於這
些區域的 PCI 內存訪問轉換爲 ISA 訪問。
6.5 PCI-PCI Bridges ( PCI-PCI 橋)
    PCI-PCI 橋是特殊的 PCI 設備,把系統中的 PCI 總線粘和在一起。簡單系統中只
有一個 PCI 總線,當時單個 PCI 總線可以支持的 PCI 設備的數量有電氣限制。使用
PCI-PCI 橋增加更多的 PCI 總線允許系統支持更多的 PCI 設備。這對於高性能的服務
器尤其重要。當然, Linux 完全支持使用 PCI-PCI 橋的使用。
6.5.1 PCI-PCI Bridges: PCI I/O and PCI Memory Windows
    PCI-PCI 橋只向下遊傳遞對於 PCI I/O 和 PCI 內存讀和寫的一個子集。例如在圖
 6.1 中,只有讀和寫的地址屬於 SCSI 或者以太網設備的時候 PCI-PCI 橋纔會把讀寫
的地址從 PCI 總線 0 傳遞到總線 1 ,其餘的都被忽略。這種過濾阻止了不必要的地址
信息遍歷系統。爲了達到這個目的, PCI-PCI 橋必須編程設置它們必須從主總線向次總
線通過的 PCI I/O 和 PCI 內存地址空間訪問的基礎( base )和限制。一旦系統中的
 PCI-PCI 橋設置好,只要 Linux 設備驅動程序只是通過這些窗口存取 PCI I/O 和 PC
I 內存空間, PCI-PCI 橋是不可見的。這是個重要的特性,使得 Linux 的 PCI 設備驅
動程序的作者的日子好過了。但是它也讓 Linux 下的 PCI-PCI 橋在一定程度上需要技
巧才能配置,我們不久就會看到。


6.5.2 PCI-PCI Bridges: PCI Configuration Cycles and PCI Bus Numbering ( PCI
-PCI 橋: PCI 配置 cycle 和 PCI 總線編號)
    既然 CPU 的 PCI 初始化代碼可以定位不在主 PCI 總線上的設備,必須有一種機制
使得橋可以決定是否把配置 cycle 從它的主接口傳遞到次接口上。一個 cycle 就是它
顯示在 PCI 總線上的地址。 PCI 規範定義了兩種 PCI 地址配置格式:類型 0 和類型
 1 ,分別在圖 6.3 和圖 6.4 中顯示。類型 0 的 PCI 配置 cycle 不包含總線號,被
這個 PCI 總線上的所有的 PCI 設備解釋用於 PCI 地址配置。配置 cycle 的位 32 :
 11 看作是設備選擇域。設計系統的一個方法是讓每一個位選擇一個不同的設備。這種
情況下爲 11 可能選擇槽位 0 的 PCI 設備,位 12 選擇槽位 1 的 PCI 設備,依此類
推。另一種方法是把設備的槽位號直接寫到位 31 : 11 中。一個系統使用哪一種機制
依賴於系統的 PCI 內存控制器。
    類型 1 的 PCI 配置 cycle 包括一個 PCI 總線號,這種配置循環被除了 PCI-PCI
 橋之外的所有 PCI 設備忽略。所有看到了類型 1 的 PCI 配置 cycle 的 PCI-PCI 橋
都可以把這些信息向它們的下游傳送。一個 PCI-PCI 橋是否忽略 PCI 配置循環或者向
它的下游傳遞,依賴於這個橋是如何配置的。每一個 PCI-PCI 橋都有一個主總線接口號
和一個次總線接口號。主總線接口離 CPU 最近而次總線接口是離 CPU 最遠的。每一個
 PCI-PCI 橋都還有一個附屬總線編號,這是在第二個總線接口之外可以橋接的最大的
PCI 總線數目。或者說,附屬總線編號是 PCI-PCI 橋下游的最大的 PCI 總線編號。當
 PCI-PCI 橋看到一個類型 1 的 PCI 配置 cycle 的時候,它做以下事情:
    如果指定的總線編號不在橋的次總線編號和總線的附屬編號之間就忽略它。
    如果指定的總線編號和橋的次總線編號符合就把它轉變成爲類型 0 的配置命令
    如果指定的總線編號大於次要總線編號而小於或等於附屬總線編號,就不改變地傳


遞到次要總線接口上。
    所以,如果我們希望尋址圖 6.9 的拓撲中總線 3 上的設備 1 ,我們必須從 CPU
生成一個類型 1 的配置命令。橋 1 不改變地傳遞到總線 1 ,橋 2 忽略它但是橋 3 把
它轉換成一個類型 0 的配置命令,並把它發送到總線 3 ,使設備 1 響應它。
每一個獨立的操作系統負責在 PCI 配置階段分配總線編號,但是不管使用哪一種編碼方
案,對於系統中所有的 PCI-PCI 橋,以下陳述都必須是正確的:
所有位於一個 PCI-PCI 橋後面的 PCI 總線的編碼都必須在次總線編號和附屬總線編號
之間(包含)
    如果違背了這條規則,則 PCI-PCI 橋將無法正確地傳遞和轉換類型 1 的 PCI 配置
 cycle ,系統無法成功地找到並初始化系統中的 PCI 設備。爲了完成編碼方案, Lin
ux 按照特定的順序配置這些特殊設備。參看 6.6.2 節對於 Linux PCI 橋和總線編碼方
案的描述以及一個可以工作的例子。
6.6 Linux PCI Initialization ( Linux PCI 初始化過程)
Linux 中 PCI 初始化代碼分爲三個邏輯部分:
    PCI Device Driver 這個僞設備驅動程序從總線 0 開始查找 PCI 系統,定位系統
中所有的 PCI 設備和橋。它建立一鏈接的數據結構的列表,描述系統的拓撲。另外,它
還爲系統中所有的橋編碼。
參見 drivers/pci/pci.c and include/linux/pci.h
    PCI BIOS 這個軟件層提供了 PCI BIOS ROM 規範中描述的服務。即使 Alpha AXP
沒有 BIOS 服務,在 Linux 核心也有提供了相同的功能的等價代碼。
參見 arch/*/kernel/bios32.c
PCI Fixup 系統相關的整理代碼,整理和系統相關的在 PCI 初始化最後的內存疏鬆的情


況。
參見 arch/*/kernel/bios32.c
6.6.1 Linux Kernel PCI Data Structures ( Linux 核心的 PCI 數據結構)
    當 Linux 核心初始化 PCI 系統的時候它建立反映系統真實的 PCI 拓撲結構的數據
結構。圖 6.5 顯示了數據結構之間的關係,它用來描述了圖 6.1 中示例的 PCI 系統。
 
    每一個 PCI 設備(包括 PCI-PCI 橋)都用一個 pci_dev 的數據結構描述。每一個
 PCI 總線用一個 pci_bus 的數據結構描述。結果是一個 PCI 總線的樹型結構,每一個
總線上有粘附着一些子 PCI 設備。因爲一個 PCI 總線只能通過 PCI-PCI 橋達到(除了
主 PCI 總線,總線 0 ),每一個 pci_bus 都包括一個它要通過的 PCI 設備的指針(
這個 PCI-PCI 橋)。這個 PCI 設備是這個 PCI 總線的父總線的一個子設備。
    圖 6.5 中沒有顯示的還有一個指向系統中所有的 PCI 設備的指針: pci_devices
 。系統中所有的 PCI 設備的 pci_dev 的數據結構都排在這個隊列中。 Linux 核心使
用這個隊列快速查找系統中所有的 PCI 設備。
6.6.2 The PCI Device Driver ( PCI 設備驅動程序)
    PCI 設備驅動程序完全不是一個真正的設備驅動程序,只是系統初始化的時候操作
系統調用的一個函數。 PCI 初始化代碼必須掃描系統中所有的 PCI 總線,查找系統中
所有的 PCI 設備(包括 PCI-PCI 橋接設備)。它使用 PCI BIOS 代碼來查看它當前掃
描的 PCI 總線上的每一個可能的槽位是否被佔用。如果這個 PCI 槽位佔用,它就建立
一個描述這個設備的 pci_dev 數據結構,並把它鏈接到已知 PCI 設備的列表中(由 p
ci_deivices 指向)。
參見 drivers/pci/pci.c Scan_bus()


    PCI 初始化代碼從 PCI 總線 0 開始掃描。它試圖讀出每一個可能的 PCI 槽位中每
一個可能的 PCI 設備的 Vendor Identification 和 Device Identification 域。當它
找到了佔用的槽位它就建立一個 pci_dev 數據結構來描述它。 PCI 初始化代碼所建立
的所有的 pci_dev 數據結構(包括所有的 PCI-PCI 橋)都鏈接到一個鏈接表: pci_d
evices 。
    如果找到的設備是一個 PCI-PCI 橋,則建立一個 pci_bus 的數據結構,並鏈接到
 pci_root 指向的由 pci_bus 和 pci_dev 數據結構組成的樹上。 PCI 的初始代碼可以
判斷 PCI 設備是否 PCI-PCI 橋,因爲它的分類編碼( class code )是 0x060400 。
然後 Linux 核心配置它剛剛找到的 PCI-PCI 橋的另一端的 PCI 總線(下游)。如果找
到更多的 PCI-PCI 橋,它們都一樣被配置。這個過程成爲深度( depthwize )算法:
系統在寬度搜索之前先在深度展開。看圖 6.1 , Linux 會首先配置 PCI 總線 1 和它
的以太網和 SCSI 設備,然後配置 PCI 總線 0 上的顯示設備。
    在 Linux 向下遊查找 PCI 總線的時候它必須配置介入的 PCI-PCI 橋的次總線和附
屬總線編號。這些在下面的 6.6.2 節詳細描述:
Configuring PCI-PCI Bridges – Assigning PCI Bus Numbers (配置 PCI-PCI 橋 -
 分配 PCI 總線編號)
    對於傳送通過它們進行的 PCI I/O 、 PCI 內存或者 PCI 配置地址空間的讀寫,
PCI-PCI 橋必須直到以下:
Primary Bus Number 剛好在 PCI-PCI 橋上游的總線編號
Secondary Bus Number 剛好在 PCI-PCI 橋下游的總線編號
Subordinate Bus Number 從這個橋向下可以達到的所有總線中最高的總線編號。
PCI I/O and PCI Memory Windows 從這個 PCI-PCI 橋向下的所有的地址的 PCI I/O 地


址空間和 PCI 內存空間的窗口的 base 和 size 。
    問題是當你希望配置任何指定的 PCI-PCI 橋的時候你並不知道這個橋的附屬總線數
目。你不知道是否下游還有其他 PCI-PCI 橋。就算知道,你也不知道它們將會被分配什
麼編號。答案是使用一個深度遞歸算法( depthwise recursive algorithm )。在每一
個總線上找到任何 PCI-PCI 橋的時候都就給它們分配編號。對於找到的每一個 PCI-PC
I 橋,就給它的次總線分配編號,並給它分配臨時的附屬總線編號 0xFF ,並掃描它的
下游所有的 PCI-PCI 橋並分配編號。這看起來相當複雜,但是下面的實際例子能使這個
過程更清楚。
    PCI-PCI Bridge Numbering : Step 1 參考圖 6.6 中的拓撲,掃描找到的第一個
橋是橋 1 ( Bridge1 )。橋 1 下游的 PCI 總線編號爲 1 ,橋 1 分配一個次總線號
 1 和一個臨時的附屬總線編號 0xFF 。這意味着指定 PCI 總線 1 或更高的所用的類型
 1 的 PCI 配置地址會穿過橋 1 到達 PCI 總線 1 。如果它們的總線編號是 1 ,就轉
換成爲類型 0 的配置 cycle ,否則對於其他的總線編號就不變。這也正是 Linux PCI
 初始化代碼需要做的,這樣才能訪問並掃描 PCI 總線 1 。
    PCI-PCI Bridge Numbering : Step 2 Linux 使用深度算法,所以初始化代碼開始
掃描 PCI 總線 1 。這是它找到了 PCI-PCI 橋 2 ,橋 2 之外沒有其他的 PCI-PCI 橋
,所以它的附屬總線編號成爲 2 ,和它的次接口一樣。圖 6.7 顯示了總線和 PCI-PCI
 橋這時是如何編碼的。
    PCI-PCI Bridge Numbering : Step 3 PCI 初始化代碼回來掃描 PCI 總線 1 ,找
到了另一個 PCI-PCI 橋 3 。它的主總線接口賦值 1 而它的次總線接口是 3 ,它的附
屬總線編號是 0xFF 。圖 6.8 顯示了系統這時是如何配置的。帶有總線編號 1 、 2 或
 3 的類型 1 的 PCI 配置 cycle 現在可以正確地傳送到適當的 PCI 總線。


6.6.3 PCI BIOS Functions ( PCI BIOS 函數)
    PCI BIOS 函數是通用的跨平臺的一系列標準例程。例如,它們對於 Intel 和 Alp
ha AXP 系統都是一樣的。它們允許 CPU 控制對於所有 PCI 地址空間的訪問。只有 Li
nux 核心和設備驅動程序需要使用它們。
參見 arch/*/kernel/bios32.c
6.6.4 PCI Fixup
    Alpha AXP 系統上的 PCI 整理代碼比 Intel (基本不做任何事情)要做更多的工
作。對於 Intel 系統,啓動時候運行的系統 BIOS ,已經完全配置了 PCI 系統。 Lin
ux 不需要做更多的事情,只是映射 PCI 的配置。對於非 Intel 系統,需要做更多的配
置:
參見 arch/kernel/bios32.c
對於每一個設備分配 PCI I/O 和 PCI 內存空間
對於系統重的每一個 PCI-PCI 橋必須配置 PCI I/O 和 PCI 內存地址窗口
對於設備產生 Interrupt Line 值,這些控制設備的中斷處理
下面描述這些代碼如何工作。
Finding Out How Much PCI I/O and PCI Memory Space a Device Needs
(找出一個設備需要多少 PCI I/O 和 PCI 內存空間)
    查詢找到的每一個 PCI 設備,找出它需要多少 PCI I/O 和內存地址空間。爲此,
把每一個 Base Address Register 都寫成 1 然後讀出來。設備會在不關心的地址位返
回 1 ,有效地指定了需要的地址空間。
    用兩個基本的基礎地址寄存器( Base Address Register ),第一種指示設備的寄
存器以及 PCI I/O 和 PCI 內存空間必須在哪一個地址空間。這通過寄存器的 0 位表示


。圖 6.10 顯示了 PCI 內存和 PCI I/O 的基礎地址寄存器的兩種形式。
    爲了找出每一個給定的基礎地址寄存器需要多少地址空間,需要向所有的寄存器寫
並讀出來。設備會把不關心的地址位設爲 0 ,這樣就有效地指明瞭需要的地址空間。這
種設計暗示了使用的所有的地址空間都是 2 的指數,本質上是對齊的。
    例如,在你初始化 DECChip 21142 PCI 快速以太網設備的時候,它告訴你在 PCI
I/O 或 PCI 內存空間它需要 0x100 字節的地址。初始化代碼爲它分配空間。在它分配
空間之後, 21142 的控制和狀態寄存器就可以在這些地址見到。
Allocating PCI I/O and PCI Memory to PCI-PCI Bridges and Devices
(爲 PCI-PCI 橋和設備分配 PCI I/O 和 PCI 內存)
        象所有的內存一樣, PCI I/O 和 PCI 內存空間是有限的,其中有一些相當緊
缺。對於非 Intel 系統的 PCI 整理代碼(和 Intel 系統的 BIOS 代碼)必須有效地爲
每一個設備分配它需要的內存量。分配給一個設備的 PCI I/O 和 PCI 內存的分配必須
自然對齊。例如,如果一個設備請求 PCI I/O 地址 0xB0 ,那麼分配的地址就必須是
0xB0 的倍數。另外,分配給任何橋的 PCI I/O 和 PCI 內存地址的基礎必須分別對齊
4K 和 1M 的邊界。下游的設備給定的地址空間必須位於它所有的上游的 PCI-PCI 橋的
內存範圍中間。所以有效地分配地址空間是有比較困難的問題。
    Linux 使用的算法依賴於用 PCI 設備驅動程序建立的總線 / 設備樹所描述的每一
個設備,它按照 PCI I/O 內存遞增的順序分配地址空間。又是使用遞歸算法,遍歷 PC
I 初始化代碼所建立的 pci_bus 和 pci_dev 數據結構。 BIOS 整理代碼從 PCI 總線的
根( pci_root 所指)開始:
分別把當前的全局 PCI I/O 和內存的基礎分別對齊在 4K 和 1M 的邊界
對於當前總線上的每一個設備(按照需要的 PCI I/O 內存順序排列)


- 分配它的 PCI I/O 和 / 或 PCI 內存
- 將全局的 PCI I/O 和內存的基礎按照合適的量移動
- 允許設備使用給定的 PCI I/O 和 PCI 內存
分別爲當前總線下游的所有總線分配空間,注意這會改變全局的 PCI I/O 和內存基礎。
 
分別把當前的全局 PCI I/O 和內存的基礎對齊在 4K 和 1M 的邊界,同時指出當前的
PCI-PCI 橋所需要的 PCI I/O 和 PCI 內存的窗口的基礎和大小
對於連接在當前總線上的 PCI-PCI 橋,設置它的 PCI-PCI I/O 和 PCI 內存地址和限制

    打開 PCI-PCI 橋上橋接 PCI I/O 和 PCI 內存訪問的功能。這意味着如果任何在橋
的主 PCI 總線上看到的 PCI I/O 和 PCI 內存地址如果位於它的 PCI I/O 和 PCI 內存
地址窗口的話就會被橋接到它的次總線。
以圖 6.1 的 PCI 系統作爲 PCI 整理代碼的例子:
Align the PCI base (初始的) PCI I/O 是 0x4000 , PCI 內存是 0x100000 。這樣
允許 PCI-ISA 橋把所有低於此的地址都轉換到 ISA 地址。
    The Video Device 請求 0x200000 的 PCI 內存,因爲必須按照要求的大小對齊,
所以我們從 PCI 內存 0x200000 開始分配, PCI 內存基礎地址移到了 0x400000 ,而
 PCI I/O 地址仍舊是 0x4000 。
    The PCI-PCI Bridges 我們現在穿過 PCI-PCI 橋,在那裏分配內存。注意因爲我們
不需要對其基礎地址因爲它們已經正確對齊了。
    The Ethernet Device 它在 PCI I/O 和 PCI 內存空間都請求 0xB0 字節。它被分
配在 PCI I/O 地址 0x4000 , PCI 內存 0x400000 。 PCI 內存的基礎移到了 0x4000


    The SCSI Device 它請求 0x1000 的 PCI 內存,所以它在對齊之後分配在 0x4010
00 。而 PCI I/O 的基礎地址還是 0x40B0 , PCI 內存的基礎移到了 0x402000 。
    The PCI-PCI Bridge’s PCI I/O and Memory Windows 我們現在返回到橋,把它的
 PCI I/O 窗口設置成爲 0x4000 和 0x40B0 之間,它的 PCI 內存窗口在 0x400000 和
 0x402000 之間。這意味着 PCI-PCI 橋會忽略對於顯示設備的 PCI 內存訪問,如果是
對以太網或者 SCSI 設備的訪問就可以通過。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章