一.ACPI 熱拔插的簡介 由 INTEL,MICROSOFT 及 TOSHIBA 所共同開發而成的 ACPI(Advanced Configuration & Power Interface,先進架構電源配置標准)能使軟、硬件、操作系統(OS),主機板和外圍設備,依照一定的方式管理用電情況,系統硬件產生的 Hot-Plug 事件,讓操作系統從用戶的角度上直接支配即插即用設備,不同於以往直接通過基於 BIOS 的方式的管理。 這種技術對系統平台、外插板卡硬件上都有特定的要求:系統集成熱插拔控制集成電路(PHP ASIC)和 PCI 插槽的逆電流控制器,這樣在系統啟動過程中可以自動監測 PCI 插槽上是否有設備,當探測到 PCI 插槽上無設備時,能夠自動將該插槽斷電,在系統的 ACPI BIOS 中包含一系列硬件存儲空 PCI 插槽的資源信息如地址段、中斷號等以便提供給 Hot Plug 的插卡所用的資源列表 ACPI Table,這些資源列表在上電之後用於進行 PCI 設備的枚舉和配置,目前南橋芯片上都集成了 ACPI 協議,例如在 Intel 82801DB I/O Controller Hub 4(ICH4)。 ACPI 基本的體系結構如圖 1 所指示: ACPI 系統由主板總線系統的電氣特性支持、主板 BIOS 支持、ACPI 層、操作系統熱插拔功能的總線驅動構成。 隨著 Intel 64 位 PCI 技術的成熟,Microsoft、Novell 和 SCO 開發的操作系統都開始全面支持 PCI設備 ACPI 熱插拔技術(PCI Hot Plug)。 Linux 內核從 2.4 開始支持 ACPI 技術,而到了 2.6.0 以上版本的內核全面支持 ACPI 下的 Hot-plug 規范;根據這個基礎,在下面,我們將要從底層的角度和應用的角度上詳細介紹基於"傳統的"x86 體系下 ACPI PCI 熱插拔設備 Linux kernel 下的驅動構成和 ACPI 層上工作模式和流程(在上半部分將介紹基本原理和命令形模式),向非 x86 平台移植的注意事項,以及一些 Linux ACPI 熱拔插設備驅動程序開發的注意事項。
二.ACPI 驅動體系簡介 ACPI 驅動體系是支持 ACPI Hot Plug 的基礎,在論述 Hot Plug 之前首先要介紹 ACPI 體系,根據ACPI 規格定義的 ACPI 驅動體系(簡稱 ACPI CA),目前 ACPI 組織已經提供了完整的 Unix 版本的ACPI 驅動體系,這個體系主要目的在於讓操作系統和當前的 ACPI 硬件隔離開,讓 Linux 中通過一系列的接口來訪問 ACPI 層。下面列出 ACPI CA 的接口,例如電源管理和配置,熱拔插等等: 在 ACPI 規范中將 ACPI 體系分割成 ACPI 核心層(Core subsystem),用於提供基本的 ACPI 服務(AML 翻譯和名字空間管理);OS 服務層(OS service)提供針對不同的操作系統的和 ACPI 單元接口服務,下面將詳細介紹它們。 a. ACPI 核心層: ACPI 核心層分成幾個相互關聯的邏輯模塊,每個模塊之間包含一些相關的 ACPI API,當用戶在編寫相關的含有 ACPI 服務的驅動程序的時候,會調用這些相關模塊的接口。 1. AML Interpreter: 從上可知AML(後面將詳細介紹)分析器是基礎,負責分析和運行從本地計算機 BIOS 提供的 AML 文件流,一般說來 AML 翻譯器為其他的 ACPI 服務模塊提供方法節點運行和獲得名字空間中某個方法節點的對象服務。 2. ACPI Table Management 是一個負責載入,管理,分析,校驗 ACPI 模塊中所使用的各種來自系統 BIOS 的一些特殊的支持 ACPI 服務的表格,例如:RSDT,FSDT,FACS,DSDT等等,這些表在操作系統進行初始化的時候被載入內存。 3. Namespace Management 在 AML 翻譯器之上提供名字空間服務,它負責創建和管理內部的名字空間。 4. Resource Management:資源管理提供建立在名字空間資源的配置和獲取,其中包括了 PCI的設備的地址區間,中斷等重要參數。它所提供的服務包括:獲取和設定當前的資源,獲取設備上可能存在的地址區間以及 PCI 設備的中斷路由表(IRQ Routing Tables),獲取當前設備的電源支持能力(例如是否支持 S1-S5 狀態)。 5. ACPI H/W Management:該模塊用於控制對橋芯片上 ACPI 寄存器和時鐘以及其他 ACPI 關聯硬件的訪問,例如 ACPI GPE 狀態寄存器和使能寄存器,系統狀態獲得。 Event handling:事件管理模塊是用於管理系統控制中斷(SCI)的發生和 GPE 事件的響應,SCI 包括 ACPI 時鐘中斷,以及 GPE 事件管理。這個單元負責"分發"地址空間和操作空間(OperationRegion)的事件到當前的操作系統層,並負責調用相關的句柄來進行處理。 b.OS 服務層: ACPI OS 服務層(OSL)可以讓 ACPI 邏輯模塊在本地操作系統上運行。OS 服務層通過可在主機操作系統中使用的接口,設備驅動程序,將從 ACP 核心的服務轉換成本地操作系統的訪問和調用;而操作系統層通過 OSL 向 ACPI 核心層發出呼叫;OSL 層對 ACPI 核心層實現了一系列完成操作系統獨立功能的標准接口(例如存儲分配和硬件訪問)。 OSL 的組成模塊介紹: 1.OS 引導服務: 在 OS 載入過程中引導服務是一些初始化的功能,在大多數其它的操作系統初始化之前執行。這些服務包括 ACPI 子系統的初始化。 2.設備驅動載入服務: 對於出現在 ACPI 名字空間中的設備節點,操作系統必須有一個模塊用以探測到它們並載入驅動,讀入配置空間,設備驅動載入服務提供這項裝置。 3.操作系統運行服務: 運行服務包括大部分 ACPI 系統和 OS 交互的外圍接口,用於當前內核的進程/線程操作,以及提供和當前操作系統接口的互斥,信號,進程隊列,休眠,暫停等,以及事件日志及電源管理功能。 4.異步服務 異步功能包括中斷服務(系統控制中斷),事件處理和分配(既定事件,GPE 事件,通知事件和操作區訪問事件),以及錯誤處理。 從 OS 至 ACPI 子系統的請求: ACPI 核心層和 ACPI OS 層,以及操作系統之間的關系如下: 從上面我們看到了在 Linux2.6.6 中提供了一個完整的符合 ACPI 規范的 ACPI 核心層和 OS 接口函數,不過我們下面論述到的 ACPI PCI 設備熱拔插只會用到其中的很小一個部分。
三.ACPI 體系中的重要名詞 DSDT: DSDT 稱做 Differentiated Definition Block,存在於 BIOS 中並與當前的硬件平台兼容的,提供了系統的硬件特性(例如某些設備的內部寄存器和存儲器)的應用策略和配置,在系統初始化的時候,DSDT 被當前系統啟動時初始化到名字空間中。 FADT:FADT 中包含了 ACPI 的硬件寄存器組(GPE)的應用和配置(包含它們的硬件地址)也包括DSDT表的硬件地址。 ACPI Namespace: 對於ACPI層來說,內存維持了一個目錄形式的指向每個設備,以及 GPE 的名字空間,這個名字樹是通過初始化的時候由 DSDT 創建的,名字樹可以通過 loadtable 方法從 BIOS 中載入 DSDT 改變,而每個設備在 ACPI 層中都被描述成一個對象,包含有對這個設備特性和操作策略的描述列表,系統所有類型設備都是保存在同一個名字樹下。在 ACPI OS 層上調用 _ADR 來獲得 Namesapce 的設備名,Namespace 的例子見例 1-1: OSPM(OS-directed Power Management):OSPM 操作系統支持 ACPI 的一個部分,操作系統 (OS)可以從操作系統下驅動程序的角度控制 ACPI 子模塊,同時支持 ACPI 包括 SCI 中斷,設備事件,系統事件模式,這些事件模式可以充分支持 Hot-plug 方式。 SCI 中斷:(System Control Interrupt) 系統控制中斷,SCI 中斷是一種源自 ACPI 兼容芯片系統中斷,系統映射不同的 ACPI 事件中斷向量以便共享此中斷,當底層硬件產生 SCI 中斷的時候(例如設備插入事件引發中斷),根據通知 OSPM 層處理相對應的 ACPI 事件,OSPM 層會調用預先安裝的中斷句柄。 GPE Block Device 和 GPE 事件:GPE Block Device 是平台設計者可按照 FADT(Fixed ACPI Descriptor Table) 描述表中響應 GPE 的寄存器組,GPE 的輸入腳。作為 GPE 設備描述塊中的地址存在於 FADT 中,每個 GPE Block Device 可以容納 128 個 GPE 事件,ACPI 層上提供兩個通用目標寄存器組--GPE0_BLK 和 GPE1_BLK,(也就是說可以響應 256 個 GPE 事件)每個寄存器組中包含兩個等長度的寄存器 GPEx_STS,GPEx_EN,他們的系統地址(硬件地址)都保存在 FADT 中,作為 GPE Blocks 的行為(或者是操作)描述部分存在於 ACPI 名字空間中;用於指示當前的設備的事件,例如設備插入/拔除事件發生的時候,相關的狀態位(GPEx_STS中的位,這個是在硬件設計的時候相關設備的事件信號會連接到這些狀態位)會被外部的事件所置位,生成 SCI,讓 OSPM 層運行相關的控制程方法通知 ACPI 層;GPEx_EN 表示每個事件的使能位,一般說來在南橋(ICH4)中有這幾個寄存器,它們的硬件地址保存在 FADT 中。 GPE 事件就是通過 GPE 寄存器組引發 SCI 中斷後,通告 OSPM 層有關設備的事件,例如下面介紹 Hot-Plug 的時候會詳細或者簡略地介紹到總線枚舉,設備檢查,設備喚醒,設備彈出幾個事件。 ACPI Source Language(ASL):ASL 語言是 ACPI 層用於描述特定的 ACPI 對象的 ACPI 專用語言,並且包括了 ACPI 對象的控制方法(Control method),OEM 廠商和 BIOS 設計者在 BIOS 中使用 ASL 定義所有的設備為 ACPI 對象,並且可以生成 ASL 格式的專門的控制方法,1-1 例就是關於 ASL 的例子: ASL 的語法規參看 ACPI Specification Revision 2.0 AML 和 AML 分析器:AML 是 ACPI 控制方法的虛擬