沿同一棵樹找到各個 Function

選擇步驟後,圖中對應的元件與下方解說會加上重點標示。完整圖與所有解說會持續顯示;也可用方向鍵切換步驟。

圖中標的是本例完成後的範圍。閱讀時從根部向下追蹤;探查期間的暫時上限及回填動作見下方步驟與正常枚舉時間表。

完成後的橋接範圍快照;導圖以這張結果圖定位每次探查,編號先後在步驟中說明。完成後的橋接範圍快照;導圖以這張結果圖定位每次探查,編號先後在步驟中說明。Root Port 00:01.0完成後下游範圍 01–04Switch Upstream 01:00.0完成後下游範圍 02–04Downstream A 02:01.0完成後範圍 03–03Downstream B 02:02.0完成後範圍 04–04Endpoint:03:00.0/03:00.1Endpoint:04:00.0

作者的教學拓樸;Bus Number 配置策略是示範,規格定義欄位及路由條件。

枚舉是由已知根部向下發現 Function 的過程。本章沿用前兩章的拓樸,先替橋接路徑建立可轉送的 Bus 範圍,再探查下游,最後記錄已找到的功能。

前情提要:Chapter 1 教你辨認 Port 與 Function;Chapter 2 教你在已知 Function 的設定空間中找欄位。現在要建立那些已知位置。

規格路線:Figures 7-1/7-2 的階層 → Figure 7-14 的橋接 Bus 欄位 → Figures 7-7/7-8 的身分與標頭。

  1. 從平台提供的根部開始

    平台已提供本例的合法根部範圍;路徑的 Link 與 Reset 後等待條件已滿足。

    先取得 Root Bridge 的設定存取介面、Segment 與 Bus 範圍,再從已知 Root Port 探查。

    Base 6.0 §7.1/Figures 7-1–7-2,pp.903–904;Firmware 3.3 §3.1.1/§3.5,pp.32、34–35。

  2. 配置通往下一層的橋接範圍

    本章示範先往一條分支走到底的配置策略;暫時上限採平台提供範圍,沒有其他管理者同時修改。

    在 Figure 7-14 找到 Primary、Secondary、Subordinate Bus Number。軟體先讓待探查分支具有合法的轉送範圍,再往下發設定要求。

    Base 6.0 §7.5.1.3.2–§7.5.1.3.4/Figure 7-14,pp.936–937。

  3. 探查分支並收斂範圍

    每筆設定存取先依成功、未就緒或失敗分流;後文另說明 RRS(Request Retry Status,暫時未就緒回覆)。

    沿 A 分支找到 Bus 03 的功能,再回來處理 B 分支。找到最深一層後,依本例策略回填各橋接器的最高下游 Bus。

    Base 6.0 §7.3.1–§7.3.3,pp.911–913;§7.5.1.3.3–§7.5.1.3.4,p.937。

  4. 記錄身分,接到後續配置

    探查 Function 1 前仍須依多功能裝置規則確認存在;完成發現後,資源與使用條件還需逐項建立。

    讀取 Vendor ID、Device ID、Header Type 與 Class Code,辨認功能及下一層橋接關係。這些資料接到 Chapter 4 的資源配置。

    Base 6.0 §7.5.1.1/Figures 7-7–7-8、Tables 7-6–7-7,pp.923–925。

圖中元件

Switch 的 Upstream Port

本例從 Bus 01 的橋接功能走到內部 Bus 02。

基本責任

Port 是連接介面;設定空間把相關路徑表示為可配置的橋接功能。

本章用同一棵樹示範發現過程。重點是每一步為什麼能走到下一層,不把一種軟體搜尋策略寫成所有平台唯一的枚舉程序。

1. 完全不知道裝置位置時,第一筆查詢從哪裡開始?

枚舉(enumeration)不是從任意記憶體位址開始猜。系統軟體先取得平台提供的 Host/Root Bridge 資訊,例如 Segment、可用 Bus 範圍,以及執行設定存取的介面,再從已知的根部往下找。

Root Bridge 是平台向軟體提供的根部存取與資源範圍,Root Port 則是 PCIe 階層中向下接出 Link 的 Port。兩者不要只因名稱都有 Root 就合併。Firmware 3.3 §3.1.1 說明 UEFI 的 Root Bridge 介面如何提供 PCI Memory、I/O 與 Configuration 存取;§3.5 則要求韌體配置所有 Host Bridge,並提供相關平台描述。

