[UEFI] Learn UEFI by RPI4 -- 2. ACPI

书接上回:[UEFI] Learn UEFI by RPI4 – 1. Prepare and Build
其实ACPI对于UEFI来说已经不算是基础内容了,之所以放在这里,主要是因为我最近在看ACPI。

ACPI简介

ACPIAdvanced Configuration and Power Interface)是一种电源管理标准,用于控制电脑硬件的配置和电源管理。ACPI最初由英特尔、微软和东芝等公司发起开发,旨在取代旧的电源管理标准,如APM(Advanced Power Management)和PnP(Plug and Play)。ACPI通过在操作系统和硬件之间引入一个统一的接口,实现了更精确和高级的电源管理功能。它包括了一套规范、一组固件和一套操作系统驱动程序,可以协调处理器、电源、存储器、外围设备等硬件资源的使用和配置。ACPI标准定义了一种描述计算机硬件和软件配置的语言,称为ACPI描述语言(ACPI Description Language,ASL)。通过ASL,系统设计者可以定义硬件配置、设备连接和电源管理策略等信息。操作系统读取这些信息并相应地调整硬件的行为。

ACPI的主要功能包括:

  • 电源管理:ACPI可以控制和管理计算机的电源使用,包括节能模式、待机模式和休眠模式等。它可以根据用户的需求和系统的状态自动调整电源设置,以延长电池寿命并降低能耗。
  • 设备配置和连接:ACPI可以检测和配置计算机中的硬件设备,包括处理器、内存、外围设备等。它还可以实现热插拔功能,即在运行时插入或拔出设备而无需重启计算机。
  • 系统状态管理:ACPI可以跟踪和管理系统的状态,包括开机、关机和重启等。它还可以监测硬件故障和错误,并提供相应的错误处理和恢复机制。

ACPI中必须存在的几张表

在ACPI(高级配置与电源接口)规范中,必须包含以下几张表:

  • RSDT (Root System Description Table) 或 XSDT (Extended System Description Table): 这些表包含了指向系统中所有其他ACPI表的指针。XSDT是RSDT的扩展,支持64位地址,而RSDT仅支持32位地址。

  • DSDT (Differentiated System Description Table): 这是最重要的ACPI表之一,包含了大量的AML(ACPI Machine Language)代码,用于描述系统硬件的配置和电源管理功能。DSDT表允许操作系统查询和控制硬件设备的电源状态。

  • FADT (Fixed ACPI Description Table): 提供了指向其他重要ACPI表的指针,并包含了系统级电源管理和配置信息,如系统电源状态、睡眠按钮功能、唤醒事件等。

  • MADT (Multiple APIC Description Table): 描述了系统中的中断控制器信息,包括本地APIC和I/O APIC的配置。这对于操作系统来说是必要的,以便正确地处理硬件中断。

  • SSDT (Secondary System Description Table): SSDT通常用于补充DSDT表中的信息,提供额外的设备描述。一个系统可以有多个SSDT表。

1. Root System Description Pointer (RSDP)

根系统描述指针 (RSDP) 结构位于系统的内存地址空间中,由平台固件设置。此结构包含扩展系统描述表 (XSDT) 的地址,该表引用向 OSPM 提供数据的其他描述表,为其提供有关基础系统实现和配置的知识(请参阅根系统描述指针和表)。所有系统描述表都以相同的标题开头。RSDT(根系统描述表)是ACPI中的一个关键数据结构,它包含指向所有其他系统描述表的指针。RSDT的主要作用是作为一个目录,帮助操作系统找到并解析其他ACPI表。

结构:RSDT表的结构包括一个标准的ACPI表头和一个指针数组,每个指针指向一个其他的ACPI表。
作用:RSDT用于定位和访问其他ACPI表,如FADT、DSDT、MADT和SSDT等。
验证:RSDT表需要通过校验和验证,以确保其完整性和正确性[2][6]。

  • 扩展系统描述表 (XSDT) 指向内存中的其他表。它始终是第一个表,指向固定 ACPI 描述表 (FADT)。此表中的数据包括各种固定长度的条目,这些条目描述硬件的固定 ACPI 功能。
  • FADT 表始终引用差异化系统描述表 (DSDT),其中包含各种系统功能的信息和描述。这些表之间的关系显示在描述表结构中。
