Note: 淺談 _GPE of ACPI

在ACPI 的 DSDT Table 會有一個 _GPE Object 是用來讓OSPM 做 General-Purpose Event Handling (see Section 5.6.4 in ACPI 4.0a spec.)的動作指引.

這裏是用 Thinkpad X60 當做解說材料, 對應到 ICH7 (Intel ICH7 datasheet), Dump ACPI的方法可以參考之前的 Note: Dump ACPI Tables , iasl 我現在用的是 Intel 20090730 版本

_GPE 是HW/SW共同建構的, 主要是用來辨識SCI發生後, 系統需要另外處理的事件, 在Intel platform 裡 ICH 會包含一個 ACPI 對應I/O Registers, ICH7 稱Power Management I/O Registers (see 10.8.3 in Datasheet), 而ICH7 負責GPE的, 是 GPE0_STS/GPE0_EN 兩個暫存器, 這個可以在 FADT/ACPI Table找到對應的 GPE0_BLK (Section 4.7.4 in ACPI 4.0a)

_GPE在Section 5.6.4.1 in ACPI 4.0a 說明了, Event 的種類會有 _Exx/_Lxx/_Qxx 三種, E是Edge的縮寫, L是Level, Q則是 Query (from Query commad 0x84 of EC, Q event 對應 SMBUS Device與EC),  在Intel Platform上用到的主要是L與 Q event

下面是X60 用的 _GPE 描述

Scope (\_GPE)
{
Method (_L18, 0, NotSerialized)
{
Store (\_SB.PCI0.LPC.EC.HWAK, Local0)  // X60 的EC 透過 Read 這各 Byte 來清除 EC的 Wakeup event 處理, see coreboot patch
Store (Local0, \RRBF)
Sleep (0x0A)
If (And (Local0, 0x02)) {}
If (And (Local0, 0x04))
{
If (\W98F)
{
Notify (\_SB.SLPB, 0x02)
}
Else
{
Notify (\_SB.LID, 0x02)
}
}

If (And (Local0, 0x10))
{
And (Local0, 0xF7, Local0)
Notify (\_SB.SLPB, 0x02)
}

If (And (Local0, 0x08))
{
\_SB.GDCK.GGPE ()
Notify (\_SB.SLPB, 0x02)
}

If (And (Local0, 0x40)) {}
If (And (Local0, 0x80))
{
Notify (\_SB.SLPB, 0x02)
}
}

Method (_L09, 0, NotSerialized)
{
If (\_SB.PCI0.EXP0.PSP0)
{
Store (0x01, \_SB.PCI0.EXP0.PSP0)
Notify (\_SB.PCI0.EXP0, 0x02)
}

If (\_SB.PCI0.EXP1.PSP1)
{
Store (0x01, \_SB.PCI0.EXP1.PSP1)
Notify (\_SB.PCI0.EXP1, 0x02)
}

If (\_SB.PCI0.EXP2.PSP2)
{
Store (0x01, \_SB.PCI0.EXP2.PSP2)
Notify (\_SB.PCI0.EXP2, 0x02)
}

If (\_SB.PCI0.EXP3.PSP3)
{
Store (0x01, \_SB.PCI0.EXP3.PSP3)
Notify (\_SB.PCI0.EXP3, 0x02)
}
}

Method (_L01, 0, NotSerialized)
{
If (\_SB.PCI0.EXP2.HPCS)
{
Store (0x01, \_SB.PCI0.EXP2.HPCS)
If (\_SB.PCI0.EXP2.ABP)
{
Store (0x01, \_SB.PCI0.EXP2.ABP)
}

If (\_SB.PCI0.EXP2.PDC)
{
Store (0x01, \_SB.PCI0.EXP2.PDC)
Store (0x00, \_SB.PCI0.EXP2.XCPF)
Notify (\_SB.PCI0.EXP2, 0x00)
If (\_SB.PCI0.EXP2.PDS)
{
Store (0x01, \_SB.PCI0.EXP2.XCPF)
Sleep (0x64)
Notify (\_SB.PCI0.EXP2.EXUP, 0x01)
}
}
}
}

Method (_L02, 0, NotSerialized)
{
Store (0x00, \_SB.PCI0.LPC.SWGE)
If (\_SB.PCI0.LPC.EC.HKEY.DHKC)
{
If (DT02)
{
\_SB.PCI0.LPC.EC.HKEY.MHKQ (0x6022)
}
}

Notify (\_TZ.THM1, 0x80)
If (\OSPX)
{
Notify (\_PR.CPU0, 0x80)
If (\MPEN)
{
Notify (\_PR.CPU1, 0x80)
}
}
}
}

可以看到 _L18 是從EC讀 Wake-up event 產生的原因, 而 _L18 從 ICH7 的Datasheet (Section 10.8.3)看來應該是接到GPIO8

image

_L09, 則是對應 PCI Express 的PME Event,

image

_L01 則是PCI 相關的 HotPlug Event, _L02 則是SWGPE Event 看來是 Thermal 的對應策略!

image

在 Section 5.6.4 in ACPI 4.0a 有描述 OSPM 應該怎樣處理, 節錄於下

OSPM manages the bits in the GPEx blocks directly, although the source to those events is not directly
known and is connected into the system by control methods. When OSPM receives a general-purpose event
(the event is from a GPEx_BLK STS bit), OSPM does the following:
1. Disables the interrupt source (GPEx_BLK EN bit).
2. If an edge event, clears the status bit.
3. Performs one of the following:
 Dispatches to an ACPI-aware device driver.
 Queues the matching control method for execution.
 Manages a wake event using device _PRW objects.
4. If a level event, clears the status bit.
5. Enables the interrupt source.
For OSPM to manage the bits in the GPEx_BLK blocks directly:
 Enable bits must be read/write.
 Status bits must be latching.
 Status bits must be read/clear, and cleared by writing a “1” to the status bit.

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s

%d 位部落客按了讚: