当前位置: 代码迷 >> 综合 >> ACPI Table基本知识
  详细解决方案

ACPI Table基本知识

热度:77   发布时间:2023-12-14 22:46:13.0

1ACPI table 在BIOS 里面用ASL code 去描述。而ACPI Table又分成不同类型的Table(RSDT/FADT/DSDT...etc).

2像是我们比较常使用的DSDT Table就是放了一些event code.简单说就是当某个H/W event发生后,系统会依照

描述在这个DSDT Table中的ASL code去执行,而这些Acpi Table 包在BIOS ROM 中的形式是AML Code (类似

机器码)。

3. BIOS在开机过程中会把包在BIOS ROM中的Acpi Table 载入到RAM中,然后留下一些信息给OS来找到他们,

最简单的例子就是RSDP Structure会放在1M以下的某个位置(一般是E0000h~FFFFh),然后OS就可以透过搜寻

Signature(某个标记字)的方式来找到其他的Acpi Table entry point。

4. OS 需要有一个AML翻译器去翻译这些AML code,然后去执行他们。

5.每个 Platform 的host controller的寄存器位置不同,所以BIOS需要透过ACPI Table来告知OS这些寄存器的

位置,这样子做的好处是OS不需要知道你是在什么Platform,因为他只单纯看BIOS所提供的HW信息。


结合ASL代码学习ACPI

1.从  _STA 说起.

_STA 描述了一个设备的当前状态,比如说它可以告诉操作系统某个device 是否存在,或者说,是否要show出来。具体参考ACPI spec 6.3.7(version 6.0)

这个object 描述了某个device 的当前状态,它可以是这三种情况:enabled, disabled 或者removed.


OSPM(其实就是OS) 在调用 INI 之前会先执行_STA 这个method.   先检测到它存在了,再去初始化它,不存在,也就没有初始化一说了。


如果某个device 下面,没有放这个_STA method ,我们默认它是存在并且正常工作的。


参数:

None


返回值:

Bit[0]   如果device 存在将会被置起

Bit[1]  如果device 被置起,并且decode 到相应的resource

Bit[2]  如果希望将其在UI中show出来,那么将这一位置起

Bit[3]  如果能正常工作,这一位会被置起。

Bit[4]  如果电池存在,置起这一位

Bit[31:5] 保留起来,以后用



    // _STA (Status)//// This object returns the current status of a device.//// Arguments: (0)//   None// Return Value://   An Integer containing a device status bitmap://    Bit 0 - Set if the device is present.//    Bit 1 - Set if the device is enabled and decoding its resources.//    Bit 2 - Set if the device should be shown in the UI.//    Bit 3 - Set if the device is functioning properly (cleared if device failed its diagnostics).//    Bit 4 - Set if the battery is present.//    Bits 5-31 - Reserved (must be cleared).//Method(_STA){If (LEqual(DPTF,1)){Return(0x0F)} Else {Return(0x00)}}


动动手:一个小实验

这张图截自windows 设备管理器,他显示了系统下有哪些device.


如果你想其中某个隐藏起来,就在asl code 中找到它(比如通过hid). 然后在下面写一个_STA 方法,返回全0.

Device(RTC) // RTC
{Name(_HID,EISAID("PNP0B00"))Name(_CRS,ResourceTemplate(){IO(Decode16,0x70,0x70,0x01,0x08)IRQNoFlags() {8}})
}


加几句,写成:

Device(RTC) // RTC
{Name(_HID,EISAID("PNP0B00"))Name(_CRS,ResourceTemplate(){IO(Decode16,0x70,0x70,0x01,0x08)IRQNoFlags() {8}})Method(_STA, 0){Return (0)}
}

然后,看看结果,是不是看不到RTC了?

FAQ?


谁去调用这些ASL code 中的这些method?

OS.

随便打开一份ACPI compatible (Linux , windows )的源代码,搜索_STA

ReactOS-0.3.14\drivers\bus\acpi\acpica\namespace\nsxfname.c  (取自ReactOS)

有这么几行

        /** Get extra info for ACPI Device/Processor objects only:* Run the _STA, _ADR and, SxW, and _SxD methods.** Note: none of these methods are required, so they may or may* not be present for this device. The Info->Valid bitfield is used* to indicate which methods were found and run successfully.*//* Execute the Device._STA method */Status = AcpiUtExecute_STA (Node, &Info->CurrentStatus);if (ACPI_SUCCESS (Status)){Valid |= ACPI_VALID_STA;}/* Execute the Device._ADR method */Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node,&Info->Address);if (ACPI_SUCCESS (Status)){Valid |= ACPI_VALID_ADR;}/* Execute the Device._SxW methods */Status = AcpiUtExecutePowerMethods (Node,AcpiGbl_LowestDstateNames, ACPI_NUM_SxW_METHODS,Info->LowestDstates);if (ACPI_SUCCESS (Status)){Valid |= ACPI_VALID_SXWS;}

2. OS 如何找到ACPI table?


通过RSDP 这个signature

/********************************************************************************* FUNCTION:    Acpi_tb_scan_memory_for_rsdp** PARAMETERS:  Start_address       - Starting pointer for search*              Length              - Maximum length to search** RETURN:      Pointer to the RSDP if found, otherwise NULL.** DESCRIPTION: Search a block of memory for the RSDP signature*******************************************************************************/u8 *
acpi_tb_scan_memory_for_rsdp (u8                      *start_address,u32                     length)
{u32                     offset;u8                      *mem_rover;/* Search from given start addr for the requested length  */for (offset = 0, mem_rover = start_address;offset < length;offset += RSDP_SCAN_STEP, mem_rover += RSDP_SCAN_STEP){/* The signature and checksum must both be correct */if (STRNCMP ((NATIVE_CHAR *) mem_rover,RSDP_SIG, sizeof (RSDP_SIG)-1) == 0 &&acpi_tb_checksum (mem_rover, RSDP_CHECKSUM_LENGTH) == 0){/* If so, we have found the RSDP */return (mem_rover);}}/* Searched entire block, no RSDP was found */return (NULL);
}

我要小额(2元)赞助,鼓励作者写出更好的教程


如果您认为本教程质量不错,读后觉得收获很大,预期工资涨幅能超过30%,不妨小额赞助我一下,让我有动力继续写出高质量的教程。

如果你有微信,请打开微信,使用“扫一扫”付款





??
??
  相关解决方案