struct ACPISDTHeader {
    char Signature[4];    // 表签名
    uint32_t Length;      // 表长度
    uint8_t Revision;     // 版本
    uint8_t Checksum;     // 校验和
    char OEMID[6];        // OEM ID
    char OEMTableID[8];   // OEM 表 ID
    uint32_t OEMRevision; // OEM 版本
    uint32_t CreatorID;   // 创建者 ID
    uint32_t CreatorRevision; // 创建者版本
};

在这里插入图片描述
在这里插入图片描述

2. DSDT(Differentiated System Description Table)

DSDT(差异化系统描述表)是ACPI中的一个主要表,用于描述系统的外围设备。DSDT包含了设备的详细信息,如I/O端口、IRQ、内存映射等。

  • 结构:DSDT表由一个标准的ACPI表头和一段AML(ACPI Machine Language)代码组成。
  • 作用:DSDT用于定义系统中的硬件设备及其电源管理功能。例如,当操作系统需要关闭系统时,它会查找DSDT中的_S5对象来执行关机操作。
  • 生成:硬件制造商使用ASL(ACPI Source Language)编译器生成DSDT的AML字节码[5][6]。
DefinitionBlock ("", "DSDT", 2, "OEMID", "OEMTABLE", 0x00000001)
{
    Device (DEV0)
    {
        Name (_HID, EisaId ("PNP0C0F"))  // 设备ID
        Name (_UID, 0x01)                // 唯一ID
        Method (_STA, 0, NotSerialized)  // 状态方法
        {
            Return (0x0F)  // 设备存在且已启用
        }
        Method (_PS0, 0, NotSerialized)  // 电源状态0 (D0)
        {
            // 启动设备的代码
        }
        Method (_PS3, 0, NotSerialized)  // 电源状态3 (D3)
        {
            // 关闭设备的代码
        }
    }
}

3. FADT(Fixed ACPI Description Table)

FADT(固定ACPI描述表)是ACPI中的一个数据结构,包含与电源管理相关的固定寄存器块的信息。

  • 结构:FADT表包括一个标准的ACPI表头和多个字段,这些字段提供了电源管理所需的各种硬件信息。
  • 作用:FADT用于定义系统的固定硬件特性,如电源管理寄存器、系统控制中断(SCI)等。它还包含指向DSDT的指针。
  • 字段:FADT表的字段包括FirmwareCtrl、Dsdt、PreferredPowerManagementProfile等[4][6]。
struct FADT {
    struct ACPISDTHeader h;
    uint32_t FirmwareCtrl;
    uint32_t Dsdt;
    uint8_t Reserved;
    uint8_t PreferredPowerManagementProfile;
    uint16_t SCI_Interrupt;
    uint32_t SMI_CommandPort;
    uint8_t AcpiEnable;
    uint8_t AcpiDisable;
    uint8_t S4BIOS_REQ;
    uint8_t PSTATE_Control;
    uint32_t PM1aEventBlock;
    uint32_t PM1bEventBlock;
    uint32_t PM1aControlBlock;
    uint32_t PM1bControlBlock;
    uint32_t PM2ControlBlock;
    uint32_t PMTimerBlock;
    uint32_t GPE0Block;
    uint32_t GPE1Block;
    uint8_t PM1EventLength;
    uint8_t PM1ControlLength;
    uint8_t PM2ControlLength;
    uint8_t PMTimerLength;
    uint8_t GPE0Length;
    uint8_t GPE1Length;
    uint8_t GPE1Base;
    uint8_t CStateControl;
};

4. MADT(Multiple APIC Description Table)

