這篇文章我一直覺得很受用,從EC為出發點來了解,跟大家分享。
以下為轉帖。
=====================================================
1.Introduction
SCI是指系統控制中斷, 為支援ACPI的作業系統提供系統管理,客制化功能。
SMI是指系統管理中斷,由設備或者軟體需要呼叫SMM功能產生,使CPU進入SMM mode。
基本上進入ACPI mode以後SMI就很少用到了,對於EC來講SCI和SMI則是互斥的,一旦進入ACPI mode EC 就只會發SCI。通常EC會有兩根pin KBSMI&KBSCI連接到SB,EC可以配置這兩根pin的屬性,決定使用何種方式產生中斷,比如level trig,edge trig,pulse trig,我做的案子常常配置成64us低電平的pulse trig。
2.KBSMI#
其實EC很少用到SMI,除了少數測試項比如DOS下 Fn+F2下切屏等。不過KBSMI#的實現原理還是很有趣的。它的原理是這樣的:EC將一根pin接在SB上,而SB的GPIO有些具有multi function,可以配置成具SMI/SCI的功能。
BIOS code在初始化時將這個資訊宣告給SMI Table。一旦EC發了一個SMI,EC接在SB上面這根pin的status就會被置位,SB檢測到以後通過拉接在cpu上SMI pin產生一個SMI,cpu切換到SMM mode然後就會通過之前宣告的那些pin的status identify smiOwner,這時就可以認出是EC的SMI,隨後通過下command給EC讀取SMI event id,並通過該id去調用相關的method。
3.KBSCI#
Q_EVENT
所謂Q_EVENT指的是OS收到EC的SCI後,OS通過發84hcommand 給EC讀取EC Ram中的值,這個值被稱為Q_EVENT id。這也是Q_EVENT得名的原因(Q是Query的縮寫,而84h就是Query Embedded Controller)。然後OS中的asl code會根據該id去調用_QXX()如下面的code所示,這裡的XX指的就是EVENT id。那麼EC什麼時候會發Q_EVENT呢?當AC、Battery in/out,LID open/close ...
// AC Status Changed
Method(_Q83)
{
Store(0x83, DBG8)
Store(0x00, Local0)
Store(POWS, Local0)
If(LEqual(Local0,1))
{
Store(1,\_SB.PCI0.SBRG.EC.ADP1.ACP)
}
else
{
Store(0,\_SB.PCI0.SBRG.EC.ADP1.ACP)
}
Notify(\_SB.PCI0.SBRG.EC.ADP1,0x80)
Notify(\_PR.P001,0x80)
Notify(\_PR.P002,0x80)
}
那麼又有一個問題,那就是OS怎麼知道這個SCI是EC的呢?請看下面的asl code你就會明白了
Device(EC)
{
Name(_HID,EISAID("PNP0C09"))
Name(_GPE,0x06) // KB_SCI
...
}
在Device EC裡面宣告了EC的KB_SCI接在了SB的哪個pin上,這樣OS識別EC SCI的過程就和前面的SMI異曲同工了。
a. OS polling GPE register status bit。
b. SCI通過8259或者APIC,產生IRQ。
Chipset spec印證了我的想法,SCI可以配置成通過8259/APIC的方式產生中斷,而且中斷向量也是可配置的如下圖1所示:
BIOS在設置好該寄存器後會將SCI INT資訊存入ACPI FADT中,這樣OS就可以通過FADT獲得SCI使用的中斷號碼,從而能夠在SCI產生時處理該中斷,這部分請參考ACPI SPEC FADT部分。下圖2是使用ACPIVIEW看到我的工作機的FADT dump,如圖2所示我的機器ACPI使用APIC INT 9。
GPE
GPE其實是屬於BIOS的範疇了(當然Q_EVENT也是GPE的一種),其他部分跟EC並沒有多少關係,不過既然講了SCI,就順便提提GPE。
所謂GPE指的是 ACPI定義的一個general-purpose event namespace 與SB中的GP registers相對應。GPE register 包括GPE_STS和GPE_EN兩個部分對應該GPIO的status和enable
Event的觸發分Level和edge兩種,分別對應ACPI Method _LXX(),_EXX(),
XX分別代表具體的GPIO pin。
所以當系統在S0一旦相關的GPIO status有變化並且SCI enable,那麼就觸發SCI,於是形如_LXX(),_EXX(),就會被調用了。
That’s all!
Peter