ACPI GED、HED及Linux处理流程相关技术问询
对ACPI通用事件设备(GED)、硬件错误设备(HED)及Linux处理流程的理解
1. 固件部分
- 操作系统的OSPM子系统通过GED1._CRS得知中断51和243与GED1关联;
- 当OS检测到中断51或243时,OSPM会接管中断并调用GED1的_EVT()方法;
- GED1._EVT()会以0x80为通知值通知HED0。
对应的ASL代码如下:
Device (GED1) { Name (_HID, "ACPI0013") Name (_UID, Zero) Method (_STA) { Return (0xF) } Name (_CRS, ResourceTemplate () { Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 51 } // Socket 0 GHESv2 Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive) { 243 } // Socket 1 GHESv2 }) Method (_EVT, 1, Serialized) { Switch (ToInteger (Arg0)) { Case (51) { // Socket 0 GHESv2 Notify (HED0, 0x80) } Case (243) { // Socket 1 GHESv2 Notify (HED0, 0x80) } } } } Device (HED0) { Name (_HID, EISAID ("PNP0C33")) Name (_UID, Zero) }
2. Linux部分
- Linux通过PNP0C33值识别HED0为硬件错误设备;
- Linux使用
drivers/acpi/hed.c驱动处理HED0; - 上述
Notify(HED0, 0x80)最终会触发drivers/acpi/hed.c中的如下代码:
static void acpi_hed_notify(struct acpi_device *device, u32 event) { blocking_notifier_call_chain(&acpi_hed_notify_list, 0, NULL); }
技术疑问解答
1. Linux是否因_HID属性值为PNP0C33,将drivers/acpi/hed.c驱动与HED0设备匹配?该理解是否正确?
完全正确。Linux的ACPI驱动匹配机制核心就是依靠设备的_HID(硬件ID)。在hed.c驱动中,明确注册了匹配表:
static const struct acpi_device_id hed_device_ids[] = { {"PNP0C33", 0}, {"", 0}, }; MODULE_DEVICE_TABLE(acpi, hed_device_ids);
当ACPI子系统枚举到HED0设备时,会通过这个匹配表找到对应的hed.c驱动并完成绑定。
2. Notify(HED0, 0x80)中的0x80对应acpi_hed_notify()的u32 event参数,但该参数未被使用,为何需要指定0x80这个特定值?
0x80是ACPI规范定义的通用硬件错误通知标准事件码,属于跨OS的统一约定。虽然当前Linux hed驱动没有直接使用这个参数,但固件必须遵循规范用这个值来通知OS发生了硬件错误事件——这样Windows、Linux等不同操作系统都能统一识别这个通知的含义。如果随意使用其他值,OS可能无法判定这是硬件错误事件,进而无法触发后续的错误处理流程。
3. 若存在信息传递,Notify(HED0, 0x80)是如何向drivers/acpi/hed.c中的acpi_hed_notify()传递信息的?
整个传递流程是:
- 固件调用
Notify(HED0, 0x80)后,ACPI子系统会捕获到这个通知事件; - ACPI子系统根据HED0的设备对象,找到已经绑定的hed.c驱动;
- ACPI子系统调用驱动中注册的通知回调函数
acpi_hed_notify,并将0x80作为event参数传入; - 这个0x80本身就是传递的核心信息,它明确告诉OS“这是一个硬件错误事件”。当前驱动未使用该参数只是因为当前场景不需要区分更细的错误类型,未来如果规范扩展或驱动需要细化处理,这个参数就会发挥作用。
内容的提问来源于stack exchange,提问作者smwikipedia
相关产品推荐
相关产品推荐