MADT(多APIC描述表)是ACPI中的一个表,提供了系统中断控制器的信息,主要用于多处理器系统。

  • 结构:MADT表由一个标准的ACPI表头和一系列可变长度的记录组成,这些记录描述了系统中的中断设备。
  • 作用:MADT用于枚举系统中的处理器和中断控制器,帮助操作系统配置和管理中断。
  • 记录类型:MADT表中的记录类型包括处理器本地APIC、I/O APIC、中断源覆盖等[3][6]。
struct MADT {
    struct ACPISDTHeader h;
    uint32_t LocalAPICAddress;
    uint32_t Flags;
    // 可变长度的记录
};

5. SSDT(Secondary System Description Table)

SSDT(次级系统描述表)是ACPI中的一个表,用于补充DSDT,提供额外的AML代码以与设备交互。

  • 结构:SSDT表的结构与DSDT相似,由一个标准的ACPI表头和一段AML代码组成。
  • 作用:SSDT用于定义DSDT中未包含的系统组件和功能,提供额外的设备定义和电源管理功能。
  • 用途:SSDT通常用于定义热插拔设备、动态加载的设备等[1][6]。
DefinitionBlock ("", "SSDT", 2, "OEMID", "OEMTABLE", 0x00000001)
{
    Device (DEV1)
    {
        Name (_HID, EisaId ("PNP0C0F"))  // 设备ID
        Name (_UID, 0x02)                // 唯一ID
        Method (_STA, 0, NotSerialized)  // 状态方法
        {
            Return (0x0F)  // 设备存在且已启用
        }
        Method (_PS0, 0, NotSerialized)  // 电源状态0 (D0)
        {
            // 启动设备的代码
        }
        Method (_PS3, 0, NotSerialized)  // 电源状态3 (D3)
        {
            // 关闭设备的代码
        }
    }
}

ACPI的历史

ACPI标准的第一个版本于1996年12月发布,支持16、24和32位寻址空间。2000年8月,ACPI 2.0版本引入了64位地址支持以及多处理器工作站和服务器的支持。此后,ACPI标准不断发展,增加了对SATA接口、PCI Express总线、USB 3.0、ARM架构等的支持。最新的ACPI 6.5版本于2022年8月发布。

ACPI的架构

ACPI架构由多个关键组件组成,包括ACPI表、ACPI BIOS和ACPI寄存器。

ACPI表

ACPI使用多个表来存储有关硬件配置和系统状态的信息。这些表对于操作系统理解硬件能力和管理硬件至关重要。主要的ACPI表包括:

  • DSDT(Differentiated System Description Table):包含系统的大部分ACPI数据,包括大多数硬件组件及其电源管理功能的定义。
  • SSDT(Secondary System Description Table):提供DSDT中未包含的系统组件的附加定义。
  • FADT(Fixed ACPI Description Table):提供各种硬件组件正确操作所需的静态信息,包括系统级信息和指向其他表的指针。
  • MADT(Multiple APIC Description Table):包含有关系统中断控制器的信息,主要用于多处理器系统。

ACPI BIOS

系统固件或BIOS包含ACPI实现,提供操作系统接管系统资源管理所需的初始ACPI表和接口。ACPI BIOS负责在操作系统接管之前引导ACPI环境。

ACPI寄存器

ACPI硬件寄存器分为固定硬件寄存器和通用硬件寄存器。固定硬件寄存器需要实现ACPI定义的接口,而通用硬件寄存器则用于任何由增值硬件生成的事件。ACPI寄存器模型包括状态/使能寄存器和控制寄存器。

ACPI的功能

ACPI提供了一系列关键功能,促进了现代计算系统的设备管理、电源效率和系统响应能力。这些功能包括:

  • 电源管理:ACPI定义了设备电源状态(D状态)、处理器状态(C状态和P状态)以及系统状态(S状态,如睡眠和休眠)的管理方法。
  • 事件处理:ACPI定义了处理与电源、热管理和其他系统功能相关的各种系统事件的机制。
  • 热管理:ACPI允许操作系统根据温度变化动态调整系统策略,以确保最佳性能和电源使用。