UEFI
Unified Extensible Firmware Interface,統一可延伸韌體介面

本例的搜尋策略是先往一條分支走到底,再回來處理旁邊的分支。Bus Number 依序使用 01、02、03、04,探查期間暫以 3F 作下游上限,完成後再縮到實際範圍。這是作者設計的配置策略;規格定義 Register 與路由行為,並未要求每個平台照這個編號順序,也未禁止為熱插拔保留額外 Bus Number。

平台起點的依據

PCI Firmware 3.3 §3.1.1,p.32;§3.5,pp.34–35。Base 6.0 §7.1,Figures 7-1/7-2,pp.903–904。Host Bridge 的實作與 Root Complex 內部編號具有平台差異,本例將已知起點列為前提,不由 Endpoint 反推平台設定。

2. 第一筆讀取,要取得什麼證據?

對一個待探查的位置,先讀 Configuration Header 的 Vendor ID。Base 6.0 建議用它判斷 Function 是否存在;在這個欄位看到 FFFFh,表示沒有 Function。可是軟體看到的讀值與 PCIe Completion Status 並不是同一件事:Root Complex 可能把某種交易結果轉成軟體可見的資料。

探查結果應先分流
觀察本章如何處理不能跳過的條件
取得有效的 Vendor ID 與成功的設定資料。記錄 Function,繼續讀 Header Type、Class Code 與必要的 Capability。先確認不是 RRS 可見性機制使用的特殊值。
平台以約定方式回報該位置沒有 Function。略過這個位置,繼續其他合法候選位置。例如依賴全 1 讀值的軟體,須搭配會對 UR 合成全 1 的 Root Complex。
收到符合條件的 RRS 可見資料。標為暫時未就緒,依平台與適用規則安排重試。不能把特殊 Vendor ID 當成一個真正廠商。
存取失敗、逾時或路徑尚未建立。保留失敗原因,先處理路徑或就緒問題。不能把任意 buffer 值當成不存在,也不能宣稱實體卡一定不在。

UR 是 Unsupported Request,表示該要求無法依適用規則被接受。RRS 是 Base 6.0 的 Request Retry Status,表示在規格允許的情況下,接收端暫時不能處理要求。RRS 不是要求遺失,也不是可在任何時刻任意使用的忙碌通知。

Vendor ID 與讀值合成的來源

Vendor ID:Base 6.0 §7.5.1.1.1,p.917。未實作的 Bus/Device/Function 對設定要求回 UR:§7.3.1,p.911。對依賴全 1 讀值的軟體,Root Complex 應合成資料的要求見 §2.3.2 的 implementation note,p.221。這不表示 UR Completion 本身帶著全 1 payload;非成功 Completion 不帶讀取資料。

3. 還不知道下一層有多深,Subordinate 要先填多少?

先沿已就緒的正常案例往下找。讀取 Bridge 的 Header Type 與 PCIe 類型,再依 Figure 7-14 找到 Secondary(0x19)與 Subordinate(0x1A);兩者各為 8 bits、可讀寫。Secondary 先指定下一層 Bus,Subordinate 暫時涵蓋仍可能分配的範圍,讓後續查詢有路可走。

本例已知平台可用上限是 3F,因此用 3F 作暫時上限,沒有任意擴到 FF。每次先完成必要的 Configuration Write,再探查新的下游位置;寫入完成的確認依平台存取機制處理,不把 CPU 已送出存取當成遠端已完成設定。

教學枚舉時間表:先往下找,再回填範圍
步驟本次設定或探查為什麼下一步走得通?
1Root Port 00:01.0:Secondary=01,Subordinate=3F。開放下一層 Bus 01,以及尚待探查的下游範圍。
2在 01:00.0 找到 Switch Upstream Port;設 Secondary=02,Subordinate=3F。可以探查 Switch 內部 Bus 02。
3在 02:01.0 找到 Downstream A;設 Secondary=03,Subordinate=3F。沿 A 的 Link 探查 Bus 03 的 Device 00。
4找到 03:00.0,Header Type=80h;再確認 03:00.1 存在。完成本分支後,把 A 的 Subordinate 改為 03。本例 A 下方沒有更深 Bridge;後續號碼可交給另一分支。
5回 Bus 02,找到 02:02.0 的 Downstream B;設 Secondary=04,Subordinate=3F。A 已縮回 03,不會與 B 的暫時範圍重疊。
6找到 04:00.0,Header Type=00h;本分支完成,把 B 的 Subordinate 改為 04。本例是單功能 Device,沒有其他機制指示須探查更多 Function。
7Switch Upstream Port 的 Subordinate 改為 04,Root Port 的 Subordinate 也改為 04。兩者保留完整下游範圍,形成 Chapter 1 的最終快照。

