unpon the return to S0. This is identical to soft-off for hardware. This state can be implemented by either OS or firmware.
S5 : the soft-off state. All activity will stop and all contexts are lost.
ACPI规范说,还规定了另一个说法,叫作Global System State:
G0 == {S0} : Working.
G1 == {S1, S2, S3, S4} : Sleeeping. G2 == {S5} : Soft off G3 : Mechanical off
11, MADT表, Multiple APIC Description Table
ACPI规范认为,一共有3种中断模型: Dual-8259, APIC和SAPIC。 Firmware可以同时提供对它们的支持,
但OSPM只能选择一个。
1.) Linux的MADT表的结构定义为:
struct acpi_table_madt {
struct acpi_table_header header;
u32 address /* physical address of local APIC */ u32 flags; };
其中MADT表在44字节偏移处,有个APIC Structure[n]结构数组,每个元素的第一个字节是该Structure的
类型,第二个字节是该Structure的长度。Linux把这两个字节封装成了一个acpi_subtable_header结构:
struct acpi_subtable_header { u8 type; u8 length; };
2.) APIC Structure的类型有:
0 : Processor Local APIC 1 : I/O APIC
2 : interrupt Source Override
3 : Non-maskable Interrupt Source(NMI) 4 : Local APIC NMI Structure
5 : Local APIC Address Override Structure 6 : I/O SAPIC 7 : Local SAPIC
8 : Platform Interrupt Sources
9-127 : Reserved. OSPM skips structures of the reserved type 128-255 : Reserved for OEM use
从0到8的这九个结构,在Linux下分别是:
0, acpi_madt_local_apic,
1, acpi_madt_io_apic,
2, acpi_madt_interrupt_override,
对于同时支持APIC和dual-8259A两种中断模型的平台,GSI中断的0-15必须被映射到8259A的0-15
引脚上。如果不是这样,那么就必须提供Interrupt Override。
例如,如果你有一个ISA的PIT,连接到ISA IRQ 0;但是在APIC模式下,它连接到I/O APIC 的
IRQ 2。你就需要提供Interrupt Source Override,在source entry == 0处,指定其GSI为2。
3, acpi_madt_nmi_source,
该结构指定,I/O APIC的中断输入中,哪些应被当作NMI。
4, acpi_madt_local_apic_nmi,
该结构指定,每个CPU的Local APIC,其中断输入(LINT
5, acpi_madt_local_override,
MADT中的address是local APIC的地址,32位。为了提供对64位系统的支持,可以提供local
APIC Address Override Structure,这样local APIC的地址就可以被Override成64位。
6, acpi_madt_io_sapic, IA64的I/O SAPIC。
7, acpi_madt_local_sapic, IA64的Local SAPIC。
8, acpi_madt_interrupt_source.
用来管理PMI(Platform Management Interrupts)的. PMI是IA-64上的,跟IA32的SMI类似。
这几个结构,可以参考Linux找到它们时打印信息的代码来理解其结构:acpi_table_print_madt_entry() 函数。
3.) Local APIC/SAPIC的entry order:
为了POST以及其后的正确引导, 有两条规则应该遵守: 1). OSPM应该以 处理器在MADT表中出现的顺序来初始化它们 2). Firmware应该把MADT中的第一个Entry列为引导处理器BP
对于多线程处理器,道理是一样的:
1. OSPM应该以 逻辑处理器在MADT表中出现的顺序来初始化它们 2。 Firmware应该把每个处理器的第一个逻辑处理器,在MADT表中 列在任何2nd逻辑处理器之前。
4.) 参考9.1/9.2中的信息,看看Linux下对local APIC和I/O APIC的定义:
/* 0:Processor Local APIC */ struct acpi_madt_local_apic {
struct acpi_subtable_header header; u8 processor_id; /* ACPI processor ID */ u8 id; /* Processor's local APIC id */ u32 lapic_flags; };
/* 1: IO APIC */
struct acpi_madt_io_apic {
struct acpi_subtable_header header; u8 id; /* I/O APIC ID */
u8 reserved; /* reserved. must be zero */ u32 address; /* IO APIC physical address */
u32 global_irq_base; /* Global system interrupt where INIT lines start */ };
在Linux上,引导时通过acpi_parse_madt_lapic_entries()和acpi_parse_madt_ioapic_entries()
两个函数来获取BIOS中ACPI提供的Local APIC和I/O APIC的信息。
5.) 多个IO-APIC
I/O APIC有一或多个。在ACPI-enabled系统中,有两种中断模型:APIC模型和PC-AT的一对主从8259A 模型。
APIC模型下,每个IO APIC支持的irq输入数目,可以是不同的, OSPM读取每个IO APIC的Max
Redirection Register来获取这个数目.