一.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 控制方法的虚拟