一、PCI橋與PCI設備的配置空間
PCI設備都有獨立的配置空間,HOST主橋通過配置讀寫總線事務訪問這段空間。PCI總線規定了三種類型的PCI配置空間,分別是PCI Agent設備使用的配置空間,PCI橋使用的配置空間和Cardbus橋片使用的配置空間。
本節重點介紹PCI Agent和PCI橋使用的配置空間,而並不介紹Cardbus橋片使用的配置空間。值得注意的是,在PCI設備配置空間中出現的地址都是PCI總線地址,屬於PCI總線域地址空間。
1、 PCI橋
PCI橋的引入使PCI總線極具擴展性,也極大地增加了PCI總線的復雜度。PCI總線的電氣特性決定了在一條PCI總線上掛接的負載有限,當PCI總線需要連接多個PCI設備時,需要使用PCI橋進行總線擴展,擴展出的PCI總線可以連接其他PCI設備,包括PCI橋。在一顆PCI總線樹上,最多可以掛接256個PCI設備,包括PCI橋。PCI橋在PCI總線樹中的位置如圖2‑8所示。

PCI橋作為一個特殊的PCI設備,具有獨立的配置空間。但是PCI橋配置空間的定義與PCI Agent設備有所不同。PCI橋的配置空間可以管理其下PCI總線子樹的PCI設備,並可以優化這些PCI設備通過PCI橋的數據訪問。PCI橋的配置空間在系統軟件遍歷PCI總線樹時配置,系統軟件不需要專門的驅動程序設置PCI橋的使用方法,這也是PCI橋被稱為透明橋的主要原因。
在某些處理器系統中,還有一類PCI橋,叫做非透明橋。非透明橋不是PCI總線定義的標准橋片,但是在使用PCI總線掛接另外一個處理器系統時非常有用,非透明橋片的主要作用是連接兩個不同的PCI總線域,進而連接兩個處理器系統,本章將在第2.5節中詳細介紹PCI非透明橋。
使用PCI橋可以擴展出新的PCI總線,在這條PCI總線上還可以繼續掛接多個PCI設備。PCI橋跨接在兩個PCI總線之間,其中距離HOST主橋較近的PCI總線被稱為該橋片上游總線(Primary Bus),距離HOST主橋較遠的PCI總線被稱為該橋片的下游總線(Secondary Bus)。如圖2‑8所示,PCI橋1的上游總線為PCI總線x0,而PCI橋1的下游總線為PCI總線x1。這兩條總線間的數據通信需要通過PCI橋1。
通過PCI橋連接的PCI總線屬於同一個PCI總線域,在圖2‑8中,PCI橋1、2和3連接的PCI總線都屬於PCI總線x域。在這些PCI總線域上的設備可以通過PCI橋直接進行數據交換而不需要進行地址轉換;而分屬不同PCI總線域的設備間的通信需要進行地址轉換,如與PCI非透明橋兩端連接的設備之間的通信。
如圖2‑8所示,每一個PCI總線的下方都可以掛接一個到多個PCI橋,每一個PCI橋都可以推出一條新的PCI總線。在同一條PCI總線上的設備之間的數據交換不會影響其他PCI總線。如PCI設備21與PCI設備22之間的數據通信僅占用PCI總線x2的帶寬,而不會影響PCI總線x0、x1與x3,這也是引入PCI橋的另一個重要原因。
由圖2‑8我們還可以發現PCI總線可以通過PCI橋組成一個胖樹結構,其中每一個橋片都是父節點,而PCI Agent設備只能是子節點。當PCI橋出現故障時,其下的設備不能將數據傳遞給上游總線,但是並不影響PCI橋下游設備間的通信。當PCI橋1出現故障時,PCI設備11、PCI設備21和PCI設備22將不能與PCI設備01和存儲器進行通信,但是PCI設備21和PCI設備22之間的通信可以正常進行。
使用PCI橋可以擴展一條新的PCI總線,但是不能擴展新的PCI總線域。如果當前系統使用32位的PCI總線地址,那么這個系統的PCI總線域的地址空間為4GB大小,在這個總線域上的所有設備將共享這個4GB大小的空間。如在PCI總線x域上的PCI橋1、PCI設備01、PCI設備11、PCI橋2、PCI設備21和PCI設備22等都將共享一個4GB大小的空間。再次強調這個4GB空間是PCI總線x域的“PCI總線地址空間”,和存儲器域地址空間和PCI總線y域沒有直接聯系。
處理器系統可以通過HOST主橋擴展出新的PCI總線域,如MPC8548處理器的HOST主橋x和y可以擴展出兩個PCI總線域x和y。這兩個PCI總線域x和y之間的PCI空間在正常情況下不能直接進行數據交換,但是PowerPC處理器可以通過設置PIWARn寄存器的TGI字段使得不同PCI總線域的設備直接通信,詳見第2.2.3節。
許多處理器系統使用的PCI設備較少,因而並不需要使用PCI橋。因此在這些處理器系統中,PCI設備都是直接掛接在HOST主橋上,而不需要使用PCI橋擴展新的PCI總線。即便如此讀者也需要深入理解PCI橋的知識。
PCI橋對於理解PCI和PCIe總線都非常重要。在PCIe總線中,雖然在物理結構上並不含有PCI橋,但是與PCI橋相關的知識在PCIe總線中無處不在,比如在PCIe總線的Switch中,每一個端口都與一個虛擬PCI橋對應,Switch使用這個虛擬PCI橋管理其下PCI總線子樹的地址空間。
2、 PCI Agent設備的配置空間
在一個具體的處理器應用中,PCI設備通常將PCI配置信息存放在E2PROM中。PCI設備進行上電初始化時,將E2PROM中的信息讀到PCI設備的配置空間中作為初始值。這個過程由硬件邏輯完成,絕大多數PCI設備使用這種方式初始化其配置空間。
讀者可能會對這種機制產生一個疑問,如果系統軟件在PCI設備將E2PROM中的信息讀到配置空間之前,就開始操作配置空間,會不會帶來問題?因為此時PCI設備的初始值並不“正確”,僅僅是PCI設備使用的復位值。
讀者的這種擔心是多余的,因為PCI設備在配置寄存器沒有初始化完畢之前,即E2PROM中的內容沒有導入PCI設備的配置空間之前,可以使用PCI總線規定的“Retry”周期使HOST主橋在合適的時機重新發起配置讀寫請求。
在x86處理器中,系統軟件使用CONFIG_ADDR和CONFIG_DATA寄存器,讀取PCI設備配置空間的這些初始化信息,然后根據處理器系統的實際情況使用DFS算法,初始化處理器系統中所有PCI設備的配置空間。
在PCI Agent設備的配置空間中包含了許多寄存器,這些寄存器決定了該設備在PCI總線中的使用方法,本節不會全部介紹這些寄存器,因為系統軟件只對部分配置寄存器感興趣。PCI Agent設備使用的配置空間如圖2‑9所示。

