6. PCI 主橋的 ACPI 考量

一般規則是,除非作業系統有其他方法可以找到它,否則 ACPI 名稱空間應描述作業系統可能使用的所有內容 [1, 2]。

例如,沒有標準硬體機制來列舉 PCI 主橋,因此 ACPI 名稱空間必須描述每個主橋、訪問其下方 PCI 配置空間的方法、主橋轉發到 PCI 的地址空間視窗(使用 _CRS),以及傳統 INTx 中斷的路由(使用 _PRT)。

PCI 裝置(位於主橋下方)通常不需要透過 ACPI 描述。作業系統可以透過標準 PCI 列舉機制發現它們,使用配置訪問來發現和識別裝置,並讀取和確定其 BAR 的大小。然而,如果 ACPI 為 PCI 裝置提供電源管理或熱插拔功能,或者如果裝置的 INTx 中斷由平臺中斷控制器連線,並且需要 _PRT 來描述這些連線,那麼 ACPI 可能會描述 PCI 裝置。

ACPI 資源描述透過 ACPI 名稱空間中裝置的 _CRS 物件完成 [2]。_CRS 就像一個通用化的 PCI BAR:作業系統可以讀取 _CRS 並確定正在消耗什麼資源,即使它沒有裝置的驅動程式 [3]。這很重要,因為這意味著舊的作業系統即使在具有作業系統未知的新裝置的系統上也能正常工作。新裝置可能什麼也做不了,但作業系統至少可以確保沒有資源與它們衝突。

像 MCFG、HPET、ECDT 等靜態表不是用於保留地址空間的機制。靜態表用於作業系統在啟動早期、在解析 ACPI 名稱空間之前需要了解的事物。如果定義了新表,舊的作業系統需要正確執行,即使它忽略該表。_CRS 允許這樣做,因為它具有通用性並被舊的作業系統理解;而靜態表則不能。

如果作業系統預期管理透過 ACPI 描述的不可發現裝置,則該裝置將具有特定的 _HID/_CID,告訴作業系統繫結哪個驅動程式,而 _CRS 則告訴作業系統和驅動程式裝置的暫存器在哪裡。

PCI 主橋是 PNP0A03 或 PNP0A08 裝置。它們的 _CRS 應描述它們所消耗的所有地址空間。這包括它們轉發到 PCI 匯流排的所有視窗,以及未轉發到 PCI 的主橋自身的暫存器。主橋暫存器包括諸如確定橋下匯流排範圍的輔助/從屬匯流排暫存器、描述孔徑的視窗暫存器等。這些都是裝置特定的、非架構化的東西,因此 PNP0A03/PNP0A08 驅動程式管理它們的唯一方法是透過包含裝置特定詳細資訊的 _PRS/_CRS/_SRS。主橋暫存器還包括 ECAM 空間,因為它被主橋消耗。

ACPI 定義了一個 Consumer/Producer 位來區分橋接暫存器(“Consumer”)和橋接孔徑(“Producer”)[4, 5],但早期的 BIOSes 沒有正確使用該位。結果是,當前的 ACPI 規範僅為擴充套件地址空間描述符定義了 Consumer/Producer 位;在舊的 QWord/DWord/Word 地址空間描述符中應忽略該位。因此,作業系統必須假定所有 QWord/DWord/Word 描述符都是視窗。

在新增擴充套件地址空間描述符之前,Consumer/Producer 的失敗意味著無法在 PNP0A03/PNP0A08 裝置本身中描述橋接暫存器。解決方法是在 PNP0C02 包羅永珍的裝置中描述橋接暫存器(包括 ECAM 空間)[6]。除了 ECAM,橋接暫存器空間都是裝置特定的,因此通用的 PNP0A03/PNP0A08 驅動程式 (pci_root.c) 不需要了解它。

新架構應該能夠在 PNP0A03 裝置中使用“Consumer”擴充套件地址空間描述符來描述橋接暫存器,包括 ECAM,儘管對 [6] 的嚴格解釋可能禁止這樣做。舊的 x86 和 ia64 核心假定所有地址空間描述符,包括“Consumer”擴充套件地址空間描述符,都是視窗,因此在這些架構上以這種方式描述橋接暫存器是不安全的。

PNP0C02 “主機板”裝置基本上是一個包羅永珍的裝置。除了“不要將這些資源用於其他任何目的”之外,沒有它們的程式設計模型。因此,PNP0C02 _CRS 應該宣告任何(1)未被 ACPI 名稱空間中任何其他裝置物件下的 _CRS 宣告,且(2)不應由作業系統分配給其他事物的地址空間。

PCIe 規範要求使用增強配置訪問方法 (ECAM),除非存在用於配置訪問的標準韌體介面,例如 ia64 SAL 介面 [7]。主橋消耗 ECAM 記憶體地址空間並將記憶體訪問轉換為 PCI 配置訪問。該規範定義了 ECAM 地址空間佈局和功能;只有地址空間的基址是裝置特定的。ACPI 作業系統從靜態 MCFG 表或 PNP0A03 裝置中的 _CBA 方法學習基址。