Function 0 的 Header Type=80h 只是允許繼續探查,並沒有說 Function 1 一定存在。表中的「確認 03:00.1 存在」是另一筆有效結果。本例另外假設其他合法候選位置沒有新 Function;即使某個 Function Number 不存在,也不能自行推出後面所有號碼都不存在。

普通 Link 對端與 Switch 內部 Bus 的候選位置也不同。非 ARI、未使用 FPB 時,外部 Link 的對端關聯到 Device 0;內部的 Downstream Port 則可用其他 Device Number。因此不能為了讓表格整齊,就只在 Bus 02 查 Device 0 而漏掉本例的 Device 01、02。

ARI
Alternative Routing-ID Interpretation,替代路由識別碼解讀
FPB
Flattening Portal Bridge,扁平化入口橋接器
時間表所依據的 Register 與規則

Base 6.0 §7.5.1.3,Figure 7-14,p.936;Secondary/Subordinate 的語義與 RW 屬性:§7.5.1.3.3–§7.5.1.3.4,p.937。Header Type:Table 7-7,p.925。Device Number 限制:§7.3.1,p.911。ECAM 寫入完成的保障要求:§7.2.2,p.908。本例不使用 Primary Bus Number 推自身 BDF,原因見 Chapter 1。深度優先次序、3F 暫時上限及最後緊縮範圍是教學策略。

4. 讀到 0xFFFF0001,是什麼裝置?

先不要把它拆成一般 Vendor/Device ID。若 Root Port 支援並已啟用 Configuration RRS Software Visibility,而且 Configuration Read 包含 Vendor ID 的兩個 bytes,Root Complex 在收到 RRS 時,會讓軟體讀到 Vendor ID = 0001h;同筆讀取的其他 bytes 則回報全 1。

RRS 可見性案例的讀取
對象與 byte offset寬度假設讀值判讀
Root Port,0x70 + 0x1E = 0x8E16 bits0x0001Root Capabilities bit 0 = 1,支援可見性。
Root Port,0x70 + 0x1C = 0x8C16 bits0x0010Root Control bit 4 = 1,已啟用。
目標 Function,0x0032 bits0xFFFF0001本情境中的 RRS 合成讀值;不是真實 Vendor/Device ID。

查詢次序是先由 Figure 7-21 找 Root Capabilities 與 Root Control 的位移,接著用 Figure 7-34/Table 7-31 查能力,再用 Figure 7-33/Table 7-30 查啟用狀態,最後回 §2.3.2 解釋 0001h 的特殊意義。它是 PCI-SIG 為此用途保留的值,不對應任何已分配的 Vendor ID。

若只讀 16-bit Vendor ID,特殊值會是 0x0001;本例讀了 32 bits,才看到 0xFFFF0001。若沒有啟用這項可見性,或讀取沒有同時涵蓋 Vendor ID 的兩個 bytes,就不能要求 Root Complex 用這個資料格式回報;適用時由 Root Complex 重新發出設定要求。

教材不把「等固定一秒」當成所有 Reset 的共同答案。重試期限要連同 Reset、Readiness 與平台策略判斷;用完允許的等待仍未就緒,應記為初始化或存取未完成,不能假裝已取得有效 Vendor ID。

RRS 的精確依據與邊界

Base 6.0 §2.3.1,p.211 列出可回 RRS 的 Reset 與禁止條件;p.214 的 implementation note 說明軟體可見性。實際 Root Complex 處理見 §2.3.2,pp.220–221。Register 位置:Figure 7-21,p.952;§7.5.3.12,Figure 7-33/Table 7-30,pp.986–988;§7.5.3.13,Figure 7-34/Table 7-31,p.988。本章使用 Base 6.0 的 RRS 名稱。

5. 對 Endpoint 讀設定時,Type 1 到哪裡變成 Type 0?

這一節的 Type 指 Configuration Request 的封包類型,不是 Configuration Header 的布局。Header Type 1 的 Bridge 也會接受對自身設定空間的 Type 0 Request;兩者名稱相同,不代表一一配對。

