EC和KBC是位於LPC下的一個控制器,KBC用來控制鍵盤的運作而EC通常包含了KBC的功能,且還有許多和硬體溝通功能,如Keyboard, PS2 device, Hot Key control, LED control, LCD brightness, power management, 音量控制, 電池偵測, Thermal Control等。我們要透過EC與硬體的溝
通方式在ACPI spec裡有定義,它會透過OS Driver來達到控制、監控硬體的功能,於是我們必需撰寫ASL code來支援這些功能,也就是BIOS的工作。它也提拱了三組的Host Interface,來讓我們下Command來控制它。
Host Interface 1 (no Logical KBC Interface): Standard keyboard functions. (Data port: 0x60, Command/Status port: 0x64)
Status Port 0x64:
Host Interface 2 (Logical KBC Interface 0): Operating System access of ACPI command. (Data port: 0x62, Command/Status port: 0x66)
Status Port:0x66:
0x80 – Read EC space with SCI
0x81 – Write EC space with SCI
0x82 – Burst enable no SCI needed
0x83 – Burst disable no SCI needed
0x84 – Query SCI event
當發Q Event 時,也就是EC控制的部分硬體發出事件(比如說Hot Key事件: Fn+F3調整LCD亮度),此時OS會到EC讀取一組Q Event number(0x0~0xFF), 然後再透過ACPI Driver去執行ASL _QXX下的Method,此ASL code就是我們BIOS所需要implement的部分,我們必須把硬體事件該做的事定義出來。
pesudo code:
Device(EC0) {
// PnP ID Name(_HID, EISAID(“PNP0C09”))
// Returns the “Current Resources” of EC Name(_CRS,
ResourceTemplate(){
IO(Decode16, 0x62, 0x62, 0, 1)
IO(Decode16, 0x66, 0x66, 0, 1)
})
// Indicate that the EC SCI is bit 0 of the GP_STS register
Name(_GPE, 0) // embedded controller is wired to bit 0 of GPE
OperationRegion(\EC0, EmbeddedControl, 0, 0xFF)
Field(EC0, ByteAcc, Lock, Preserve) {
// Field definitions
... }
// Query methods
Method(_Q00){..}
Method(_QFF){..}
}
Host Interface 3 (Logical KBC Interface 1): SMI access of special command (Data port: 0x68, Command/Status port: 0x6C)
範例1: 做 KBC Reset. (KBC Rest command 為Host Interface 1 的0xFE)
∴我們必需先判斷0x64 Status Port 的IBF Bit 1和OBF Bit 0是否為0.
當為0 時再對0x64 port下0xFE command.
pesudo code:
#define KBC_STD_CMD_RESET 0xFE ;Reset command 0xFE
#define KbcTimeOutPeriod xxxxxxx
KBC_DEV mKbcDev;
void main ( ) {
...
mKbcDev.CmdPort = 0x64;
mKbcDev.DataPort = 0x60;
TimeOut = EfiReadTsc() + KbcTimeOutPeriod;
do {
KbcReadStatus (&ControlStatus);
ControlStatus &= 0x02;
if ((EfiReadTsc() >= TimOut) { ;KBC timeout
return ERROR;
}
} while (ControlStatus != 0x0);
KbcSetCmd (KBC_STD_CMD_RESET);
...
}
EFI_STATUS
KbcSetCmd (
IN UINT8 Cmd
)
{
mKbcDev.Write(Cmd);
....
}
EFI_STATUS
KbcReadStatus (
Out UINT8 *Status
)
{
mKbcDev.Read(Status);
....
}
範例2: 在OS下透過Hot Key: Fn+F3,Fn+F4來EC 控制LCD亮度控制,請撰寫相關ASL code. (Hot Key Event: 0x50:增加亮度, 0x4C:減少亮度)
(等補完ACPI介紹再提供範例2解答,先放流程圖)
這篇文章提到一些ASL code、硬體事件的發生和ACPI Driver等關鍵字,這是ACPI spec所定義的,將在其它篇文章介紹ACPI在做什麼。
good
回覆刪除HI 我在寫讀取EC的shell 程式中遇到一些問題 方便請教您嗎
回覆刪除