在PCI Agent設備配置空間中包含的寄存器如下所示。
(1) Device ID和Vendor ID寄存器
這兩個寄存器的值由PCISIG分配,只讀。其中Vendor ID代表PCI設備的生產廠商,而Device ID代表這個廠商所生產的具體設備。如Intel公司的基於82571EB芯片的系列網卡,其Vendor ID為0x8086[1],而Device ID為0x105E[2]。
(2) Revision ID和Class Code寄存器
這兩個寄存器只讀。其中Revision ID寄存器記載PCI設備的版本號。該寄存器可以被認為是Device ID寄存器的擴展。
(3) Header Type寄存器
該寄存器只讀,由8位組成。
第7位為1表示當前PCI設備是多功能設備,為0表示為單功能設備。
第6~0位表示當前配置空間的類型,為0表示該設備使用PCI Agent設備的配置空間,普通PCI設備都使用這種配置頭;為1表示使用PCI橋的配置空間,PCI橋使用這種配置頭;為2表示使用Cardbus橋片的配置空間,Card Bus橋片使用這種配置頭,本篇對這類配置頭不感興趣。
系統軟件需要使用該寄存器區分不同類型的PCI配置空間,該寄存器的初始化必須與PCI設備的實際情況對應,而且必須為一個合法值。
(4) Cache Line Size寄存器
該寄存器記錄HOST處理器使用的Cache行長度。在PCI總線中和Cache相關的總線事務,如存儲器寫並無效和Cache多行讀等總線事務需要使用這個寄存器。值得注意的是,該寄存器由系統軟件設置,但是在PCI設備的運行過程中,只有其硬件邏輯才會使用該寄存器,比如PCI設備的硬件邏輯需要得知處理器系統Cache行的大小,才能進行存儲器寫並無效總線事務,單行讀和多行讀總線事務。
如果PCI設備不支持與Cache相關的總線事務,系統軟件可以不設置該寄存器,此時該寄存器為初始值0x00。對於PCIe設備,該寄存器的值無意義,因為PCIe設備在進行數據傳送時,在其報文中含有一次數據傳送的大小,PCIe總線控制器可以使用這個“大小”,判斷數據區域與Cache行的對應關系。
(5) Subsystem ID和Subsystem Vendor ID寄存器
這兩個寄存器和Device ID和Vendor ID類似,也是記錄PCI設備的生產廠商和設備名稱。但是這兩個寄存器和Device ID與Vendor ID寄存器略有不同。下文以一個實例說明Subsystem ID和Subsystem Vendor ID的用途。
Xilinx公司在FGPA中集成了一個PCIe總線接口的IP核,即LogiCORE。用戶可以使用LogiCORE設計各種各樣基於PCIe總線的設備,但是這些設備的Device ID都是0x10EE,而Vendor ID為0x0007[3]。
(6) Expansion ROM base address寄存器
有些PCI設備在處理器還沒有運行操作系統之前,就需要完成基本的初始化設置,比如顯卡、鍵盤和硬盤等設備。為了實現這個“預先執行”功能,PCI設備需要提供一段ROM程序,而處理器在初始化過程中將運行這段ROM程序,初始化這些PCI設備。Expansion ROM base address記載這段ROM程序的基地址。
(7) Capabilities Pointer寄存器
在PCI設備中,該寄存器是可選的,但是在PCI-X和PCIe設備中必須支持這個寄存器,Capabilities Pointer寄存器存放Capabilities寄存器組的基地址,PCI設備使用Capabilities寄存器組存放一些與PCI設備相關的擴展配置信息。該組寄存器的詳細說明見第4.3節。
(8) Interrupt Line寄存器
這個寄存器是系統軟件對PCI設備進行配置時寫入的,該寄存器記錄當前PCI設備使用的中斷向量號,設備驅動程序可以通過這個寄存器,判斷當前PCI設備使用處理器系統中的哪個中斷向量號,並將驅動程序的中斷服務例程注冊到操作系統中[4]。
該寄存器由系統軟件初始化,其保存的值與8259A中斷控制器相關,該寄存器的值也是由PCI設備與8259A中斷控制器的連接關系決定的。如果在一個處理器系統中,沒有使用8259A中斷控制器管理PCI設備的中斷,則該寄存器中的數據並沒有意義。
在多數PowerPC處理器系統中,並不使用8259A中斷控制器管理PCI設備的中斷請求,因此該寄存器沒有意義。即使在x86處理器系統中,如果使用I/O APIC中斷控制器,該寄存器保存的內容仍然無效。目前在絕大多數處理器系統中,並沒有使用該寄存器存放PCI設備使用的中斷向量號。
(9) Interrupt Pin寄存器
這個寄存器保存PCI設備使用的中斷引腳,PCI總線提供了四個中斷引腳INTA#、INTB#、INTC#和INTD#。Interrupt Pin寄存器為1時表示使用INTA#引腳向中斷控制器提交中斷請求,為2表示使用INTB#,為3表示使用INTC#,為4表示使用INTD#。
如果PCI設備只有一個子設備時,該設備只能使用INTA#;如果有多個子設備時,可以使用INTB~D#信號。如果PCI設備不使用這些中斷引腳,向處理器提交中斷請求時,該寄存器的值必須為0。值得注意的是,雖然在PCIe設備中並不含有INTA~D#信號,但是依然可以使用該寄存器,因為PCIe設備可以使用INTx中斷消息,模擬PCI設備的INTA~D#信號,詳見第6.3.4節。
(10) Base Address Register 0~5寄存器
該組寄存器簡稱為BAR寄存器,BAR寄存器保存PCI設備使用的地址空間的基地址,該基地址保存的是該設備在PCI總線域中的地址。其中每一個設備最多可以有6個基址空間,但多數設備不會使用這么多組地址空間。
在PCI設備復位之后,該寄存器將存放PCI設備需要使用的基址空間大小,這段空間是I/O空間還是存儲器空間[5],如果是存儲器空間該空間是否可預取,有關PCI總線預讀機制的詳細說明見第3.4.5節。
系統軟件對PCI總線進行配置時,首先獲得BAR寄存器中的初始化信息,之后根據處理器系統的配置,將合理的基地址寫入相應的BAR寄存器中。系統軟件還可以使用該寄存器,獲得PCI設備使用的BAR空間的長度,其方法是向BAR寄存器寫入0xFFFF-FFFF,之后再讀取該寄存器。
處理器訪問PCI設備的BAR空間時,需要使用BAR寄存器提供的基地址。值得注意的是,處理器使用存儲器域的地址,而BAR寄存器存放PCI總線域的地址。因此處理器系統並不能直接使用“BAR寄存器+偏移”的方式訪問PCI設備的寄存器空間,而需要將PCI總線域的地址轉換為存儲器域的地址。
如果x86處理器系統使能了IOMMU后,這兩個地址也並不一定相等,因此處理器系統直接使用這個PCI總線域的物理地址,並不能確保訪問PCI設備的BAR空間的正確性。除此之外在Linux系統中,ioremap函數的輸入參數為存儲器域的物理地址,而不能使用PCI總線域的物理地址。
而在pci_devàresource[bar].start參數中保存的地址已經經過PCI總線域到存儲器域的地址轉換,因此在編寫Linux系統的設備驅動程序時,需要使用pci_devàresource[bar].start參數中的物理地址,然后再經過ioremap函數將物理地址轉換為“存儲器域”的虛擬地址。
(11) Command寄存器
該寄存器為PCI設備的命令寄存器,該寄存器在初始化時,其值為0,此時這個PCI設備除了能夠接收配置請求總線事務之外,不能接收任何存儲器或者I/O請求。系統軟件需要合理設置該寄存器之后,才能訪問該設備的存儲器或者I/O空間。在Linux系統中,設備驅動程序調用pci_enable_device函數,使能該寄存器的I/O和Memory Space位之后,才能訪問該設備的存儲器或者I/O地址空間。
(12) Status寄存器
該寄存器的絕大多數位都是只讀位,保存PCI設備的狀態。
(13) Latency Timer寄存器
在PCI總線中,多個設備共享同一條總線帶寬。該寄存器用來控制PCI設備占用PCI總線的時間,當PCI設備獲得總線使用權,並使能Frame#信號后,Latency Timer寄存器將遞減,當該寄存器歸零后,該設備將使用超時機制停止[6]對當前總線的使用。
如果當前總線事務為Memeory Write and Invalidate時,需要保證對一個完整Cache行的操作結束后才能停止當前總線事務。對於多數PCI設備而言,該寄存器的值為32或者64,以保證一次突發傳送的基本單位為一個Cache行。
PCIe設備不需要使用該寄存器,該寄存器的值必須為0。因為PCIe總線的仲裁方法與PCI總線不同,使用的連接方法也與PCI總線不同。
3、 PCI橋的配置空間
PCI橋使用的配置空間的寄存器如圖2‑10所示。PCI橋作為一個PCI設備,使用的許多配置寄存器與PCI Agent的寄存器是類似的,如Device ID、Vendor ID、Status、Command、Interrupt Pin、Interrupt Line寄存器等,本節不再重復介紹這些寄存器。下文將重點介紹在PCI橋中與PCI Agent的配置空間不相同的寄存器。

