ACPI休眠按钮触发S0切换到S3流程(附流程图)

ACPI休眠按钮触发S0切换到S3流程(附流程图)

本文属于《 ACPI规范基础系列教程》之一,欢迎查看其它文章。

从硬件(休眠按钮)触发一个电平变化,到操作系统优雅地冻结用户空间、挂起设备驱动,最后让CPU断电、内存进入自刷新------这一切都必须严格遵循ACPI(高级配置与电源接口)这个复杂的标准。

本文将带你以初学者的视角,从头梳理ACPI规范中,从 S0(工作状态) 进入 S3(Suspend to RAM,挂起到内存) 的完整流程。

1 两种硬件实现路径

在深入流程前,需要明确:休眠按钮在硬件层面有两种实现方式,这会直接影响中断处理路径:

实现方式 硬件信号路径 中断类型 状态寄存器
固定硬件方案 按钮 → EC → PWRBTN#引脚 → 芯片组 固定事件 PM1状态寄存器(SLPBTN_STS位)
Control Method方案 按钮 → EC → GPIO引脚变化 → 芯片组 通用事件(GPE) GPE状态寄存器(某GPIO位)

下面以常见的固定硬件方案为主线,进行介绍。Control Method方案的差异点我会在流程中标注。

2 完整软硬件流程(S0 → S3)

第一阶段:硬件触发(物理层 → 寄存器层)

  1. 用户按下休眠按钮:产生物理信号。
  2. 嵌入式控制器捕获 :EC检测到按钮按下,根据平台设计:
    • 固定硬件方案:EC向芯片组的PWRBTN#专用引脚发送一个低脉冲。
    • Control Method方案:EC改变某个GPIO引脚的电平状态。
  3. 芯片组记录事件
    • 固定硬件方案 :芯片组将PM1状态寄存器 中的SLPBTN_STS位置为1(PM1x_STS.SLPBTN_STS)。
    • Control Method方案 :芯片组将GPE状态寄存器 中对应GPIO的某位置为1(GPEx_STS.yy)。
  4. SCI中断触发
    • 固定硬件方案 :芯片组检查对应的PM1使能寄存器SLPBTN_EN使能位(PM1x_EN.SLPBTN_EN)
    • Control Method方案 :芯片组检查对应的GPE使能寄存器GPE enable使能位(GPEx_EN.yy)

如果使能位为1,芯片组拉高SCI中断线,通知CPU有电源管理事件需要处理。

PM1控制寄存器中的SCI_EN=0 时,事件路由到 SMI中断(固件处理);SCI_EN=1 时,事件路由到 SCI中断(操作系统处理)。

  • 在ACPI/Legacy系统中,如果操作系统尚未设置 SCI_EN 位,你按下休眠按钮,只会触发SMI,系统可能根本不会进入你预期的S3状态。
  • 在仅支持ACPI的系统中,由于 SCI_EN 始终为1,你的按钮事件会直接通过SCI通知操作系统,操作系统便会执行后续进入S3状态流程。

第二阶段:OSPM中断处理(内核层)

  1. CPU响应SCI:CPU执行中断向量,进入ACPI驱动注册的中断处理程序。
  2. 中断处理程序轮询
    • 首先读取PM1状态寄存器 ,发现SLPBTN_STS位为1,确认是固定事件中的休眠按钮。
    • (如果是Control Method方案,则会在GPE状态寄存器中找到对应位,然后执行AML中的_Lxx_Exx方法,该方法通常包含Notify(***, 0x80)来通知操作系统)。
  3. 执行固定事件处理逻辑
    • 调用内核中预定义的休眠按钮处理函数(如Linux中的acpi_button_notify)。
    • 向PM1状态寄存器的SLPBTN_STS写入1,清除该状态位,表示事件已接收。
  4. 生成输入事件 :内核通过输入子系统向用户空间报告KEY_SLEEP事件,唤醒用户空间的电源管理服务(如systemd-logindacpid)。

第三阶段:软件准备(用户层 → 内核层)

  1. 用户空间策略决策:电源管理服务根据系统配置决定进入哪个休眠状态(通常是S3 mem)。
  2. 触发内核休眠 :用户空间将"mem"写入/sys/power/state文件。
  3. 内核开始休眠流程 :调用state_store()enter_state()suspend_prepare()
    • 同步文件系统
    • 冻结用户空间进程
    • 调用设备驱动的suspend回调,逐个挂起设备

第四阶段:ACPI控制方法执行(AML层)

