白灼菜心ACPI学习笔记 - 不断修订中-last updated on Oct 15
刚起步, 3.0b规范还只看了一部分,本文档对别人应该没什么意义,只是记录我的学习过程而已。肯定有大量误解,欢迎BUG FIXING。
/**
* file : ACPI Notes
* AUTHOR : albcamus <>
* Copyright : GNU FDL(Free Documentation Licen)
* XXX : continuously correcting and improving
*/
TERMINOLOGY:
===========
I.) TABLES OF ACPI
SDTH : System Description Table Header
(注意这个不是Table,它是每个Table都包含的头)
RSDP : Root System Description Pointer
('RSD PTR')
RSDT : Root System Description Table
(signature is 'RSDT')
FADT : Fixed ACPI Description Table
('FACP')
FACS : Firmware ACPI Control Structure
('FACS')
DSDT : Differentiated System Description Table
('DSDT')
PSDT : Persistent System Description Table
('PSDT'). 注意它是ACPI Spec-1.0定义的,早已被移除。
SSDT : Secondary System Description Table
('SSDT')
MADT : Multipile ACPI Description Table
('APIC')
SBST : Smart Battery Table
('SBST')
XSDT : Extended System Description Table
('XSDT')
ECDT : Embedded Conroller Boot Resources Table
('ECDT')
SLIT : System Locality Distance Information Table
('SLIT')
SRAT : System Resource Affinity Table
('SRAT')
MCFG : PCI-Memory Mapped Configuration table and sub-table
微信登录网页版
('MCFG')
SPCR : Serial Port Console Redirection table
('SPCR')
BERT : Boot Error Record Table
('BERT')
SBFT : Simple Boot Flag Table
('BOOT')
CPET? : Corrected Platform Error Polling Table
('CPEP')
DBGT? : Debug Port Table
('DBGP')企业内控体系建设
DMAT? : DMA Remapping Table
('DMAR')
TCPT? : Trusted Computing Platform Alliance Table
('TCPA')
WDRT : Watchdog Resource Table
('WDRT')
ASFT? : Alert Standard Format Table
('ASF!')
具体见ACPI规范3.0b的Table 5-6. 这里只是一部分。
Note, ACPI定义的所有tables、blocks和structures,全都是little-endian。
II.) THE OTHER TERMINOLOGIES
ASL : ACPI Source Language
AML : ACPI Machine Language
DSL : Digital Simulation Language
E820 : a system memory map protocol, provided in ACPI spec, ch14 for 3.0b EFI : Enhanced Firmware Interface
武松打虎的故事HPET : High Precision Event Timer
GPE : General-Purpo Event
GSI : Global System Interrupts
OSL : OS Service Layer
OSPM : OS Power Management, 指Linux等OS中实现对ACPI支持的代码
PRT : PCI IRQ Routing Table
PXE : Preboot Execution Environment
SAPIC : Streamlined APIC, IA64上使用的APIC。其local SAPIC和I/O SAPIC分别对应着IA32
和x86-64上的Local APIC和I/O APIC
SBF : Simple Boot Flag
SCI : System Control Interrupt
(OS-visible interrupts, triggered by ACPI events)
SMBIOS/DMI : System Management BIOS/Desktop Management Interface. PC的BIOS规范。 TOM : Top Of Memory
UUID : Universal Uniform IDentifiers
xface : Linux内核ACPI源文件的命名法,表示Interface。例如tbxface.c实现table
的接口。
1, RSDP, RSDT and XSDT
RSDP是位于系统内存地址空间中的,它的值由firmware设置。
RSDP包含了两个指针(还有其他字段,见Linux的struct acpi_table_rsdp),分别保存着RSDT
表的物理地址
(32位),和XSDT表的物理地址(64位)。
Linux寻找RSDP的代码见acpi_os_get_root_pointer()函数。
从ACPI2.0+开始,XSDT就取代了RSDT。 RSDT是ACPI 1.0中的,现代的OEM厂商一般也还提供RSDT,但那只
是为了向后兼容ACPI-1.0而已。或者用RSDT,或者用XSDT,不管选择用那个,它都包含了其他ACPI表数组
的地址。
Linux下这2者的定义是:
struct acpi_table_rsdt {
struct acpi_table_header header; /* Common ACPI table header */
u32 table_offt_entry[1]; /* Array of pointers to ACPI tables */
};
struct acpi_table_xsdt {专生本
struct acpi_table_header header; /* Common ACPI table header */
u64 table_offt_entry[1]; /* Array of pointers to ACPI tables */
/* FIXME: 为什么数组大小是1?
*/
};
2, ACPI Table Header
ACPI所有的描述表(FACS表除外?Linux的acpi_table_facs结构不包含header,ACPI规范中也没有)都包含
着一个Header,所有描述表的Header结构都是一样的。Linux把它定义为:
struct acpi_table_header {
char signature[ACPI_NAME_SIZE]; /* ASCII table signature */
u32 length; /* Length of table in bytes, including this header */ u8 revision; /* ACPI Specification minor version # */
u8 checksum; /* To make sum of entire table == 0 */
char oem_id[ACPI_OEM_ID_SIZE]; /* ASCII OEM identification */
找到的英语
char oem_table_id[ACPI_OEM_TABLE_ID_SIZE]; /* ASCII OEM table identification */
u32 oem_revision; /* OEM revision number */
char asl_compiler_id[ACPI_NAME_SIZE]; /* ASCII ASL compiler vendor ID */ u32 asl_compiler_revision; /* ASL compiler version */
};
3, (RSDT/XSDT之外的) ACPI描述表数组的第一个:FADT
这个数组的第一个元素由XSDT中的table_offt_entry[0]指定位置。
被指向的第一个表通常是FADT(Fixed ACPI
Description Table),它的几个主要作用:
1) 保存着FACS和DSDT表的地址(64位也是)
钓鱼的技巧
2) 包含一些entries,每个entry有固定的length,描述一个硬件的ACPI feature(我的理解就是,
硬件对ACPI的支持程度)
Linux下FADT的定义见struct acpi_table_fadt结构。
4. DSDT表(Differentiated System Description Table)
由FADT中的字段指向,见上一条笔记。
//Thanks for wheelz!
DSDT表包含一个Definition Block,叫作'Differentiated Definition Block for the DSDT',它包含了
实现与配置信息(implementation and configuration information)。 OSPM用这些信息来实现:电源管理,
热量管理,以及(在ACPI硬件寄存器所描述的信息之外的)即插即用。
//FIXME: 奇怪的是,Linux没有提供一个struct acpi_table_dsdt 结构的定义,只提供了一个`
acpi_system_read_dsdt()函数。
//FIXED: 注意,这个acpi_system_read_dsdt()函数不是内核用来load DSDT表的,而是为了让用户程序(例如cp)通过/proc/acpi/dsdt来读取DSDT表的(in AML format),以便给内核开发者诊断
问题。
很多platform vendor提供的BIOS,特别是笔记本上,其DSDT表往往有BUG,导致Linux的电源管理出现问题。
Linux内核提供了CONFIG_ACPI_CUSTOM_DSDT和CONFIG_ACPI_CUSTOM_DSDT_FILE配置选项,允许用户自己提供
DSDT文件,替代BIOS中有BUG的那个。
这个用户自己提供的DSDT文件,其实就是一个AML语言描述的数据块。可以用pmtools中的acpidump和
acpixtract程序把ACPI的表从BIOS中提取出来,再用iasl工具(Intel ACPICA中的ASL编译器、AML反汇编器)
反汇编它,修正BUG,然后编译。
这个原理,参考Linux内核的acpi_os_table_override()函数。
5. SSDT表
它是DSDT表的扩展。如果有这个表,RSDT/XSDT中就有指向它的指针。 SSDT表可能有不止一个。 Definition Blocks, 都是定义在DSDT或者SSDT(s)表里的。其它的表没有定义块。
6, FACS表(Firmware ACPI Control Structure)
跟DSDT表一样,FACS表也由FADT表中的字段指向。见笔记<3>。
7, CPU的Idle States (C-states)
从C0到C<n>。一般来说,都是共有从C0到C4这5个状态。 C0是正常状态,即CPU全频率工作,不省电。
n越大,CPU越省电,但从它转到C0的所需时间也越长。
属兔的Linux下,可以通过kernel parameter: processor.max_cstate来改变<n>的上限。
8, CPU的Performance States (P-States), CPU频率管理
从P0到P<n>。 P0时,CPU以最高主频工作;其他状态下,n越大,CPU频率越低。