ACPI
ACPI(Advanced Configuration and Power Interface,高级配置和电源接口)是由Intel、Microsoft和Toshiba联合开发的PC电源管理和配置标准。(译者注:第一次接触的时候愚蠢的译者以为这个是一个电源管理标准,其实它是现代总线的重要枚举和配置接口) ACPI允许操作系统控制每个设备的电量 (例如,允许其使某些设备处于待机状态或断电状态)。 它还用于控制和/或检查热区(温度传感器、风扇速度等)、电池电量、PCI IRQ路由、CPU、NUMA域和许多其他内容。
实现ACPI
有关ACPI的信息存储在BIOS的内存中 (当然适用于那些支持ACPI的系统)。
ACPI有两个主要部分。 第一部分是操作系统在引导期间用于配置的表(包括CPU数量、APIC详细信息、NUMA内存范围等)。 第二部分是运行时ACPI环境,它由 AML 代码 (一种来自BIOS和设备的平台独立OOP语言) 和ACPI SMM (系统管理模式-System Management Mode) 代码组成。
要开始使用ACPI,操作系统必须查找RSDP(根系统描述指针-Root System Description Pointer)。 这在RSDP中有涉及,因为它太冗长了,这里暂不介绍。
如果找到RSDP并且验证有效,则它包含指向RSDT (根系统描述表) 的指针,并且对于较新版本的ACPI (ACPI 2.0及更高版本),还有一个额外的XSDT (扩展系统描述表)。 RSDT和XSDT都包含指向其他表的指针。 RSDT和XSDT之间唯一的真正区别是XSDT包含64位指针,而不是32位指针。
对于ACPI的运行时部分,要检测的主表是FADT (固定的ACPI描述表),因为它包含启用ACPI所需的信息。
使用ACPI有两种可能性。 您可以编写自己的ACPI表读取器和AML解释器。 或者你可以在你的操作系统中集成 ACPICA。
切换到ACPI模式
在某些pc上,如果是一下情况,则已经切换到ACPI模式:
- FADT中的SMI命令字段为0
- FADT中的ACPI启用和ACPI禁用字段均为0
- 设置PM1a控制块I/O端口的位0 为值1
否则,将ACPI Enable字段的值写入smi命令字段指向的寄存器号,如下所示:
outb(fadt->smi_command,fadt->acpi_enable);
Linux等待硬件更改模式的时间为3秒。 然后轮询PM1a控制块,直到位0设置为值1。 当设置此位已设置时,表示电源管理正在生成SCI,而不是SMI,这意味着您的操作系统必须处理这些事件,而不需要系统管理BIOS为您做任何事情。 SCI是FADT告诉你的IRQ。
while (inw(fadt->pm1a_control_block) & 1 == 0);