MCFG 表必須描述非熱插拔主橋的 ECAM 空間 [8]。由於 MCFG 是一個靜態表,無法透過熱插拔更新,因此 PNP0A03 裝置中的 _CBA 方法描述了熱插拔主橋的 ECAM 空間 [9]。請注意,對於 MCFG 和 _CBA,基址始終對應於匯流排 0,即使橋下匯流排範圍(透過 _CRS 報告)不從 0 開始。

[1] ACPI 6.2,第 6.1 節

對於任何位於不可列舉匯流排型別(例如 ISA 匯流排)上的裝置,OSPM 會列舉裝置的識別符號,並且 ACPI 系統韌體必須為每個裝置提供一個 _HID 物件……以使 OSPM 能夠做到這一點。

[2] ACPI 6.2,第 3.7 節

作業系統只需讀取 ACPI 名稱空間,查詢具有硬體 ID 的裝置即可列舉主機板裝置。

ACPI 列舉的每個裝置在 ACPI 名稱空間中都包含 ACPI 定義的物件,這些物件報告裝置可能佔用的硬體資源 [_PRS]、報告裝置當前使用的資源的物件 [_CRS] 以及用於配置這些資源的物件 [_SRS]。這些資訊由即插即用作業系統 (OSPM) 用於配置裝置。

[3] ACPI 6.2,第 6.2 節

OSPM 使用裝置配置物件來配置透過 ACPI 列舉的裝置的硬體資源。裝置配置物件提供有關當前和可能的資源要求、共享資源之間的關係以及配置硬體資源的方法的資訊。

當 OSPM 列舉裝置時,它會呼叫 _PRS 來確定裝置的資源要求。它還可以呼叫 _CRS 來查詢裝置的當前資源設定。使用此資訊,即插即用系統確定裝置應消耗哪些資源,並透過呼叫裝置的 _SRS 控制方法來設定這些資源。

在 ACPI 中,裝置可以消耗資源(例如,傳統鍵盤),提供資源(例如,專有 PCI 橋),或兩者兼而有之。除非另有說明,否則裝置資源被假定取自裝置層次結構中裝置上方最近的匹配資源。

[4] ACPI 6.2,第 6.4.3.5.1、2、3、4 節
QWord/DWord/Word 地址空間描述符 (.1, .2, .3)

通用標誌:位 [0] 忽略

擴充套件地址空間描述符 (.4)

通用標誌:位 [0] 消費者/生產者 (Consumer/Producer)

  • 1 – 此裝置消耗此資源

  • 0 – 此裝置生成並消耗此資源

[5] ACPI 6.2,第 19.6.43 節

ResourceUsage 指定記憶體範圍是由此裝置消耗 (ResourceConsumer) 還是傳遞給子裝置 (ResourceProducer)。如果未指定,則假定為 ResourceConsumer。

[6] PCI Firmware 3.2,第 4.1.2 節

如果作業系統不原生理解保留 MMCFG 區域,則 MMCFG 區域必須由韌體保留。MCFG 表中報告的地址範圍或由 _CBA 方法(參見第 4.1.3 節)報告的地址範圍必須透過宣告主機板資源來保留。對於大多數系統,主機板資源將出現在 ACPI 名稱空間的根部(_SB 下),位於具有 EISAID (PNP0C02) _HID 的節點中,並且在這種情況下,不應在根 PCI 匯流排的 _CRS 中宣告資源。資源可以選擇透過 Int15 E820 或 EFIGetMemoryMap 作為保留記憶體返回,但必須始終透過 ACPI 報告為主機板資源。

[7] PCI Express 4.0,第 7.2.2 節

對於與 PC 相容或未實現允許訪問配置空間的處理器架構特定韌體介面標準的系統,需要本節中定義的 ECAM。

[8] PCI Firmware 3.2,第 4.1.2 節

MCFG 表是一個 ACPI 表,用於在啟動時向作業系統傳達 PCI 段組內非熱插拔 PCI 段組範圍對應的基址。這對於 PC 相容系統是必需的。

MCFG 表僅用於傳達系統啟動時可用的 PCI 段組對應的基址。

[9] PCI Firmware 3.2,第 4.1.3 節

_CBA(記憶體對映配置基址)控制方法是一個可選的 ACPI 物件,它返回支援熱插拔的主橋的 64 位記憶體對映配置基址。_CBA 返回的基址是處理器相關地址。_CBA 控制方法評估為一個整數。

此控制方法出現在主橋物件下。當 _CBA 方法出現在活動主橋物件下時,作業系統評估此結構以識別與 _CRS 方法中指定的匯流排號範圍對應的 PCI 段組的記憶體對映配置基址。包含 _CBA 方法的 ACPI 名稱空間物件也必須包含相應的 _SEG 方法。