一、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晶片中,各個埠都可以設定為非透明模式。