與PCI Agent設備不同,在PCI橋中只含有兩組BAR寄存器,Base Address Register 0~1寄存器。這兩組寄存器與PCI Agent設備配置空間的對應寄存器的含義一致。但是在PCI橋中,這兩個寄存器是可選的。如果在PCI橋中不存在私有寄存器,那么可以不使用這組寄存器設置BAR空間。
在大多數PCI橋中都不存在私有寄存器,操作系統也不需要為PCI橋提供專門的驅動程序,這也是這類橋被稱為透明橋的原因。如果在PCI橋中不存在私有空間時,PCI橋將這兩個BAR寄存器初始化為0。在PCI橋的配置空間中使用兩個BAR寄存器的目的是這兩個32位的寄存器可以組成一個64位地址空間。
在PCI橋的配置空間中,有許多寄存器是PCI橋所特有的。PCI橋除了作為PCI設備之外,還需要管理其下連接的PCI總線子樹使用的各類資源,即Secondary Bus所連接PCI總線子樹使用的資源。這些資源包括存儲器、I/O地址空間和總線號。
在PCI橋中,與Secondary bus相關的寄存器包括兩大類。一類寄存器管理Secondary Bus之下PCI子樹的總線號,如Secondary和Subordinate Bus Number寄存器;另一類寄存器管理下游PCI總線的I/O和存儲器地址空間,如I/O和Memory Limit、I/O和Memory Base寄存器。在PCI橋中還使用Primary Bus寄存器保存上游的PCI總線號。
其中存儲器地址空間還分為可預讀空間和不可預讀空間,Prefetchable Memory Limit和Prefetchable Memory Base寄存器管理可預讀空間,而Memory Limit、Memory Base管理不可預讀空間。在PCI體系結構中,除了了ROM地址空間之外,PCI設備使用的地址空間大多都是不可預讀的。
(1) Subordinate Bus Number、Secondary Bus Number和Primary Bus Number寄存器
PCI橋可以管理其下的PCI總線子樹。其中Subordinate Bus Number寄存器存放當前PCI子樹中,編號最大的PCI總線號。而Secondary Bus Number寄存器存放當前PCI橋Secondary Bus使用的總線號,這個PCI總線號也是該PCI橋管理的PCI子樹中編號最小的PCI總線號。因此一個PCI橋能夠管理的PCI總線號在Secondary Bus Number~Subordinate Bus Number之間。這兩個寄存器的值由系統軟件遍歷PCI總線樹時設置。
Primary Bus Number寄存器存放該PCI橋上游的PCI總線號,該寄存器可讀寫。Primary Bus Number、Subordinate Bus Number和Secondary Bus Number寄存器在初始化時必須為0,系統軟件將根據這幾個寄存器是否為0,判斷PCI橋是否被配置過。
不同的操作系統使用不同的Bootloader引導,有的Bootloader可能會對PCI總線樹進行遍歷,此時操作系統可以不再重新遍歷PCI總線樹。在x86處理器系統中,BIOS會遍歷處理器系統中的所有PCI總線樹,操作系統可以直接使用BIOS的結果,也可以重新遍歷PCI總線樹。而PowerPC處理器系統中的Bootloader,如U-Boot並沒有完全遍歷PCI總線樹,此時操作系統必須重新遍歷PCI總線樹。
(2) Secondary Status寄存器
該寄存器的含義與PCI Agent配置空間的Status寄存器的含義相近,PCI橋的Secondary Status寄存器記錄Secondary Bus的狀態,而不是PCI橋作為PCI設備時使用的狀態。在PCI橋配置空間中還存在一個Status寄存器,該寄存器保存PCI橋作為PCI設備時的狀態。
(3) Secondary Latency Timer寄存器
該寄存器的含義與PCI Agent配置空間的Latency Timer寄存器的含義相近,PCI橋的Secondary Latency Timer寄存器管理Secondary Bus的超時機制,即PCI橋發向下游的總線事務;在PCI橋配置空間中還存在一個Latency Timer寄存器,該寄存器管理PCI橋發向上游的總線事務。
(4) I/O Limit和I/O Base寄存器
在PCI橋管理的PCI子樹中包含許多PCI設備,而這些PCI設備可能會使用I/O地址空間。PCI橋使用這兩個寄存器,存放PCI子樹中所有設備使用的I/O地址空間集合的基地址和大小。
(5) Memory Limit和Memory Base寄存器
在PCI橋管理的PCI子樹中有許多PCI設備,這些PCI設備可能會使用存儲器地址空間。這兩個寄存器存放所有這些PCI設備使用的,存儲器地址空間集合的基地址和大小,PCI橋規定這個空間的大小至少為1MB。
(6) Prefetchable Memory Limit和Prefetchable Memory Base寄存器
在PCI橋管理的PCI子樹中有許多PCI設備,如果這些PCI設備支持預讀,則需要從PCI橋的可預讀空間中獲取地址空間。PCI橋的這兩個寄存器存放這些PCI設備使用的,可預取存儲器空間的基地址和大小。
如果PCI橋不支持預讀,則其下支持預讀的PCI設備需要從Memory Base寄存器為基地址的存儲器空間中獲取地址空間。如果PCI橋支持預讀,其下的PCI設備需要根據情況,決定使用可預讀空間,還是不可預讀空間。PCI總線建議PCI設備支持預讀,但是支持預讀的PCI設備並不多見。
(7) I/O Base Upper 16 Bits and I/O Limit Upper 16寄存器
如果PCI橋僅支持16位的I/O端口,這組寄存器只讀,且其值為0。如果PCI橋支持32位I/O端口,這組寄存器可以提供I/O端口的高16位地址。
(8) Bridge Control Register。
該寄存器用來管理PCI橋的Secondary Bus,其主要位的描述如下。
Secondary Bus Reset位,第6位,可讀寫。當該位為1時,將使用下游總線提供的RST#信號復位與PCI橋的下游總線連接的PCI設備。通常情況下與PCI橋下游總線連接的PCI設備,其復位信號需要與PCI橋提供的RST#信號連接,而不能與HOST主橋提供的RST#信號連接。
Primary Discard Timer位,第8位,可讀寫。PCI橋支持Delayed傳送方式,當PCI橋的Primary總線上的主設備使用Delayed方式進行數據傳遞時,PCI橋使用Retry周期結束Primary總線的Non-Posted數據請求,並將這個Non-Posted數據請求轉換為Delayed數據請求,之后主設備需要擇時重試相同的Non-Posted數據請求。當該位為1時,表示在Primary Bus上的主設備需要在210個時鍾周期之內重試這個數據請求,為0時,表示主設備需要在215個時鍾周期之內重試這個數據請求,否則PCI橋將丟棄Delayed數據請求。
Secondary Discard Timer位,第9位,可讀寫。當該位為1時,表示在Secondary Bus上的主設備需要在210個時鍾周期之內重試這個數據請求,為0時,表示主設備需要在215個時鍾周期之內重試這個數據請求,如果主設備在規定的時間內沒有進行重試時,PCI橋將丟棄Delayed數據請求。
二、PCI總線的配置
其中HOST主橋或者PCI橋使用Type 00h配置請求,訪問與HOST主橋或者PCI橋直接相連的PCI Agent設備或者PCI橋[1];而HOST主橋或者PCI橋使用Type 01h配置請求,需要至少穿越一個PCI橋,訪問沒有與其直接相連的PCI Agent設備或者PCI橋。如圖2‑8所示,HOST主橋可以使用Type 00h配置請求訪問PCI設備01,而使用Type 01h配置請求通過PCI橋1、2或者3轉換為Type 00h配置請求之后,訪問PCI總線樹上的PCI設備11、21、22、31和32[2]。PCI總線定義了兩類配置請求,一個是Type 00h配置請求,另一個是Type 01h配置請求。PCI總線使用這些配置請求訪問PCI總線樹上的設備配置空間,包括PCI橋和PCI Agent設備的配置空間。
當x86處理器對CONFIG_DATA寄存器進行讀寫操作時,HOST主橋將決定向PCI總線發送Type 00h配置請求還是Type 01h配置請求。在PCI總線事務的地址周期中,這兩種配置請求總線事務的不同反映在PCI總線的AD[31:0]信號線上。
值得注意的是,PCIe總線還可以使用ECAM(Enhanced Configuration Access Mechanism)機制訪問PCIe設備的擴展配置空間,使用這種方式可以訪問PCIe設備256B~4KB之間的擴展配置空間。但是本節僅介紹如何使用CONFIG_ADDRESS和CONFIG_FATA寄存器產生Type 00h和Type 01h配置請求。有關ECAM機制的詳細說明見第5.3.2節。
處理器首先將目標PCI設備的ID號保存在CONFIG_ADDRESS寄存器中,之后HOST主橋根據該寄存器的Bus Number字段,決定是產生Type 00h配置請求,還是Type 01h配置請求。當Bus Number字段為0時,將產生Type 00h配置請求,因為與HOST主橋直接相連的總線號為0;大於0時,將產生Type 01h配置請求。
1、 Type 01h和Type 00h配置請求
本節首先介紹Type 01h配置請求,並從PCI總線使用的信號線的角度上,講述HOST主橋如何生成Type 01配置請求。在PCI總線中,只有PCI橋能夠接收Type 01h配置請求。Type 01h配置請求不能直接發向最終的PCI Agent設備,而只能由PCI橋將其轉換為Type 01h繼續發向其他PCI橋,或者轉換為Type 00h配置請求發向PCI Agent設備。PCI橋還可以將Type 01h配置請求轉換為Special Cycle總線事務(HOST主橋也可以實現該功能),本節對這種情況不做介紹。
在地址周期中,HOST主橋使用配置讀寫總線事務,將CONFIG_ADDRESS寄存器的內容拷貝到PCI總線的AD[31:0]信號線中。CONFIG_ADDRESS寄存器與Type 01h配置請求的對應關系如圖2‑11所示。