ACPI架构图

为了更好地理解ACPI(高级配置与电源接口)的架构,我们可以通过一张架构图来展示其主要组件及其相互关系。以下是ACPI架构的简要说明和示意图。

ACPI架构的主要组件

  1. ACPI表(ACPI Tables)

    • DSDT(Differentiated System Description Table):包含系统的大部分ACPI数据,包括大多数硬件组件及其电源管理功能的定义。
    • SSDT(Secondary System Description Table):提供DSDT中未包含的系统组件的附加定义。
    • FADT(Fixed ACPI Description Table):提供各种硬件组件正确操作所需的静态信息,包括系统级信息和指向其他表的指针。
    • MADT(Multiple APIC Description Table):包含有关系统中断控制器的信息,主要用于多处理器系统[2][3][4][5]。
  2. ACPI BIOS

    • 系统固件或BIOS包含ACPI实现,提供操作系统接管系统资源管理所需的初始ACPI表和接口。ACPI BIOS负责在操作系统接管之前引导ACPI环境[4]。
  3. ACPI寄存器(ACPI Registers)

    • ACPI硬件寄存器分为固定硬件寄存器和通用硬件寄存器。固定硬件寄存器需要实现ACPI定义的接口,而通用硬件寄存器则用于任何由增值硬件生成的事件[4]。
  4. AML(ACPI Machine Language)

    • ACPI表使用一种称为ACPI机器语言(AML)的字节码语言编码。操作系统中的ACPI组件解释AML字节码,允许操作系统直接管理系统硬件资源[3][4]。

ACPI架构图示意

以下是ACPI架构的示意图,展示了其主要组件及其相互关系:
在这里插入图片描述

详细说明

  • ACPI表:这些表存储有关硬件配置和系统状态的信息,操作系统通过这些表了解硬件能力并进行管理。
  • ACPI BIOS:在系统启动时加载ACPI表,并提供初始的ACPI环境。
  • ACPI寄存器:用于管理硬件事件和状态。
  • AML:ACPI表中的AML代码由操作系统解释,用于定义事件、设备配置和电源状态。

ACPI代码示例

以下是一个简单的ACPI代码示例,展示了如何使用ACPI Machine Language(AML)定义设备的电源管理功能:

DefinitionBlock ("", "DSDT", 2, "OEMID", "OEMTABLE", 0x00000001)
{
    Device (DEV0)
    {
        Name (_HID, EisaId ("PNP0C0F"))  // Device ID
        Name (_UID, 0x01)                // Unique ID
        Method (_STA, 0, NotSerialized)  // Status method
        {
            Return (0x0F)  // Device is present and enabled
        }
        Method (_PS0, 0, NotSerialized)  // Power state 0 (D0)
        {
            // Code to power on the device
        }
        Method (_PS3, 0, NotSerialized)  // Power state 3 (D3)
        {
            // Code to power off the device
        }
    }
}

总结

ACPI是一个关键的系统级接口和电源管理规范,通过统一和标准化操作系统与硬件之间的交互,实现了高效的电源管理和配置。它不仅涵盖了电源管理,还包括系统事件处理、热管理和设备即插即用等功能。通过ACPI,操作系统可以更精细地控制系统资源,提升系统的灵活性和电源效率。

