ACPI(Advanced Configuration and Power Interface)
基本概念
-
RSDP: 是 ACPI 数据结构中的第一个表,用于引导 ACPI 表的查找过程。根系统描述指针,指向 RSDT 或 XSDT 的位置。
-
RSDT 和 XSDT:根表和扩展表,提供其他 ACPI 表的位置。
-
FADT:固定配置表,包含 ACPI 固件的配置信息。
-
ACPI通过设备表(DSDT、SSDT)描述系统的硬件结构和控制方法,也就是DSDT、SSDT中保存了硬件寄存器的定义。
-
ACPI最重要的事情是实现电源管理
- 在电源管理S0状态,可以通过设置_PS0和_PS3等方法控制设备的电源状态.
- 可以通过设置_S1,_S2,S3方法,了解进入相应电源状态需要执行的操作。或者调用_PTS(Prepare To Sleep)设置进入Sx状态的寄存器.唤醒使用_PRW,_PSW等.
- S4(休眠或保存到磁盘状态),系统的内容会保存到硬盘,恢复时,系统从硬盘读取之前保存的状态._GTS(进入S4前调用的方法),_WAK(从S4唤醒后调用的方法)
- S5关机_S5
-
MADT(Multiple APIC Description Table):描述中断控制器的信息。
-
HPET:描述高精度定时器设备。
SBST:描述电池相关信息。
SRAT:描述处理器和内存的亲和性。
常用语法
-
OperationRegion(),定义设备的资源访问区域,允许代码访问特定的硬件资源,通过定义OperationRegion,OS 或 固件可以在该区域读写硬件寄存器或其它资源,通过与Field()配合使用
OperationRegion
OperationRegion (RegionName, RegionSpace, Offset, Length) RegionSpace 类型 RegionSpace 指定了操作区域的类型,常见的值有: SystemMemory (0x00): 指定内存映射 I/O(MMIO)区域。操作区域对应系统的物理内存地址,通常用于访问 PCI 设备或其他通过内存地址控制的硬件设备。 SystemIO (0x01): 指定 I/O 端口空间。操作区域对应 I/O 端口号,通常用于访问使用 I/O 端口的硬件设备(如传统的串口设备、键盘等)。 PCI_Config (0x02): 指定 PCI 配置空间。该区域用于访问 PCI 设备的配置空间寄存器。 EmbeddedControl (0x03): 指定嵌入式控制器(EC)区域,通常用于访问与系统电源、风扇控制等相关的设备。 SMBus (0x04): 指定系统管理总线(SMBus)区域,常用于访问传感器设备或电池管理单元。 CMOS (0x05): 指定 CMOS 区域,用于访问主板的 CMOS 内存。 PCI_BarTarget (0x06): 通过 PCI 配置空间的基址寄存器(BAR)访问 PCI 设备。
-
Field(),用于指定OperationRegion区域中特定字段的读写.
内存地址示例代码
OperationRegion (REG1, SystemMemory, 0xFED40000, 0x1000) Field (REG1, AnyAcc, NoLock, Preserve) { Offset (0x10), // 指定寄存器的偏移量 REG_FIELD, 32 // 32 位宽的寄存器 }
-
Method(), 相当于一个可以被执行的功能,用于动态处理硬件事件或者设备管理。常见的有_STA(返回设备状态), _HID(返回设备硬件ID),
Method
Method (方法名, 参数个数(arg0-arg5)) { // 方法体 // 执行逻辑 Return (返回值) // 可选 }
-
Name(), 取别名
-
Package(),相当于结构体
Package
Package (元素数量) { 元素0, 元素1, ... 元素N }
-
Scope用于定义命名空间中的范围,表示特定的设备或路径。
\_SB
Scope (\_SB) // 定义系统总线(System Bus)的作用范围 { Device (PC00) {...} }
-
ResourceTemplate中定义的资源会按照顺序在内存中依次分配和存储。
ResourceTemplate ()
Name (RBRS, ResourceTemplate () { WordBusNumber (...), // 第一个资源 WordIO (...), // 第二个资源 DWordMemory (...) // 第三个资源 })
常用方法
_CRS
在 ACPI 中,所有设备的硬件资源(如内存地址、I/O 端口、IRQ 中断等)都应该通过 _CRS(Current Resource Settings)方法来预先定义才能被使用。在 DSDT 或 SSDT 表中通过 _CRS 方法定义设备的资源,可以使用 SystemMemory 或 SystemIo 来告知操作系统该设备寄存器的位置。
CRS使用方法
Memory资源
Name (_CRS, ResourceTemplate() {
Memory32Fixed(ReadWrite,
0xFED40000, // 基地址
0x1000 // 地址范围大小
)
})
IO端口资源
Name (_CRS, ResourceTemplate() {
IO (Decode16,
0x03F8, // I/O 基地址
0x03F8, // 最小地址
0x0000, // 步长
0x0008 // 地址范围
)
})
IRQ资源
Name (_CRS, ResourceTemplate() {
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ) {5}
})
DMA资源
Name (_CRS, ResourceTemplate() {
DMA (0x04, Compatibility, )
})
示例: 假设一个 PCI 设备的控制寄存器被映射到内存地址 0xFED40000,并且它使用 I/O 端口 0x03F8 和中断号 5。其 _CRS 方法可以这样定义:
点击查看代码
Method (_CRS, 0) {
Name (RES, ResourceTemplate() {
Memory32Fixed(ReadWrite,
0xFED40000, // 内存基地址
0x1000 // 地址大小
)
IO (Decode16,
0x03F8, // I/O 基地址
0x03F8, // 最小地址
0x0000, // 步长
0x0008 // 地址大小
)
Interrupt(ResourceConsumer, Level, ActiveHigh, Shared, ) {5}
})
Return (RES)
}
CRS和OpeartionRegion的关系
- CRS用于说明设备占用位置,操作系统据此分配和管理资源。
- OperationRegion用于实际访问这些资源区域内的寄存器,是 ACPI 与设备交互的机制。