一般路由規則可整理為下面的分支。前提是符合本章的正常傳統配置,且要求的 Device/Function 與其他欄位也有效。

遇到 Type 1 Configuration Request 時,往哪裡送?
目標 Bus 與下游關係處理方式
正是某個對外 Port 的下一層 Bus,且 Device 解碼符合。將要求改為 Type 0,再送向該 Link 的對端。
還在該分支涵蓋的更深層範圍。保持 Type 1,繼續送往該下游分支。
不屬於有效分支。依 Unsupported Request 規則處理,不憑猜測廣播到所有 Link。

案例推演:目標是 03:00.1。Root Port 的下一層是 Bus 01,而目標 Bus 03 位於其下游範圍,所以外部 Link 上仍送 Type 1 給 Switch。Switch 再辨識 Bus 03 正好是 Downstream A 的 Link 所對應的 Bus,便在送向 Endpoint 前轉成 Type 0。Endpoint 最後以 Function 1 與 Register 位移處理要求。

Switch 內部是邏輯設定拓樸;本例沒有假設內部真的有另一條實體 PCIe Link,或每個 virtual Bridge 都要在實體線路上產生一份封包。這裡只描述規格要求的對外路由結果。

路由規則的來源

Base 6.0 §7.3.2–§7.3.3,pp.912–913。Endpoint 對 Type 1 Configuration Request 依 UR 處理;Root Port/Switch 對有效的本地 Type 0 Request 則處理自身設定空間。本節沒有將 Type 0/Type 1 的角色延伸到所有其他 TLP。

裝置的 Requester ID 從哪裡來?

前一節沿路由找到 Endpoint;現在換到 Endpoint 自己發出要求的方向。Non-Flit Configuration Request 的 Figure 2-33 同時有 Requester ID 和 Destination ID:前者是這筆設定要求的發起者,後者指出要設定的 Function。兩者有不同角色,不能拿主機發起設定時的 Requester ID 當成 Endpoint 日後發起交易的身分。

【模擬資料】以下資料為教學用途建立,不代表特定硬體或平台。沿用一般非 ARI 的 Endpoint Function 03:00.0,不使用 Shadow 或 Phantom Function。假設設定路徑已建立,主機送達一筆合法的 Type 0 Configuration Write,目標是這個 Function,並得到成功完成回覆。

讀 §2.2.6.2:Function 必須從由它完成的 Type 0 Configuration Write 擷取 Bus 與 Device Number,並將擷取值用在它自身發起要求的 Requester ID。規格建議只在成功完成的要求上擷取;本例已假設成功。Function Number 仍是該 Function 的身分,因此本例正常組成的 Requester ID 是 0300h,不是主機那筆 Configuration Write 的 Requester ID。

如果平台之後需要重新配置 Bus Number,先依 §6.4 完成相關工作停止與未完成交易的協調。假設新配置將同一 Function 設為 04:00.0,且它完成新的 Type 0 Configuration Write,Function 便需重新擷取新的 Bus/Device 值;後續自身發起的要求使用更新後的身分。本例不表示軟體可以在交易仍進行時直接改號。

首次 Configuration Write 之前,Function 不得發起 Non-Posted Request(需要 Completion 的要求),因為回覆需要有效的 Requester ID。規格對 Root Complex 內的 Functions 存取系統開機裝置有例外;本例一般 Endpoint 不套用該例外。完成設定寫入後,仍須檢查 Bus Master Enable、資源與裝置初始化;取得身分本身不代表可以立即開始 DMA。

DMA
Direct Memory Access,裝置直接存取記憶體

ARI(Alternative Routing-ID Interpretation,替代路由識別方式)的 Bus 擷取方式另見 Chapter 26。Flit Mode Segment 與 Shadow Function 也有各自的識別規則,應查 §2.2.6.2,不套用本例的 BDF 拆解。

BDF
Bus/Device/Function,匯流排、裝置與功能識別

PCI Express Base 6.0 §2.2.6.2,文件頁/PDF 頁 156–157;§2.2.7.1、Figure 2-33,pp.164–165;§6.4 Device Synchronization,pp.717–718。

Flit Mode 的 Configuration Write 如何帶入 Segment?