<think>好的,用户现在想了解UEFI中_STA配置的含义和设置方法。之前他们询问过关于屏幕背光控制(BCL)的问题,现在转向了ACPI的_STA方法。我需要结合之前的对话和提供的引用内容来回答。首先,回忆一下ACPI中的_STA方法。_STA是Status的缩写,用于返回设备的当前状态,比如是否存在、是否启用等。用户可能想知道如何在UEFI中配置这个状态,或者它的具体含义。根据引用[1]中的内容,用户之前在学习UEFIACPI,特别是关于RPI4的内容,这可能和硬件设备的状态管理有关。接下来,查看用户提供的引用。引用[3]提到_HID、_CID和_SUB,这些都是ACPI中用于设备识别的标识符,而_STA可能和这些标识符一起使用,确定设备的状态。引用[4]中的RTC驱动涉及寄存器的读取,这可能和_STA返回的状态位有关联,比如设备是否正常工作。 用户的问题需要详细解释_STA的作用、返回值结构,以及在UEFI中如何设置。我需要分点说明,包括结构、设置步骤、示例代码和注意事项。例如,_STA返回一个32位的值,每个位代表不同的状态标志,如设备是否存在、是否启用等。在UEFI中,可能需要通过ACPI表协议来添加或修改_STA方法。还需要考虑用户可能的后续问题,比如_STA与电源管理的关系,或者如何调试_STA的返回值。结合之前回答中的相关问题,比如ACPI方法调用、电源状态交互,这些都可能成为相关的问题点。 最后,确保回答符合格式要求:数学表达式用$符号,引用标注正确,代码块语法正确,并生成相关问题。比如,在解释返回值时,使用$$包裹位定义的公式,引用来自提供的引用[3]和[1]中的ACPI相关内容。</think>### UEFI中_STA配置详解 #### 1. **_STA方法定义** `_STA`(Status)是ACPI规范中定义的对象方法,用于返回设备的当前状态。其返回值是32位整数,各bit位的含义如下: $$ \begin{aligned} &\text{Bit 0} & \text{Device Present} & (1=\text{存在})\\ &\text{Bit 1} & \text{Device Enabled} & (1=\text{启用})\\ &\text{Bit 2} & \text{Device Shown in UI} & (1=\text{显示})\\ &\text{Bit 3} & \text{Device Functional} & (1=\text{正常工作})\\ &\text{Bit 4-31} & \text{Reserved} & (0) \end{aligned} $$ 典型返回值示例:`0x0F`表示设备存在、启用、可见且功能正常[^3] #### 2. **在UEFI中的设置方法** 在UEFI驱动中配置_STA通常需要以下步骤: 1. **定位设备对象**:通过ACPI表协议(`EFI_ACPI_TABLE_PROTOCOL`)定位目标设备节点 ```c EFI_ACPI_TABLE_PROTOCOL *AcpiTable; gBS->LocateProtocol(&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable); ``` 2. **定义_STA方法**:使用AML(ACPI Machine Language)编写状态控制逻辑 ```aml Method(_STA, 0x0, NotSerialized) { Return(0x0F) // 默认返回全功能状态 } ``` 3. **动态状态控制**:根据硬件实际状态调整返回值,例如检测RTC寄存器状态: ```c LS7A_TOY_REG0 RtcReg; MmioRead(RTC_REG_BASE + 0x2C, &RtcReg.Data); // 参考引用[4]的寄存器读取方式 if ((RtcReg.Bits.TOY_MONTH__ & 0x1F) > 12) { Return(0x00); // 无效日期时禁用设备 } ``` #### 3. **优先级规则** 当多个ACPI方法影响设备状态时,按以下优先级生效: $$ \text{\_STA} > \text{\_DIS} > \text{\_INI} > \text{默认状态} $$ 这意味着明确设置的_STA值将覆盖其他方法的状态控制[^3] #### 4. **调试技巧** 在UEFI Shell中可直接查询设备状态: ```shell acpiexec -l DSDT.aml # 加载ACPIacpiexec -n \_SB.PCI0.LPCB.RTC._STA # 查询特定设备的_STA返回值 ``` --- ### 关键注意事项 1. **时序要求**:在调用_STA前需确保设备已完成初始化(例如RTC需要完成时间校准[^4]) 2. **电源状态关联**:设备进入D3hot状态后,_STA应返回`0x00`表示不可用 3. **热插拔支持**:对于可热插拔设备,需要实现_STA的动态更新机制 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山猫Show

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值