從圖2‑11中可以發現,CONFIG_ADDRESS寄存器的內容基本上是原封不動的拷貝到PCI總線的AD[31:0]信號線上的[3]。其中CONFIG_ADDRESS的Enable位不被拷貝,而AD總線的第0位為必須為1,表示當前配置請求是Type 01h。
當PCI總線接收到Type 01配置請求時,將尋找合適的PCI橋[4]接收這個配置信息。如果這個配置請求是直接發向PCI橋下的PCI設備時,PCI橋將接收個Type 01配置請求,並將其轉換為Type 00h配置請求;否則PCI橋將當前Type 01h配置請求原封不動的傳遞給下一級PCI總線。
如果HOST主橋或者PCI橋發起的是Type 00h配置請求,CONFIG_ADDRESS寄存器與AD[31:0]的轉換如圖2‑12所示。

此時處理器對CONFIG_DATA寄存器進行讀寫時,處理器將CONFIG_ADDRESS寄存器中的Function Number和Register Number字段拷貝到PCI的AD總線的第10~2位;將AD總線的第1~0位賦值為0b00。PCI總線在配置請求總線事務的地址周期根據AD[1:0]判斷當前配置請求是Type 00h還是Type 01h,如果AD[1:0]等於0b00表示是Type 00h配置請求,如果AD[1:0]等於0b01表示是Type 01h配置請求。
而AD[31:11]與CONFIG_ADDRESS的Device Number字段有關,在Type 00h配置請求的地址周期中,AD[31:11]位有且只有一位為1,其中AD[31:11]的每一位選通一個PCI設備的配置空間。如第1.2.2節所述,PCI設備配置空間的片選信號是IDSEL,因此AD[31:11]將與PCI設備的IDSEL信號對應相連。
當以下兩種請求之一滿足時,HOST主橋或者PCI橋將生成Type 00h配置頭,並將其發送到指定的PCI總線上。
(1) CONFIG_ADDRESS寄存器的Bus Number字段為0時,處理器訪問CONFIG_DATA寄存器時,HOST主橋將直接向PCI總線0發出Type 00h配置請求。因為與HOST主橋直接相連的PCI總線號為0,此時表示HOST主橋需要訪問與其直接相連的PCI設備。
(2) 當PCI橋收到Type 01h配置頭時,將檢查Type 01配置頭的Bus Number字段,如果這個Bus Number與PCI橋的Secondary Bus Number相同,則將這個Type 01配置頭轉換為Type 00h配置頭,並發送到該PCI橋的Secondary總線上。
2、 PCI總線配置請求的轉換原則
當CONFIG_ADDRESS寄存器的Enable位為1,系統軟件訪問CONFIG_DATA寄存器時,HOST主橋可以產生兩類PCI總線配置讀寫總線事務,分別為Type 00h和Type 01h配置讀寫總線事務。在配置讀寫總線事務的地址周期和數據周期中,CONFIG_ADDRESS和CONFIG_DATA寄存器中的數據將被放置到PCI總線的AD總線上。其中Type 00h和Type 01h配置讀寫總線事務映射到AD總線的數據並不相同。
其中Type 00h配置請求可以直接讀取PCI Agent設備的配置空間,而Type 01h配置請求在通過PCI橋時,最終將被轉換為Type 00h配置請求,並讀取PCI Agent設備的配置寄存器。本節重點講述PCI橋如何將Type 01h配置請求轉換為Type 00h配置請求。
首先Type 00h配置請求不會被轉換成Type 01h配置請求,因為Type 00h配置請求是發向最終PCI Agent設備,這些PCI Agent設備不會轉發這些配置請求。
當CONFIG_ADDRESS寄存器的Bus Number字段為0時,處理器對CONFIG_DATA寄存器操作時,HOST主橋將直接產生Type 00h配置請求,掛接在PCI總線0上的某個設備將通過ID譯碼接收這個Type 00h配置請求,並對配置寄存器進行讀寫操作。如果PCI總線上沒有設備接收這個Type 00h配置請求,將引發Master Abort,詳情見PCI總線規范,本節對此不做進一步說明。
如果CONFIG_ADDRESS寄存器的Bus Number字段為n(n≠0),即訪問的PCI設備不是直接掛接在PCI總線0上的,此時HOST主橋對CONFIG_DATA寄存器操作時,將產生Type 01h配置請求,PCI總線0將遍歷所有在這條總線上的PCI橋,確定由哪個PCI橋接收這個Type 01h配置請求。
如果n大於等於某個PCI橋的Secondary Bus Number寄存器,而且小於等於Subordinate Bus number寄存器,那么這個PCI橋將接收在當前PCI總線上的Type 01配置請求,並采用以下規則進行遞歸處理。
(1) 開始。
(2) 遍歷當前PCI總線的所有PCI橋。
(3) 如果n等於某個PCI橋的Secondary Bus Number寄存器,說明這個Type 01配置請求的目標設備直接連接在該PCI橋的Secondary bus上。此時PCI橋將Type 01配置請求轉換為Type 00h配置請求,並將這個配置請求發送到PCI橋的Secondary Bus上,Secondary Bus上的某個設備將響應這個Type 00h配置請求,並與HOST主橋進行配置信息的交換,轉(5)。
(4) 如果n大於PCI橋的Secondary Bus Number寄存器,而且小於等於PCI橋的Subordinate Bus number寄存器,說明這個Type 01配置請求的目標設備不與該PCI橋的Secondary Bus直接相連,但是由這個PCI橋下游總線上的某個PCI橋管理。此時PCI橋將首先認領這個Type 01配置請求,並將其轉發到Secondary Bus,轉(2)。
(5) 結束。
下文將舉例說明PCI總線配置請求的轉換原則,並以圖2‑8為例說明處理器如何訪問PCI設備01和PCI設備31的配置空間。PCI設備01直接與HOST主橋相連,因此HOST主橋可以使用Type 00h配置請求訪問該設備。
而HOST主橋需要經過多級PCI橋才能訪問PCI設備31,因此HOST主橋需要首先使用Type 01h配置請求,之后通過PCI橋1、2和3將Type 01h配置請求轉換為Type 00h配置請求,最終訪問PCI設備31。
1 PCI設備01
這種情況較易處理,當HOST處理器訪問PCI設備01的配置空間時,發現PCI設備01與HOST主橋直接相連,所以將直接使用Type 00h配置請求訪問該設備的配置空間,具體步驟如下。
首先HOST處理器將CONFIG_ADDRESS寄存器的Enable位置1,Bus Number號置為0,並對該寄存器的Device、Function和Register Number字段賦值。當處理器對CONFIG_DATA寄存器訪問時,HOST主橋將存放在CONFIG_ADDRESS寄存器中的數值,轉換為Type 00h配置請求,並發送到PCI總線0上,PCI設備01將接收這個Type 00h配置請求,並與處理器進行配置信息交換。
2 PCI設備31
HOST處理器對PCI設備31進行配置讀寫時,需要通過HOST主橋、PCI橋1、2和3,最終到達PCI設備31。
當處理器訪問PCI設備31時,首先將CONFIG_ADDRESS寄存器的Enable位置1,Bus Number字段置為3,並對Device、Function和Register Number字段賦值。之后當處理器對CONFIG_DATA寄存器進行讀寫訪問時,HOST主橋、PCI橋1、2和3將按照以下步驟進行處理,最后PCI設備31將接收這個配置請求。
(1) HOST主橋發現Bus Number字段的值為3,該總線號並不是與HOST主橋直接相連的PCI總線的Bus Number,所以HOST主橋將處理器對CONFIG_DATA寄存器的讀寫訪問直接轉換為Type 01h配置請求,並將這個配置請求發送到PCI總線0上。PCI總線規定Type 01h配置請求只能由PCI橋負責處理。
(2) 在PCI總線0上,PCI橋1的Secondary Bus Number為1而Subordinate Bus Number為3。而1< Bus Number <= 3,所以PCI橋1將接收來自PCI總線0的Type 01h配置請求,並將這個配置請求直接下推到PCI總線1。
(3) 在PCI總線1上,PCI橋2的Secondary Bus Number為2而Subordinate Bus Number為3。而1< Bus Number <= 3,所以PCI橋2將接收來自PCI總線0的Type 01h配置請求,並將這個配置請求直接下推到PCI總線2。
(4) 在PCI總線2上,PCI橋3的Secondary Bus Number為3,因此PCI橋3將“來自PCI總線2的Type 01h配置請求”轉換為Type 00h配置請求,並將其下推到PCI總線3。PCI總線規定,如果PCI橋的Secondary Bus Number與Type 01h配置請求中包含的Bus Number相同時,該PCI橋將接收的Type 01h配置請求轉換為Type 00h配置請求,然后再發向其Secondary Bus。
(5) 在PCI總線3上,有兩個設備PCI設備31和PCI設備32。在這兩個設備中,必然有一個設備將要響應這個Type 00h配置請求,從而完成整個配置請求周期。本篇在第2.4.1節中,討論了究竟是PCI設備31還是PCI設備32接收這個配置請求,這個問題涉及PCI總線如何分配PCI設備使用的設備號。
3、 PCI總線樹Bus號的初始化
在一個處理器系統中,每一個HOST主橋都推出一顆PCI總線樹。在一顆PCI總線樹中有多少個PCI橋(包括HOST主橋),就含有多少條PCI總線。系統軟件在遍歷當前PCI總線樹時,需要首先對這些PCI總線進行編號,即初始化PCI橋的Primary、Secondary和Subordinate Bus Number寄存器。
在一個處理器系統中,一般將與HOST主橋直接相連的PCI總線被命名為PCI總線0。然后系統軟件使用DFS(Depth First Search)算法,依次對其他PCI總線進行編號。值得注意的是,與HOST主橋直接相連的PCI總線,其編號都為0,因此當處理器系統中存在多個HOST主橋時,將有多個編號為0的PCI總線,但是這些編號為0的PCI總線分屬不同的PCI總線域,其含義並不相同。
在一個處理器系統中,PCI總線樹的結構如圖2‑13所示。當然在一個實際的處理器系統中,很少會出現這樣復雜的PCI總線樹結構,本節采用這個結構的目的是便於說明PCI總線號的分配過程。