前面用 Bus、Device、Function 辨識同一階層內的 Endpoint。Flit Mode 還有獨立的 Segment 欄位,可協助跨 Hierarchy(階層)的識別與路由。先讀 §2.2.1.2 的 Segment Rules:Root Port 以 Flit Mode 送出的 Configuration Request,必須帶 OHC-A3,並設置 Destination Segment Valid(DSV,目的 Segment 有效位)及正確的 Destination Segment;即使系統只有一個 Segment 也一樣。

【模擬資料】以下資料為教學用途建立,不代表特定硬體或平台。假設 Root Port 直接連接一般 Endpoint 03:00.0,這條 Link 正以 Flit Mode 運作。平台將該階層配置為 Segment 02h,並向這個 Function 傳送合法的 Type 0 Configuration Write。假設本次寫入的 1 DW 全部 bytes 都啟用,所選 Register 允許這樣寫入;Payload 與基本 Header 的其他欄位省略。

DW
Double Word,4 bytes的資料單位

沿 Figure 2-6 找到 Header Base 後,再由 Table 2-6 選 Configuration Request 的 OHC-A3。Figure 2-9 顯示 OHC-A3 占 1 DW:byte 0 是 Destination Segment,byte 2 的 bit 7 是 DSV,byte 3 是 Last/First DW Byte Enable。本例的 OHC-A3 四個 bytes 可寫成 02 00 80 0F,分別表示 Segment=02h、DSV=1、Last DW BE=0000b、First DW BE=1111b;其餘保留位在這個模擬封包中為 0。

DW
Double Word,4 bytes的資料單位

如果 Endpoint 成功完成這筆 Flit Mode Type 0 Configuration Write,就依 §2.2.6.2 擷取 Destination Segment。再查 Device 3 Extended Capability:假設已找到其起點 200h,Figure 7-124/Table 7-110 的 Device Status 3 在相對位移 0Ch,所以讀取位置是 20Ch。Status 的 Segment Captured 是 bit 3、屬性 RO;這次收到的 DSV=1,因此該 bit 為 1。這個 bit 只表示有效 Segment 已擷取,不提供 Segment 的數值;本例的 02h 是從設定要求取得。

假設這筆 Configuration Write 的 Completion 因其他適用條件而帶有 OHC-A5。接收端要依 Figure 2-11 與 Segment Rules 判讀:Completer Segment 使用剛擷取的 02h,而 Configuration Completion 的 DSV 必須清為 0、Destination Segment 必須為 00h。不需要 OHC-A5 的完成回覆可依其適用條件省略它;不能只因 Request 的 DSV=1,就要求所有 Completion 都複製同一個 DSV。

若 Function 收到的是 Non-Flit Mode 的 Configuration Write,§7.7.9.4 要求清除 Segment Captured。這個情況不表示 Segment 值一定是零;DSV 清除時,相關 Destination Segment 欄位是 Reserved。讀到某一時點的 Status,也不能單獨還原完整的路徑模式歷史。

擷取 Segment、具備 Requester ID 與允許裝置發起 DMA 是不同檢查。一般 Memory Request 是否附帶 Requester Segment,還要依其類型與 §2.2.1.2 的條件判斷;不應因 Segment Captured=1 就假設每筆 Memory Request 都必定帶 OHC-C。

DMA
Direct Memory Access,裝置直接存取記憶體

PCI Express Base 6.0 §2.2.1.2、Figures 2-6、2-9、2-11/Table 2-6,文件頁/PDF 頁 123、131–133、134–135、140;§2.2.6.2,p.157;§2.2.9.2,p.199;§7.7.9.1、§7.7.9.4、Figures 7-121、7-124/Tables 7-107、7-110,pp.1072–1073、1076–1077。

已知目標 BDF,讀取卻失敗時,先檢查哪一段?

沿用本章的拓撲,目標是 Endpoint 的 03:00.1。先找到連向它的分支,再由根部向下檢查每個 Bridge 的 Secondary/Subordinate Bus Number,確認目標 Bus 是否落在該分支的設定範圍。這裡的檢查順序是查閱方法,不代表硬體一定以這個時間順序處理。

讀規格時,先用 Figure 7-14 找 Secondary/Subordinate 的位置,再讀 §7.5.1.3.3–7.5.1.3.4 了解各欄位所記錄的範圍;接著到 §7.3.3 判讀 Type 1 Request 的轉送與轉換。若寫入採 ECAM,§7.2.2 要求平台提供軟體可確認寫入已由 Completer 完成的方法;本例不指定平台必須採用哪一種方法。(Base 6.0,文件頁/PDF 頁 908、912–913、936–937。)