经过通用电源管理框架(enter_state → suspend_prepare → suspend_devices_and_enter),最终通过平台钩子进入ACPI驱动层,由 acpi_sleep_prepare 调用BIOS提供的 _PTS 控制方法,完成了从"用户层"到"内核通用框架"再到"AML层"的完整交接。

  1. 调用_PTS方法 :ACPI驱动执行ACPI控制方法\_PTS(Prepare To Sleep),并将目标S状态(如3)作为参数传入。此方法由BIOS提供 ,通常用于:
    • 通知嵌入式控制器系统即将睡眠
    • 保存某些平台特定的硬件状态
    • 调用SMM代码进行底层配置
  2. 调用_GTS方法 (可选):如果存在,执行\_GTS(Going To Sleep)方法,进一步进行平台特定的睡眠准备。
  3. 禁用/使能GPE:内核禁用所有非唤醒源的GPE,仅保留标记为可唤醒设备的GPE。

每个GPE对应两个寄存器:

  • 状态(STS):在 GPE0_STS 或 GPE1_STS 中。当事件发生时硬件置1,软件写1清除。
  • 使能(EN):在 GPE0_EN 或 GPE1_EN 中。软件写1允许该GPE触发中断,写0则屏蔽。

如果不加选择地使能所有GPE,那么任何风吹草动(比如电源噪声)都可能唤醒系统。所以操作系统必须只使能那些被用户或策略允许唤醒的设备对应的GPE。

软件需要提前告诉硬件:哪些GPE是允许唤醒的,并且确保它们被正确使能。

第五阶段:最终硬件操作(寄存器写入)

  1. 获取SLP_TYP值 :内核从FADT表中获取PM1a/PM1b控制寄存器 的地址,并从\_S3对象中获取该S状态对应的SLP_TYP值。
  2. 设置唤醒向量 :内核将唤醒时执行的代码地址,写入Firmware Waking Vector(位于FADT表中FIRMWARE_CTRL指向的FACS结构中),供BIOS在唤醒后跳转。
  3. 写入PM1控制寄存器
    • 先将SLP_TYP值写入PM1a和PM1b控制寄存器的对应位。
    • 刷新CPU缓存。
    • 最后将SLP_TYPSLP_EN同时写入PM1a和PM1b控制寄存器。
  4. 硬件进入休眠 :芯片组检测到SLP_EN位被设置,开始控制电源时序:
    • 停止CPU时钟
    • 切断除内存外的多数设备电源
    • 内存进入自刷新模式保持数据
    • 系统进入S3状态

第六阶段:唤醒路径(简述)

当用户再次按下电源按钮唤醒时:

  1. 芯片组恢复电源,CPU从重置向量开始执行
  2. BIOS检测到是从S3唤醒,跳转到Firmware Waking Vector指向的地址
  3. 内核恢复代码执行,调用\_WAK方法
  4. 恢复设备驱动,解冻进程,返回用户空间

3 完整流程图

下面是根据上述流程,绘制的完整流程图:

4 关键寄存器与控制方法速查

为方便理解软硬件,以下是流程中涉及的寄存器/方法及其作用:

名称 类型 作用 所在位置
SLPBTN_STS PM1状态寄存器位 休眠按钮状态,硬件置1,软件写1清除 FADT中PM1a_EVT_BLK
SLPBTN_EN PM1使能寄存器位 使能休眠按钮的SCI中断 FADT中PM1a_EVT_BLK
SLP_EN PM1控制寄存器位 写入该位触发硬件进入休眠 FADT中PM1a_CNT_BLK
SLP_TYP PM1控制寄存器位 指定要进入的S状态(值从_Sx对象获取) FADT中PM1a_CNT_BLK
_PTS 控制方法 准备进入睡眠,S状态作为参数传入 DSDT
_GTS 控制方法 Going To Sleep,可选 DSDT
_S3 控制方法 返回S3状态对应的SLP_TYP值 DSDT
_WAK 控制方法 唤醒后执行 DSDT
_Lxx/_Exx GPE控制方法 对应GPE位的处理程序,Control Method方案中调用 DSDT的_GPE作用域
相关推荐
sitelist2 个月前
ACPI!device后ACPI!Name函数建立子节点对象
device·name·acpi
亚林瓜子3 个月前
AWS中国云中的ETL之从aurora搬数据到s3(Glue版——修复版)
云计算·etl·aws·s3·glue
nicepainkiller3 个月前
aws s3 对象存储 上传文件
云计算·aws·s3
DevOps0088 个月前
将 RustFS 用作 GitLab 对象存储后端
rust·gitlab·minio·分布式存储·s3·rustfs
ApacheSeaTunnel8 个月前
MySQL 数据同步至 S3file,并接入 Hive 访问:SeaTunnel 实践指南
大数据·mysql·开源·数据集成·s3·seatunnel·数据同步
DevOps0088 个月前
在 Azure Linux 上安装 RustFS
rust·minio·分布式存储·s3·rustfs
亚林瓜子9 个月前
AWS S3拒绝非https的请求访问
https·云计算·json·ssl·aws·s3
为美好的生活献上中指10 个月前
java每日精进 5.18【文件存储】
java·开发语言·minio·七牛云存储·s3·七牛云
太阳伞下的阿呆10 个月前
Aws S3上传优化
云计算·aws·云存储·亚马逊·s3