在PCI總線中,系統軟件使用深度優先DFS算法對PCI總線樹進行遍歷,DFS算法和廣度優先BFS(Breadth First Search)算法是遍歷樹型結構的常用算法。與BFS算法相比,DFS算法的空間復雜度較低,因此絕大多數系統系統在遍歷PCI總線樹時,都使用DFS算法而不是BFS算法。
DFS是搜索算法的一種,其實現機制是沿着一顆樹的深度遍歷各個節點,並盡可能深地搜索樹的分支,DFS的算法為線性時間復雜度,適合對拓撲結構未知的樹進行遍歷。在一個處理器系統的初始化階段,PCI總線樹的拓撲結構是未知的,適合使用DFS算法進行遍歷。下文以圖2‑13為例,說明系統軟件如何使用DFS算法,分配PCI總線號,並初始化PCI橋中的Primary Bus Number、Secondary Bus Number和Subordinate Bus number寄存器。所謂DFS算法是指按照深度優先的原則遍歷PCI胖樹,其步驟如下。
(1) HOST主橋掃描PCI總線0上的設備。系統軟件首先忽略所有這條總線上的PCI Agent設備,因為在這些設備之下不會掛接新的PCI總線。例如PCI設備01下不可能掛接新的PCI總線。
(2) HOST主橋首先發現PCI橋1,並將PCI橋1的Secondary Bus命名為PCI總線1。系統軟件將初始化PCI橋1的配置空間,將PCI橋1的Primary Bus Number寄存器賦值為0,而將Secondary Bus Number寄存器賦值為1,即PCI橋1的上游PCI總線號為0,而下游PCI總線號為1。
(3) 掃描PCI總線1,發現PCI橋2,並將PCI橋2的Secondary Bus命名為PCI總線2。系統軟件將初始化PCI橋2的配置空間,將PCI橋2的Primary Bus Number寄存器賦值為1,而將Secondary Bus Number寄存器賦值為2。
(4) 掃描PCI總線2,發現PCI橋3,並將PCI橋3的Secondary Bus命名為PCI總線3。系統軟件將初始化PCI橋3的配置空間,將PCI橋3的Primary Bus Number寄存器賦值為2,而將Secondary Bus Number寄存器賦值為3。
(5) 掃描PCI總線3,沒有發現任何PCI橋,這表示PCI總線3下不可能有新的總線,此時系統軟件將PCI橋3的Subordinate Bus number寄存器賦值為3。系統軟件在完成PCI總線3的掃描后,將回退到PCI總線3的上一級總線,即PCI總線2,繼續進行掃描。
(6) 在重新掃描PCI總線2時,系統軟件發現PCI總線2上除了PCI橋3之外沒有發現新的PCI橋,而PCI橋3之下的所有設備已經完成了掃描過程,此時系統軟件將PCI橋2的Subordinate Bus number寄存器賦值為3。繼續回退到PCI總線1。
(7) PCI總線1上除了PCI橋2外,沒有其他橋片,於是繼續回退到PCI總線0,並將PCI橋1的Subordinate Bus number寄存器賦值為3。
(8) 在PCI總線0上,系統軟件掃描到PCI橋4,則首先將PCI橋4的Primary Bus Number寄存器賦值為0,而將Secondary Bus Number寄存器賦值為4,即PCI橋1的上游PCI總線號為0,而下游PCI總線號為4。
(9) 系統軟件發現PCI總線4上沒有任何PCI橋,將結束對PCI總線4的掃描,並將PCI橋4的Subordinate Bus number寄存器賦值為4,之后回退到PCI總線4的上游總線,即PCI總線0繼續進行掃描。
(10) 系統軟件發現在PCI總線0上的兩個橋片PCI總線0和PCI總線4都已完成掃描后,將結束對PCI總線的DFS遍歷全過程。
從以上算法可以看出,PCI橋的Primary Bus和Secondary Bus號的分配在遍歷PCI總線樹的過程中從上向下分配,而Subordinate Bus號是從下向上分配的,因為只有確定了一個PCI橋之下究竟有多少條PCI總線后,才能初始化該PCI橋的Subordinate Bus號。
4、 PCI總線Device號的分配
一條PCI總線會掛接各種各樣的PCI設備,而每一個PCI設備在PCI總線下具有唯一的設備號。系統軟件通過總線號和設備號定位一個PCI設備之后,才能訪問這個PCI設備的配置寄存器。值得注意的是,系統軟件使用“地址尋址方式”訪問PCI設備的存儲器和I/O地址空間,這與訪問配置空間使用的“ID尋址方式”不同。
PCI設備的IDSEL信號與PCI總線的AD[31:0]信號的連接關系決定了該設備在這條PCI總線的設備號。如上文所述,每一個PCI設備都使用獨立的IDSEL信號,該信號將與PCI總線的AD[31:0]信號連接,IDSEL信號的含義見第1.2.2節。
在此我們簡要回顧PCI的配置讀寫事務使用的時序。如圖1‑3所示,PCI總線事務由一個地址周期加若干個數據周期組成。在進行配置讀寫請求總線事務時,C/BE#信號線的值在地址周期中為0x1010或者為0x1011,表示當前總線事務為配置讀或者配置寫請求。此時出現在AD[31:0]總線上的值並不是目標設備的PCI總線地址,而是目標設備的ID號,這與PCI總線進行I/O或者存儲器請求時不同,因為PCI總線使用ID號而不是PCI總線地址對配置空間進行訪問。
如圖2‑12所示,在配置讀寫總線事務的地址周期中,AD[10:0]信號已經被Function Number和Register Number使用,因此PCI設備的IDSEL只能與AD[31:11]信號連接。
認真的讀者一定可以發現在CONFIG_ADDRESS寄存器中Device Number字段一共有5位可以表示32個設備,而AD[31:11]只有21位,顯然在這兩者之間無法建立一一對應的映射關系。因此在一條PCI總線上如果有21個以上的PCI設備,那么總是有幾個設備無法與AD[31:11]信號線連接,從而PCI總線無法訪問這些設備。因為PCI總線在配置請求的地址周期中,只能使用第31~11這些AD信號,所以在一條總線上最多也只能掛接21個PCI設備。這21個設備可能是從0到20,也可能是從11到31排列。從而系統軟件在遍歷PCI總線時,還是需要從0到31遍歷整條PCI總線。
在實際的應用中,一條PCI總線能夠掛接21個設備已經足夠了,實際上由於PCI總線的負載能力有限,即便總線頻率為33MHz的情況下,在一條PCI總線中最多也只能掛接10個負載,一條PCI總線所能掛接的負載詳見表1‑1。AD信號線與PCI設備IDSEL線的連接關系如圖2‑14所示。