Function 不存在,和其中一個 Register 未實作,有什麼不同?

以可觀察到 PCIe Completion 的資料為例:指定未實作的 Bus、Device 或 Function 時,§7.3.1 規定回 Unsupported Request(UR);對已實作 Function 內未實作的 Register 讀取,在沒有其他需回報的錯誤時,§7.3.3 規定回 Successful Completion,讀取資料為 0。兩者的目標與結果不同。

如果只看到軟體的讀值,仍要先確認存取是否成功、讀的是哪個 BDF 與 offset,以及平台如何呈現交易結果。Root Complex 在 §2.3.2 所述的條件下,會為依賴全 1 讀值的軟體合成 UR 讀取結果;那不是 UR Completion 自帶的 payload。RRS 的特殊值則依前面的就緒情境判讀。(Base 6.0,文件頁/PDF 頁 220–221、911、913。)

6. 能列出 BDF,就表示裝置已經可以工作嗎?

這次搜尋完成後,系統有了 Function 清單與下游路徑,但還沒有因此完成 BAR 資源配置、開啟 Memory Space,或準備驅動程式的工作資料。Vendor/Device ID 和 Class Code 能提供識別與驅動選擇線索,也不等於初始化已成功。

BAR
Base Address Register,基底位址暫存器

枚舉也不保證全由韌體一次做完。Firmware 3.3 §3.5 要求韌體配置開機與主控台裝置的完整路徑,以及所有 Host Bridge;其他裝置可以留給 OS 處理。因此,OS 看到某個 Endpoint 尚未配置,不能僅憑這件事宣告韌體違反規格。若要檢查交接,應先確認它是不是被要求完成的那條路徑。

來源與下一步

Base 6.0 §7.5.1.1.1–§7.5.1.1.2,p.917;Class Code:§7.5.1.1.6,Figure 7-7/Table 7-6,pp.923–924。PCI Firmware 3.3 §3.5,pp.34–35。資源與命令控制位在 Chapter 4 接續處理。

7. 沿著不同條件調整發現流程

Root Port 只把下游上限開到 Bus 01,還沒找到 Switch 下方的 Bus 03,就能直接跳去讀 03:00.0 嗎?

不能假設走得通。先要為通往 Bus 03 的各層 Bridge 建立一致且有效的 Bus 範圍。對目前不屬於有效路徑的要求,規格允許的結果不是「幫你找到裝置」,而是按 UR 規則處理。(§7.3.3,pp.912–913。)

Function 0 的 Header Type 是 00h,可以為了保險一律掃 Function 1–7 嗎?

本章沒有 ARI/SR-IOV 等額外指示,因此不可以。Table 7-7(p.925)在 Multi-Function Device bit 清除時禁止這種探查。若 bit 設定,允許探查也不等於那些 Function 已存在。

SR-IOV
Single Root I/O Virtualization,單根I/O虛擬化
讀到 0xFFFF0001,就把 Device ID FFFFh 當成未知型號繼續初始化,問題在哪裡?

若符合本章的 RRS 可見性條件,整個讀值是 Root Complex 為重試狀態合成的資料,尚未取得真正的 Vendor/Device ID。應處理就緒與重試,不能據此選驅動或讀取假想的裝置欄位。(§2.3.2,p.220。)

最終 Subordinate 比本例的 04 大,就一定錯了嗎?

不一定。本例採完成後緊縮到實際使用範圍的策略;平台可能依法配置並保留額外 Bus Number。要檢查的是平台授予的範圍、各分支是否一致,以及保留政策,不能把本例的數字當成唯一合法答案。

8. 找到裝置之後,還欠哪一步?

接著讀 Chapter 4:BAR、位址空間與資源配置。那一章會從裝置需要多少空間開始,算出大小與對齊,檢查沿途 Bridge Window,再分清 Memory Space Enable 與 Bus Master Enable。

BAR
Base Address Register,基底位址暫存器

版本與來源

PCI Express Base Specification Revision 6.0 與 PCI Firmware Specification Revision 3.3;精確位置附於各節。Firmware 3.3 的 Base 參考版為 5.0,本章欄位和 RRS 行為均取自 Base 6.0。枚舉順序與 Bus Number 配置是作者推演,不是原文指定程序。查核日期:2026-10-28。