7.4. OEM 提供的系统级控制方法
由 OEM 提供的定义块提供若干适用于系统级管理的控制。这些控制由 OSPM 使用,以集成到 OEM 提供的功能中。下表列出了可提供的已定义 OEM 系统控制。
表 7.10 用于系统级功能的 BIOS 提供的控制方法
| 对象 | 描述 |
|---|---|
| \_PTS | 用于通知平台即将进行睡眠转换的控制方法。 |
| \_S0 | 定义系统 \_S0 状态模式的包。 |
| \_S1 | 定义系统 \_S1 状态模式的包。 |
| \_S2 | 定义系统 \_S2 状态模式的包。 |
| \_S3 | 定义系统 \_S3 状态模式的包。 |
| \_S4 | 定义系统 \_S4 状态模式的包。 |
| \_S5 | 定义系统 \_S5 状态模式的包。 |
| \_TTS | 用于准备进入睡眠并在唤醒后运行一次的控制方法 |
| \_WAK | 在唤醒后运行一次的控制方法。 |
注
兼容性问题:_BFS(从睡眠返回)和 _GTS(进入睡眠)方法已在 ACPI 5.0A 中弃用。
7.4.1. _PTS(准备进入睡眠)
_PTS 控制方法由 OS 在 S1、S2、S3、S4 的睡眠转换过程中,以及在有序的 S5 关闭过程中执行。睡眠状态值(例如,S5 软关机状态对应的 1、2、3、4 或 5)会传递给 _PTS 控制方法。此方法会在 OSPM 已通知原生设备驱动程序睡眠状态转换之后、且在 OSPM 有机会为睡眠状态转换将系统完全准备好之前调用。因此,该控制方法可能会在实际进入目标睡眠状态之前相当长的一段时间执行。如果 OSPM 中止了睡眠状态转换,OSPM 应运行 _WAK 方法以向平台指示此情况。
参数(1):
Arg0 - 一个 Integer,包含睡眠状态的值(S1 为 1,S2 为 2,依此类推)
返回值:
无
_PTS 控制方法不能修改系统中任何设备的当前配置或电源状态。例如,当 SLP_EN 位被设置时,_PTS 仅会将睡眠类型存储到嵌入式控制器中,以便按顺序将系统切换到睡眠状态。
平台在调用 _PTS 时不得对机器的状态做任何假设。例如,要求设备已配置并已启用的操作区域访问可能不会成功,因为这些设备可能由于即插即用或电源管理操作而处于非译码状态。
7.4.2. _Sx(系统状态)
系统支持的所有系统状态都必须在静态定义块中提供一个包含如下格式 DWORD 值的包。系统状态称为 S0-S5,在命名空间中引用为 \_S0-\_Sx,并且为清晰起见,除非特指已命名的 _Sx 对象,否则使用简短的 Sx 名称。对于每个 Sx 状态,都定义了相应的系统行为。
参数:
无
返回值:
一个包,其中包含一个 Integer,该 Integer 包含用于睡眠的寄存器值
表 7.11 系统状态包
| 字节长度 | 字节偏移 | 描述 |
|---|---|---|
| 1 | 0 | 用于进入该系统状态的 PM1a_CNT.SLP_TYP 寄存器的值。在 硬件精简 平台上,这是用于 SLEEP_CONTROL_REG.SLP_TYP 的 硬件精简 睡眠类型值。 |
| 1 | 1 | 用于进入该系统状态的 PM1b_CNT.SLP_TYP 寄存器的值。为进入任意给定状态,OSPM 必须先写入 PM1a_CNT.SLP_TYP 寄存器,再写入 PM1b_CNT.SLP_TYP 寄存器。在 硬件精简 平台上,此值会被忽略。 |
| 2 | 2 | 保留 |
状态 S1-S4 表示某种系统睡眠状态。S0 状态是系统工作状态。从其他某个系统状态(如睡眠)转换到 S0 状态是自动的,并且由于指令正在执行,OSPM 认为系统处于 S0 状态。转换到任何系统睡眠状态仅能通过操作软件指示硬件进入适当状态来完成,而操作软件只能在 Power Resource 和 Bus/Device Package 对象所定义的要求范围内执行此操作。
除 S4 和 S5 之外,所有运行时系统状态转换(例如,往返于 S0 状态)都以类似方式完成,因此执行此操作的代码序列如下:
/*
* Intel Architecture SetSleepingState example
*/
ULONG
SetSystemSleeping (
IN ULONG NewState
)
{
PROCESSOR_CONTEXT Context;
ULONG PowerSeqeunce;
BOOLEAN FlushCaches;
USHORT SlpTyp;
// Required environment: Executing on the system boot
// processor. All other processors stopped. Interrupts
// disabled. All Power Resources (and devices) are in
// corresponding device state to support NewState.
// Get h/w attributes for this system state
FlushCaches = SleepType[NewState].FlushCache;
SlpTyp = SleepType[NewState].SlpTyp & SLP_TYP_MASK;
_asm {
lea eax, OsResumeContext
push eax ; Build real mode handler the resume
push offset sp50 ; context, with eip = sp50
call SaveProcessorState
mov eax, ResumeVector ; set firmware's resume vector
mov [eax], offset OsRealModeResumeCode
mov edx, PM1a_STS ; Make sure wake status is clear
mov ax, WAK_STS ; (cleared by asserting the bit
out dx, ax ; in the status register)
mov edx, PM1b_STS ;
out dx, ax ;
and eax, not SLP_TYP_MASK
or eax, SlpTyp ; set SLP_TYP
or ax, SLP_EN ; set SLP_EN
cmp FlushCaches, 0
jz short sp10 ; If needed, ensure no dirty data in
call FlushProcessorCaches ; the caches while sleeping
sp10: mov edx, PM1a_SLP_TYP ; get address for PM1a_SLP_TYP
out dx, ax ; start h/w sequencing
mov edx, PM1b_SLP_TYP ; get address for PM1b_SLP_TYP
out dx, ax ; start h/w sequencing
mov edx, PM1a_STS ; get address for PM1x_STS
mov ecx, PM1b_STS
sp20: in ax, dx ; wait for WAK status
xchg edx, ecx
test ax, WAK_STS
jz short sp20
sp50:
}
// Done..
*ResumeVector = NULL;
return 0;
}
在 硬件精简 ACPI 平台上,所有运行时系统状态转换(例如,往返于 S0 状态)也以类似方式完成,但应包含以下内容,而不是 PM1*_BLK 寄存器位操作:
在确保任何期望的可唤醒中断已启用之后,OSPM 将 硬件精简 睡眠类型值写入 Sleep Control Register,并循环等待 Sleep Status Register 的 WAK_STS 位被置位,以指示平台已转换到 Working 状态。
7.4.2.1. 系统 _S0 状态(工作)
当系统处于 S0 状态时,它处于系统工作状态。该状态的行为定义如下:
处理器要么正在运行,要么处于 C-state,要么处于 LPI 状态。处理器复合体上下文会被保持,并且会按照这些处理器状态中任一种的定义执行指令。
动态 RAM 上下文会被保持,并且处理器可对其进行读/写。
设备状态由操作软件分别管理,并且可以处于任何设备状态(D0、D1、D2、D3hot 或 D3)。
Power Resources 处于与当前设备状态兼容的状态。
从某个系统睡眠状态转换到 S0 状态是自动的,并且由于 OSPM 正在执行指令,因此认为系统处于 S0 状态。
7.4.2.2. 系统 _S1 状态(保持处理器上下文的睡眠)
当系统处于 S1 睡眠状态时,其行为如下:
处理器不执行指令。处理器复合体上下文会被保持。
动态 RAM 上下文会被保持。
Power Resources 处于与系统 S1 状态兼容的状态。所有提供 S0 系统级引用的 Power Resources 都处于 OFF 状态。
设备状态与当前 Power Resource 状态兼容。只有那些仅引用在给定设备状态下处于 ON 状态的 Power Resources 的设备,才能处于该设备状态。在所有其他情况下,设备都处于 D3(关闭)状态。(或者至少其设备驱动程序必须认为它处于 D3 状态。例如,如果设备没有明确描述当系统处于睡眠状态时它如何能够保持某种非关闭状态,则操作软件必须假定该设备可能会丢失其电源和状态。)
被启用为可唤醒系统且能够从其当前设备状态执行此操作的设备,可以发起一个硬件事件,使系统状态转换到 S0。此转换会使处理器从其离开处继续执行。
要转换到 S1 状态,OSPM 必须刷新所有处理器缓存。
7.4.2.3. 系统 _S2 状态
S2 睡眠状态在逻辑上比 S1 状态更深,并且假定可节省更多电力。该状态的行为定义如下:
处理器不执行指令。处理器复合体上下文不被保持。
动态 RAM 上下文会被保持。
Power Resources 处于与系统 S2 状态兼容的状态。所有提供 S0 或 S1 系统级引用的 Power Resources 都处于 OFF 状态。
设备状态与当前 Power Resource 状态兼容。只有那些仅引用在给定设备状态下处于 ON 状态的 Power Resources 的设备,才能处于该设备状态。在所有其他情况下,设备都处于 D3(关闭)状态。
被启用为可唤醒系统且能够从其当前设备状态执行此操作的设备,可以发起一个硬件事件,使系统状态转换到 S0。此转换会使处理器从其启动位置开始执行。平台运行时固件会按需执行核心功能的初始化,以退出 S2 状态,并将控制权传递给固件恢复向量。有关平台固件初始化的更多详细信息,请参见平台启动固件的内存初始化。
由于处理器上下文在 S2 状态下可能会丢失,因此转换到 S2 状态要求操作软件将所有脏缓存刷新到动态 RAM(DRAM)。
7.4.2.4. 系统 _S3 状态
S3 状态在逻辑上比 S2 状态更深,并且假定可节省更多电力。该状态的行为定义如下:
处理器不执行指令。处理器复合体上下文不被保持。
动态 RAM 上下文会被保持。
Power Resources 处于与系统 S3 状态兼容的状态。所有提供 S0、S1 或 S2 系统级引用的 Power Resources 都处于 OFF 状态。
设备状态与当前 Power Resource 状态兼容。只有仅引用在给定设备状态下处于 ON 状态的 Power Resources 的设备,才能处于该设备状态。在所有其他情况下,设备都处于 D3(关闭)状态。
- 被使能为可唤醒系统且能够从其当前设备状态执行该操作的设备,可以发起一个硬件事件,使系统状态转换到 S0。此转换会导致处理器从其启动位置开始执行。平台运行时固件会按需执行核心功能初始化,以退出 S3 状态,并将控制权交给固件恢复向量。有关平台固件初始化的更多详细信息,请参见平台启动固件的内存初始化。
从软件视角来看,该状态在功能上与 S2 状态相同。运行上的差异在于,某些为了处于 S2 状态而可以保持为 ON 状态的 Power Resources,可能对于 S3 状态不可用。因此,对于 S3,可能需要让更多设备进入比 S2 更深的状态。类似地,某些设备唤醒事件在 S2 中可以工作,但在 S3 中则不能工作。
由于处理器上下文在 S3 状态期间可能会丢失,因此转换到 S3 状态要求操作系统软件将所有脏缓存刷新到 DRAM。
7.4.2.5. 系统 _S4 状态
当系统处于该状态时,它处于系统 S4 睡眠状态。该状态在逻辑上比 S3 状态更深,并且被认为能节省更多电能。该状态的行为定义如下:
处理器不执行指令。处理器复合体上下文不被保持。
DRAM 上下文不被保持。
Power Resources 处于与系统 S4 状态兼容的状态。所有提供 S0、S1、S2 或 S3 的系统级引用的 Power Resources 都处于 OFF 状态。
设备状态与当前 Power Resource 状态兼容。换句话说,当系统状态为 S4 时,所有设备都处于 D3 状态。
被使能为可唤醒系统且能够从 S4 中的其设备状态执行该操作的设备,可以发起一个硬件事件,使系统状态转换到 S0。此转换会导致处理器从其启动位置开始执行。
在 OSPM 执行了 _PTS 控制方法并将整个系统状态放入主内存之后,OSPM 可以用两种方式处理 S4 状态转换的下一阶段;保存和恢复主内存。第一种方式是使用操作系统的驱动程序访问磁盘和文件系统结构,将内存副本保存到磁盘,然后通过设置 SLP_EN 寄存器位来启动硬件 S4 序列。当系统唤醒时,固件执行正常的启动过程,并通过 firmware_waking_vector 加载器将控制权转移给 OS。随后 OS 恢复系统内存并继续执行。
进入 S4 状态的另一种方法是通过 S4BIOS 转换利用平台运行时固件。平台运行时固件使用固件将内存副本保存到磁盘,然后启动硬件 S4 序列。当系统唤醒时,固件从磁盘恢复内存,并通过将控制权转移到 FACS 唤醒向量来唤醒 OSPM。
S4BIOS 转换是可选的,但任何支持此机制的系统都必须支持通过直接 OS 机制进入 S4 状态。因此,S4 支持的首选机制是直接 OS 机制,因为它提供了更广泛的平台支持。备用的 S4BIOS 转换为不支持直接方法的操作系统提供了一种实现 S4 支持的方式。
7.4.2.6. 系统 _S5 状态(软关机)
S5 状态与 S4 状态类似,不同之处在于 OSPM 不保存任何上下文。系统处于软关机状态,并且在被唤醒时需要完整启动(平台启动固件和 OS)。软件使用不同的状态值来区分该状态和 S4 状态,以便平台启动固件中的初始启动操作能够区分此次启动是否将从已保存的内存映像中唤醒。在进入 S5 系统状态时,OSPM 在设置 SLP_EN 位之前不会禁用唤醒事件。这通过启用远程启动功能,为远程管理方案提供支持。符合 ACPI 的 OS 必须提供一种终端用户可访问的机制,以便在用户界面的单一位置禁用除系统电源按钮之外的所有唤醒设备。
7.4.3. _SWS(系统唤醒源)
此对象为 OSPM 提供了一种方式,以明确确定导致系统进入 S0 状态的事件源。包含唤醒事件源信息的通用事件和固定功能硬件寄存器不足以用于此目的,因为在从所有其他系统状态转换到 S0 状态之后,源事件信息可能不可用(S1-S5)。
为了确定导致系统转换到 S0 状态的源事件,当 _SWS 对象存在时,OSPM 将对其进行求值:在 \_GPE 作用域下(用于来自 GPE Blocks 的所有固定功能通用事件)、在 \_SB 作用域下(用于固定功能硬件事件),以及在 GPE Block 设备的作用域内(用于来自该设备的 GPE 事件)。根据平台确定导致系统转换到 S0 状态的源事件的需要,_SWS 对象可以存在于这些位置中的任意一个或多个位置。
参数:
无
返回值:
一个 Integer,包含如下所述的源事件
源事件的值取决于 _SWS 对象的位置:
如果在 \_GPE 作用域下对 _SWS 求值,则源事件是导致系统转换到 S0 的 GPE 的索引。如果在 \_GPE 作用域下对 _SWS 求值,则源事件是导致系统转换到 S0 的 GPE 的索引。
如果在 GPE Block 设备的作用域内对 _SWS 求值,则源事件是导致系统转换到 S0 的 GPE 的索引。在这种情况下,该索引相对于 GPE Block 设备,而不是系统范围内唯一的。
如果在 \_SB 作用域下对 _SWS 求值,则源事件是 PM1 状态寄存器中导致系统转换到 S0 的索引。
在上述所有情况下,如果无法确定 S0 转换的原因,则 _SWS 返回 Ones (-1)。
为了使 OSPM 能够通过 _SWS 对象确定 S0 状态转换的源,硬件或固件应检测并保存导致该转换的事件,以便在对 _SWS 对象求值期间返回。系统的单一唤醒源可以在转换期间由硬件锁存,以便 _SWS 不会返回错误的唤醒事件。不使用硬件为系统锁存单一唤醒源、而是使用固件保存唤醒源的实现,必须在唤醒事件发生后尽快执行此操作,以便 _SWS 不会返回与睡眠到唤醒转换之后发生的事件相对应的值。这样的实现还必须注意确保在保存唤醒源之后发生的事件不会覆盖原始唤醒源。
_SWS 返回的源事件数据必须针对每次进入 S0 状态的转换来确定。在系统驻留于 S0 状态期间,_SWS 返回的值也必须保持持久,因为 OSPM 可能会多次对 _SWS 求值。在这种情况下,平台必须对每次调用返回相同的源事件信息。
在 \_GPE 作用域内或在 GPE Block 设备的作用域内对 _SWS 对象求值之后,若存在与 _SWS 返回的 GPE 索引相对应的 _Wxx 控制方法,OSPM 将调用它。这使平台在 GPE 由多个设备共享时能够进一步确定源事件。详见使用 _Wxx 控制方法确定系统唤醒源。
7.4.4. _TTS(转换到状态)
_TTS 控制方法由 OSPM 在 S1、S2、S3、S4 以及有序 S5 关机的睡眠转换过程开始时执行。OSPM 将在通知任何原生模式设备驱动程序睡眠状态转换之前调用 _TTS。睡眠状态值(例如,对于 S5 软关机状态,值为 1、2、3、4 或 5)会传递给 _TTS 控制方法。
_TTS 控制方法还由 OSPM 在任何睡眠转换过程结束时执行,即当系统从 S1、S2、S3 或 S4 转换到 S0 时。OSPM 将在通知任何原生模式设备驱动程序睡眠状态转换结束之后调用 _TTS。工作状态值(0)会传递给 _TTS 控制方法。
参数:
Arg0 - 一个 Integer,包含睡眠状态的值(S1 为 1,S2 为 2,等等)
返回值
无
如果 OSPM 中止睡眠转换过程,OSPM 仍将针对 S0 转换运行 _TTS,以指示 OSPM 已返回到 S0 状态。平台必须假定,如果 OSPM 针对 S1、S2、S3 或 S4 转换调用 _TTS 控制方法,则 OSPM 会在返回到 S0 状态之前,针对 S0 转换调用 _TTS 控制方法。
当调用 _TTS 时,平台不得对机器状态作出任何假设。例如,需要设备已被配置并启用的 operation region 访问可能不会成功,因为这些设备可能由于即插即用或电源管理操作而处于非译码状态。
7.4.5. _WAK(系统唤醒)
系统从睡眠状态唤醒后,将调用 \_WAK 方法,并传递已经结束的睡眠状态值。该操作与系统中的其他驱动程序通知异步发生,并不是系统唤醒后采取的第一个动作。此控制方法的 AML 代码会发出设备、热以及其他通知,以确保 OSPM 检查那些在系统睡眠状态期间无法维持其状态的设备、热区等等的状态。例如,如果系统无法确定在 S2 状态期间某个设备是否被插入到总线或从总线移除,则 _WAK 方法在接收到睡眠状态值 2 时,将为该总线发出 devicecheck 类型的通知(有关通知类型的更多信息,请参见设备对象通知。
请注意,来自 _SB 节点的设备检查通知将导致 OSPM 重新枚举整棵树。只有支持硬件定义的枚举方法的总线才会在运行时自动完成此操作。这将包括由 ACPI 枚举的设备。
硬件没有义务跟踪提供结果状态所需的状态;然而,此方法必须返回有关由 OSPM 发起的最近一次睡眠操作的状态。返回值可用于向 OSPM 或用户提供附加信息。
参数:
Arg0 - 一个 Integer,包含睡眠状态的值(S1 为 1,S2 为 2,等等)
返回值:
一个 Package,包含两个 Integer,分别包含状态和电源供应 S-state
返回值信息
_WAK 返回一个具有以下格式的包:
Element 0 - 一个 Integer,包含一个位字段,表示睡眠期间发生的情况:
0x00000000 - 唤醒已发出信号且成功
0x00000001 - 唤醒已发出信号,但因电力不足而失败
0x00000002 - 唤醒已发出信号,但因热条件而失败
其他值 - 保留
元素 1 - 一个包含电源 S-state 的整数:
如果非零,则这是实际进入的电源的有效 S-state。该值用于检测由于从电源汲取的电流过大而未能进入目标 S-state 的情况。例如,当某个活动设备的电流消耗使系统的电源需求超过低电源供电标记时,就可能发生这种情况,从而阻止系统按预期进入更深的系统睡眠状态。