PCI總線推薦了一種Device Number字段與AD[31:16]之間的映射關系。其中PCI設備0與Device Number字段的0b00000對應;PCI設備1與Device Number字段的0b00001對應,並以此類推,PCI設備15與Device Number字段的0b01111對應。
在這種映射關系之下,一條PCI總線中,與信號線AD16相連的PCI設備其設備號為0;與信號線AD17相連的PCI設備其設備號為1;以此類推,與信號線AD31相連的PCI設備其設備號為15。在Type 00h配置請求中,設備號並沒有像Function Number和Register Number那樣以編碼的形式出現在AD總線上,而是與AD信號一一對應,如圖2‑12所示。
這里有一個原則需要讀者注意,就是對PCI設備的配置寄存器進行訪問時,一定要有確定的Bus Number、Device Number、Function Number和Register Number,這“四元組”缺一不可。在Type 00h配置請求中,Device Number由AD[31:11]信號線與PCI設備IDSEL信號的連接關系確定;Function Number保存在AD[10:8]字段中;而Register Number保存在AD[7:0]字段中;在Type 01h配置請求中,也有完整的四元組信息。
三、非透明PCI橋
此時處理器1和2使用的存儲器空間必須映射到PCI總線的地址空間中,而32位的PCI總線只能提供4GB地址空間,此時PCI總線x0的地址空間將全部被處理器1和2的存儲器空間占用,而沒有額外的空間分配給PCI設備。
但是在某些場合下PCI透明橋並不適用。在圖2‑15所示的處理器系統中存在兩個處理器,此時使用PCI橋1連接處理器2並不利於整個處理器系統的配置與管理。我們假定PCI總線使用32位地址空間,而處理器1和處理器2所使用的存儲器大小都為2GB,同時我們假定處理器1和處理器2使用的存儲器都可以被PCI設備訪問。PCI橋規范定義了透明橋的實現規則,本篇在第2.3.1節中詳細介紹了這種橋片。通過透明橋,處理器系統可以以HOST主橋為根節點,建立一顆PCI總線樹,在這個樹上的PCI設備共享同一個PCI總線域上的地址空間。

