5.6.4. 通用事件处理
当OSPM接收到通用事件时,它会将控制权传递给ACPI感知的驱动程序,或者使用OEM提供的控制方法来处理该事件。 OEM每个GPE块可以在硬件中实现多达 128 个通用事件输入,每个输入都作为电平或边缘事件。也可以实现单个 256 引脚块,只要它是系统中定义的唯一块即可。
ACPI 硬件规范 中指定了通用事件的示例,其中定义了 EC_STS 和 EC_EN 位以使 OSPM 能够与 ACPI 感知的嵌入式控制器设备驱动程序进行通信。当嵌入式控制器空间中的接口生成中断或嵌入式控制器接口需要服务时,EC_STS位被设置。请注意,如果平台在ACPI环境中使用嵌入式控制器,则嵌入式控制器的SCI输出必须直接且排他地连接到单个GPE输入位。
硬件可以从GPEx_BLK中的位通过操作区域(I/O 空间、内存空间、PCI配置空间或嵌入式控制器空间)中的状态和使能位级联其他通用事件。有关详细信息,请参阅通用事件寄存器块中通用事件块 (GPEx_BLK) 的规范
OSPM 直接管理 GPEx 块中的位,尽管这些事件的源不是直接已知的,而是通过控制方法连接到系统中的。当OSPM收到通用事件(该事件来自GPEx_BLK、STS位、GPIO引脚或中断)时,OSPM执行以下操作:
禁止中断源
(GPEx_BLK EN 位):GPIO GPIO 信号事件中断。 |中断信号事件的中断。 |如果发生边沿事件,则清除状态位。
执行以下操作之一: 分派至识别ACPI的设备驱动程序。 |将匹配的控制方法排队等待执行。 |使用设备 _PRW 对象管理唤醒事件。
如果是级别事件,则等待控制方法处理程序完成并清除状态位。
使能中断源。
对于OSPM直接管理GPEx_BLK块中的位:
使能位必须可读/写。
状态位必须被锁存。
状态位必须读取/清除,并通过向状态位写入“1”来清除。
5.6.4.1. 用于GPE处理的_Exx、_Lxx和_Qxx方法
OEM、AML代码可以通过执行与事件匹配的控制方法,针对特定平台可能生成的每个事件执行OEM特定功能。对于GPE事件,OSPM将执行名称为\_GPE._TXX的控制方法,其中XX是需要处理的事件的十六进制值格式,T表示事件处理类型(对于边缘事件,T必须为“E”,对于电平事件,T必须为“L”)。 GPE0_BLK 中状态位的事件值从零 (_T00) 开始,到 (GPE0_BLK_LEN / 2) - 1 结束。GPE1_BLK 中状态位的事件值从 GPE1_BASE 开始,到 GPE1_BASE + (GPE1_BLK_LEN / 2) - 1 结束。 GPE0_BLK_LEN、GPE1_BASE和GPE1_BLK_LEN均在FADT中定义。
_Qxx 方法用于嵌入式控制器和 SMBus(见下文)。
5.6.4.1.1. 将匹配的控制方法排队等待执行
当引发通用事件时,OSPM使用命名约定来确定要排队执行的控制方法以及如何处理GPE和EOI。 GPEx_BLK中的GPEx_STS位使用 0 到FF之间的数字进行索引。对从使能状态位引发的事件进行排队的控制方法名称始终采用 \_GPE._Txx 形式,其中 xx 是事件值,T 表示要使用的事件 EOI 协议(“E”表示边沿触发,“L”表示电平触发)。 GPE0_BLK 中状态位的事件值从零 (_T00) 开始,到 (GPE0_BLK_LEN / 2) - 1 结束,并对应于 GPE0_BLK 中的每个状态位索引。 GPE1_BLK 中状态位的事件值偏移 GPE_BASE,因此从 GPE1_BASE 开始,到 GPE1_BASE + (GPE1_BLK_LEN / 2) - 1 结束。
例如,假设OEM为通信端口提供唤醒事件,并使用GPE0_STS位的第 4 位来提高唤醒事件状态。在OEM提供的定义块中,必须有一个使用名称\_GPE._L04或\GPE._E04来处理事件的方法声明。使用此类名称的控制方法声明的示例如下:
Method (\_GPE._L04) { // GPE 4 level wake handler
Notify (\_SB.PCIO.COM0, 2)
}
控制方法执行适合其处理的事件的任何操作。例如,如果该事件意味着设备已出现在槽中,则控制方法可能会向某个其他硬件寄存器确认该事件,并向适当的设备对象发出更改通知请求。或者,通用事件的原因可能由多个源引起,在这种情况下,该事件的控制方法确定源并采取适当的操作。
当从与嵌入式控制器关联的GPE位引发通用事件时,嵌入式控制器驱动程序使用ACPI为嵌入式控制器驱动程序定义的另一个命名约定来确定要排队执行的控制方法。嵌入式控制器驱动程序与嵌入式控制器交换的查询编号从 0 到FF,产生事件代码 01 到FF。 (来自嵌入式控制器的查询响应 0 保留用于“无未完成的事件”。)要排队的控制方法的名称始终采用 _Qxx 形式,其中 xx 是嵌入式控制器确认的查询编号。处理嵌入式控制器查询的控制方法的声明示例如下:
Method(_Q34) { // embedded controller event for thermal
Notify (\_SB.TZ0.THM1, 0x80)
}
当 SMBus 驱动程序处理 SMBus 警报时,SMBus 驱动程序使用ACPI为驱动程序定义的类似命名约定来确定排队执行的控制方法。当SMBus主机控制器接收到警报时,它通常接收发出警报的设备的SMBus地址和一个字的数据。在使用 SMBALERT# 进行通知的实现中,只会收到设备地址。队列控制方法的名称始终采用 _Qxx 形式,其中 xx 是发出警报的设备的 SMBus 地址。 SMBus 地址为 7 位长,对应于十六进制值 0 到 7F,但有些地址已保留且不会使用。控制方法将始终使用一个参数进行排队,该参数包含与警报一起接收到的数据字。 SMBus 使用 SMBALERT# 进行通知是一个例外,在这种情况下,参数将为 0。处理 SMBus 警报的控制方法的声明示例如下:
Method(_Q18, 1) { // Thermal sensor device at address 001 1000
// Arg0 contains notification value (if any)
// Arg0 = 0 if device supports only SMBALERT#
Notify (\_SB.TZ0.THM1, 0x80)
}
5.6.4.1.2. 分派至 ACPI 感知设备驱动程序
某些设备支持(例如嵌入式控制器)需要专用的GPE来为设备提供服务。此类 GPE 被分派到本机OS代码进行处理,而不是分派到相应的GPE特定控制方法。
对于嵌入式控制器,OS本机、ACPI感知驱动程序会为其设备提供GPE事件。该驱动程序为嵌入式控制器设备提供服务,并通过使用查询命令确定嵌入式控制器何时报告事件。当发生嵌入式控制器事件时,ACPI感知驱动程序会将请求分派给其他ACPI感知驱动程序,这些驱动程序已注册来处理嵌入式控制器查询或对控制方法进行排队以处理每个事件。如果没有设备驱动程序来处理特定查询,OEM、AML代码可以执行OEM特定功能,这些功能是针对特定平台上的每个事件定制的,方法是在命名空间中包含用于处理这些事件的特定控制方法。对于嵌入式控制器事件,OSPM将对名称为_QXX的控制方法进行排队,其中XX是查询代码的十六进制格式。请注意,每个嵌入式控制器设备都可以具有查询事件控制方法。
同样,对于 SMBus 驱动程序,如果没有驱动程序注册 SMBus 警报,则 SMBus 驱动程序将对控制方法进行排队来处理这些警报。方法必须放置在名为 _QXX 的 SMBus 设备下,其中XX是发送警报的设备的 SMBus 地址的十六进制格式。
5.6.4.2. GPE 唤醒事件
通用事件的一个重要用途是实现设备唤醒事件。 ACPI事件编程模型的组件按以下方式交互:
当设备发出唤醒信号时,用于跟踪该设备的通用状态事件位被设置。
当相应的通用使能位被使能时,SCI中断被置位。
如果系统正在睡眠,这将导致硬件(如果可能)将系统转换为S0状态。
系统运行后,OSPM将调度相应的GPE处理程序。
处理程序需要确定哪个设备对象已发出唤醒信号,并对已发出唤醒信号的相应设备对象执行唤醒通知命令。
- 反过来,OSPM将通知每个设备的OSPM本机驱动程序,该驱动程序将唤醒其设备以提供服务。
唤醒事件不得与同一GPE输入上的非唤醒(运行时)事件混合。此规则的唯一例外是以下特殊设备。仅允许以下设备将单个GPE用于唤醒和运行时事件:
- 按钮设备:PNP0C0C - 电源按钮设备| PNP0C0D - 盖子装置| PNP0C0E - 睡眠按钮设备
2.PCI总线唤醒事件报告(PME):PNP0A03 - PCI主机桥
所有不专门与GPE输入相关的唤醒事件(例如,多个唤醒事件共享一个输入)必须具有单独的启用和状态位,以便正确处理系统使用的语义。
5.6.4.2.1. 使用设备 _PRW 对象管理唤醒事件
设备的 _PRW 对象向通用状态寄存器块提供从零开始的位索引,以指示GPE0_BLK或GPE1_BLK中的哪个通用状态位用作特定设备的唤醒掩码。尽管硬件必须维护单独的设备唤醒使能位,但系统可以通过使用OEM专用硬件来提供二级状态和使能位,从而使多个设备使用相同的通用事件位。在这种情况下,OEMAML代码负责第二级启用和状态位。
OSPM通过启用或禁用其相应的GPE并执行其_PSW控制方法(用于处理二级启用)来启用或禁用设备唤醒功能。当GPE被置位时,OSPM仍然执行相应的GPE控制方法,该方法确定哪些设备唤醒被置位并通知相应的设备对象。然后,本机OS驱动程序会收到通知,其设备已声明唤醒,为此驱动程序将打开其设备电源以对其进行服务。
如果系统处于睡眠状态,当启用的GPE位被置位时,硬件会将系统转换为S0状态(如果可能)。
5.6.4.2.2. 使用 _Wxx 控制方法确定系统唤醒源
转换到S0状态后,OSPM可以评估_GPE范围中的_SWS对象,以确定作为转换事件源的GPE的索引。当多个设备共享单个GPE时,平台提供 _Wxx 控制方法,其中 xx 是GPE索引,如使用 _Wxx 控制方法确定系统唤醒源中所述,该方法允许确定转换的源设备。如果实现,_Wxx 控制方法必须存在于_GPE范围内或GPE块设备范围内。
如果实现 _Wxx,则硬件或固件必须检测并保存源设备,如 sws-system-wake-source 中所述。在调用期间,_Wxx 控制方法确定源设备,并在设备上发出 Notify(<device>, 0x2),从而导致系统转换到 S0 状态。如果设备使用特定于总线的唤醒方法,则必须在具有 _PRW 方法的设备的父设备上发出 Notify。__Wxx_ 方法必须仅向其设备作用域中包含 _PRW 方法的设备发出 Notify(<device>, 0x2)。OSPM 对 _SWS 和 _Wxx 对象的评估是不确定的。因此,平台不得依赖 _SWS 或 _Wxx 的评估来清除任何硬件状态(包括 GPEx_STS 位)或执行任何唤醒相关操作。
如果_SWS 对象返回的GPE索引仅由系统中的单个_PRW 对象引用,则暗示包含该_PRW 的设备是唤醒源。在这种情况下,平台没有必要提供__Wxx_方法。