此外有些處理器不能作為PCI Agent設備,因此不能直接連接到PCI橋上,比如x86處理器就無法作為PCI Agent設備,因此使用PCI透明橋無法將兩個x86處理器直接相連。如果處理器2有兩個以上的PCI接口,其中一個可以與PCI橋1相連(此時處理器2將作為PCI Agent設備),而另一個作為HOST主橋y連接PCI設備。此時HOST主橋y掛接的PCI設備將無法被處理器1直接訪問。
使用透明橋也不便於解決處理器1與處理器2間的地址沖突,如圖2‑15所示的處理器系統,如果處理器1和2都將各自的存儲器映射到PCI總線地址空間中,有可能會出現地址沖突。雖然PowerPC處理器可以使用Inbound寄存器,將存儲器地址空間映射到不同的PCI總線地址空間中,但是不是所有的處理器都具有這種映射機制。許多處理器的存儲器地址與PCI總線地址使用了“簡單相等”這種映射方法,如果PCI總線連接了兩個這樣的處理器,將不可避免地出現PCI總線地址的映射沖突。
采用非透明橋將有效解決以上這些問題,非透明橋並不是PCI總線定義的標准橋片,但是這類橋片在連接兩個處理器系統中得到了廣泛的應用。一個使用非透明橋連接兩個處理器系統的實例如圖2‑16所示。

使用非透明PCI橋可以方便地連接兩個處理器系統。從上圖中我們可以發現非透明橋可以將PCI總線x域與PCI總線y域進行隔離。值得注意的是,非透明PCI橋的作用是對不同PCI總線域地址空間進行隔離,而不是隔離存儲器域地址空間。而HOST主橋的作用才是將存儲器域與PCI總線域進行隔離。
非透明PCI橋可以連接兩條獨立的PCI總線,一條被稱為Secondary PCI總線,另一條被稱為Primary PCI總線,但是這兩條總線沒有從屬關系,兩邊是對等的[1]。從處理器x的角度上看,與非透明PCI橋右邊連接的總線叫Secondary PCI總線;而從處理器y的角度上看,非透明PCI橋左邊連接的總線叫Secondary PCI總線。
HOST處理器x和PCI設備可以通過非透明PCI橋,直接訪問PCI總線y域的地址空間,並通過HOST主橋y與訪問存儲器y;HOST處理器y和PCI設備也可以通過非透明PCI橋,直接訪問PCI總線x域的地址空間,並通過HOST主橋x訪問存儲器x。為此非透明PCI橋需要對分屬不同PCI總線域的地址空間進行轉換。
目前有許多廠商可以提供非透明PCI橋的芯片,在具體實現上各有差異,但是其基本原理類似,下文以Intel 21555為例說明非透明PCI橋。值得注意的是,在PCIe體系結構中,也存在非透明PCI橋的概念。
1、 Intel 21555中的配置寄存器
Intel 21555非透明PCI橋源於DEC21554[2],並在此基礎上做了一些改動。Intel 21555橋片與其他透明橋在系統中的位置相同。如圖2‑16所示,這個橋片一邊與Primary PCI總線相連,另一邊與Secondary PCI總線相連。
在Intel 21555橋片中,包含兩個PCI 設備配置空間,分別是Primary PCI總線配置空間和Secondary PCI總線配置空間,處理器可以使用Type 00h配置請求訪問這些配置空間。在大多數情況之下,在Primary PCI總線上的HOST處理器管理Primary PCI配置空間;在Secondary PCI總線上的HOST處理器管理Secondary PCI配置空間[3]。
在Intel 21555橋片中,還有一組私有寄存器CSR(Control and Status Register),系統軟件使用這組寄存器對非透明橋進行管理並獲得橋片的一些信息,這組寄存器可以被映射成為PCI總線的存儲器地址空間或者I/O地址空間。
本章僅介紹Primary PCI總線這一邊的配置寄存器,Secondary PCI總線的配置寄存器雖然與Primary PCI總線的這些寄存器略有不同,但是基本對等,因此本節對此不做介紹。Primary PCI總線的主要寄存器如表2‑6所示。
表2‑6 Primary PCI總線的配置寄存器

從表2‑6中,我們可以發現Primary PCI總線的這些配置寄存器共分為兩組,一組寄存器與PCI設備的配置寄存器的BAR0~5對應,這些寄存器與標准PCI配置寄存器BAR0~5的功能相同;另一組寄存器是Translated Base寄存器,這組寄存器的主要作用是將來自Primary PCI總線的數據訪問轉換到Secondary PCI總線。
其中BAR0~5寄存器在系統初始化時由Primary PCI總線上的HOST處理器進行配置,配置過程與PCI總線上的普通設備完全相同。只是Intel 21555規定,BAR0只能映射為32位存儲器空間。
CSR寄存器可以根據需要映射在BAR0空間中,此時BAR0空間最小為4KB。CSR寄存器也可以根據需要使用BAR1寄存器映射為I/O地址空間,同時BAR1寄存器還可以映射其他I/O空間;BAR2~3只能映射為32位存儲器地址空間;而BAR4~5用來映射64位的存儲器地址空間。
對於Primary PCI總線,所有BAR0~5寄存器映射的地址空間都將占用Primary PCI總線域,然而這些地址空間中所對應的數據並不在Primary PCI總線域中,而是在Secondary PCI總線域中。Translated Base寄存器實現不同PCI總線域地址空間的轉換,Intel 21555將不同PCI總線域地址空間的轉換過程稱為“地址翻譯”。
Intel 21555支持兩種地址翻譯方法,一個是直接地址翻譯,一個是查表翻譯。Primary PCI總線的BAR空間只支持直接地址翻譯,而Secondary PCI總線的Memory 2 BAR空間支持查表翻譯,本節僅介紹直接地址翻譯方法,對查表翻譯有興趣的讀者請閱讀Intel 21555的數據手冊[4]。直接地址翻譯過程如圖2‑17所示。

當Primary PCI總線對非透明橋21555的BAR0~5地址空間進行數據請求時,這個數據請求將被轉換為對Secondary PCI總線的數據請求。Translated Base寄存器將完成這個地址翻譯過程,下節將結合實例說明這個直接地址翻譯過程。
2、通過非透明橋片進行數據傳遞
下文以圖2‑16中處理器x訪問處理器y存儲器地址空間的實例,說明非透明橋21555如何將PCI總線x域與PCI總線y域聯系在一起。
處理器x需要訪問處理器y的存儲器空間之前,需要做一些必要的准備工作。
(1) 首先確定由哪一個BAR寄存器空間映射處理器y的存儲器地址空間。本節假定使用BAR2寄存器映射處理器y的存儲器地址空間。
(2) BAR2寄存器使用Downstream Memory 2 Translated Base寄存器,將來自Primary PCI總線的訪問轉換為對Secondary PCI總線地址空間的訪問。其中Downstream Memory 2 Translated Base寄存器可以由處理器x或者處理器y根據需要進行設置。
假定處理器x和y的HOST主橋使用“直接相等”策略,建立存儲器域與PCI總線域間的映射;而處理器x使用BAR2地址空間訪問處理器y存儲器空間0x1000-000~0x1FFF-FFFF;處理器x的系統軟件事先將BAR2寄存器設置完畢。處理器x訪問處理器y的這段存儲器空間的步驟如下,讀者可參考圖2‑18理解這一步驟。
(1) 首先處理器x訪問在處理器x域中,且與非透明橋的BAR2空間相對應的存儲器地址空間。
(2) HOST主橋將進行存儲器域到PCI總線域的轉換,並將這個請求發送到Primary PCI總線上。
(3) 非透明橋發現這個數據請求發向BAR2地址空間,則接收這個數據請求,並在橋片中暫存這個數據請求。
(4) 非透明橋根據Downstream Memory 2 Translated Base寄存器的內容,按照圖2‑17所示的規則進行地址轉換。假設Downstream Memory 2 Translated Base寄存器的基地址被預先設置為0x1000-0000,大小為256MB(這個物理地址屬於處理器y的主存儲器地址空間)。
(5) 經過非透明橋的轉換后,這個數據請求將穿越非透明橋,從Primary PCI總線域進入Secondary PCI總線域,然后訪問處理器y的基地址為0x1000-0000的存儲器區域。
(6) 處理器y的HOST主橋接收這個存儲器訪問請求,並最終將數據請求發向處理器y的存儲器中。

非透明橋21555除了可以支持存儲器到存儲器之間的數據傳遞,還支持PCI總線域到存儲器域,以及PCI總線域之間的數據傳遞,此外非透明橋21555還可以通過I2O和Doorbell寄存器進行Primary PCI總線與Secondary PCI總線之間的中斷信號傳遞。本節對這部分內容不做進一步介紹。
非透明橋有效解決了使用PCI總線連接兩個處理器存在的問題,因而得到了廣泛的應用。在PCIe體系結構中,也存在非透明PCI橋的概念。如在PLX的Switch芯片中,各個端口都可以設置為非透明模式。
