ps2kbdctrller.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,781 行 · 第 1/3 页
C
1,781 行
if (((KEYBOARD_CONSOLE_IN_DEV *) Context)->KeyboardErr) {
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return ;
}
//
// If there is something error, issue a 'resend' command to keyboard
//
if (KeyReadStatusRegister (Context) & 0xc0) {
//
// wait for input buffer empty
//
for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
if (!(KeyReadStatusRegister (Context) & 0x02)) {
break;
}
gBS->Stall (30);
}
//
// issue the 'resend' command
//
KeyWriteDataRegister (Context, 0xfe);
}
Data = 0;
//
// if there is no key present, just return
//
if ((KeyReadStatusRegister (Context) & 0x21) != 0x1) {
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return ;
}
//
// Read one byte of the scan code and store it into the memory buffer
//
if (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT) {
Data = KeyReadDataRegister (Context);
//
// put the scancode into the memory scancode buffer
//
ConsoleIn->ScancodeBufCount++;
ConsoleIn->ScancodeBufEndPos++;
if (ConsoleIn->ScancodeBufEndPos >= KEYBOARD_BUFFER_MAX_COUNT) {
ConsoleIn->ScancodeBufEndPos = 0;
}
ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufEndPos] = Data;
//
// Handle Alt+Ctrl+Del Key combination
//
switch (Data) {
case SCANCODE_CTRL_MAKE:
ConsoleIn->Ctrled = TRUE;
break;
case SCANCODE_CTRL_BREAK:
ConsoleIn->Ctrled = FALSE;
break;
case SCANCODE_ALT_MAKE:
ConsoleIn->Alted = TRUE;
break;
case SCANCODE_ALT_BREAK:
ConsoleIn->Alted = FALSE;
break;
}
//
// if Alt+Ctrl+Del, Reboot the System
//
if (ConsoleIn->Ctrled && ConsoleIn->Alted && Data == 0x53) {
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
}
}
//
// Leave critical section and return
//
gBS->RestoreTPL (OldTpl);
return ;
}
STATIC
EFI_STATUS
GetScancodeBufHead (
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT32 Count,
OUT UINT8 *Buf
)
/*++
Routine Description:
Read several bytes from the scancode buffer without removing them.
This function is called to see if there are enough bytes of scancode
representing a single key.
Arguments:
Count - Number of bytes to be read
Buf - Store the results
Returns:
EFI_STATUS
--*/
// GC_TODO: ConsoleIn - add argument and description to function comment
// GC_TODO: EFI_NOT_READY - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
UINT32 Index;
UINT32 Pos;
Index = 0;
Pos = 0;
//
// check the valid range of parameter 'Count'
//
if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {
return EFI_NOT_READY;
}
//
// retrieve the values
//
for (Index = 0; Index < Count; Index++) {
if (Index == 0) {
Pos = ConsoleIn->ScancodeBufStartPos;
} else {
Pos = Pos + 1;
if (Pos >= KEYBOARD_BUFFER_MAX_COUNT) {
Pos = 0;
}
}
Buf[Index] = ConsoleIn->ScancodeBuf[Pos];
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
PopScancodeBufHead (
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT32 Count,
OUT UINT8 *Buf
)
/*++
Routine Description:
Read & remove several bytes from the scancode buffer.
This function is usually called after GetScancodeBufHead()
Arguments:
Count - Number of bytes to be read
Buf - Store the results
Returns:
EFI_STATUS
--*/
// GC_TODO: ConsoleIn - add argument and description to function comment
// GC_TODO: EFI_NOT_READY - add return value to function comment
// GC_TODO: EFI_SUCCESS - add return value to function comment
{
UINT32 Index;
Index = 0;
//
// Check the valid range of parameter 'Count'
//
if (Count <= 0 || ConsoleIn->ScancodeBufCount < Count) {
return EFI_NOT_READY;
}
//
// Retrieve and remove the values
//
for (Index = 0; Index < Count; Index++) {
if (Index != 0) {
ConsoleIn->ScancodeBufStartPos++;
if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {
ConsoleIn->ScancodeBufStartPos = 0;
}
}
Buf[Index] = ConsoleIn->ScancodeBuf[ConsoleIn->ScancodeBufStartPos];
ConsoleIn->ScancodeBufCount--;
}
ConsoleIn->ScancodeBufStartPos++;
if (ConsoleIn->ScancodeBufStartPos >= KEYBOARD_BUFFER_MAX_COUNT) {
ConsoleIn->ScancodeBufStartPos = 0;
}
return EFI_SUCCESS;
}
EFI_STATUS
KeyboardRead (
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
OUT UINT8 *Data
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
ConsoleIn - GC_TODO: add argument description
Data - GC_TODO: add argument description
Returns:
EFI_TIMEOUT - GC_TODO: Add description for return value
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
UINT32 TimeOut;
UINT32 RegFilled;
TimeOut = 0;
RegFilled = 0;
//
// wait till output buffer full then perform the read
//
for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
RegFilled = 1;
*Data = KeyReadDataRegister (ConsoleIn);
break;
}
gBS->Stall (30);
}
if (!RegFilled) {
return EFI_TIMEOUT;
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
KeyboardWrite (
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT8 Data
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
ConsoleIn - GC_TODO: add argument description
Data - GC_TODO: add argument description
Returns:
EFI_TIMEOUT - GC_TODO: Add description for return value
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
UINT32 TimeOut;
UINT32 RegEmptied;
TimeOut = 0;
RegEmptied = 0;
//
// wait for input buffer empty
//
for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
if (!(KeyReadStatusRegister (ConsoleIn) & 0x02)) {
RegEmptied = 1;
break;
}
gBS->Stall (30);
}
if (!RegEmptied) {
return EFI_TIMEOUT;
}
//
// Write it
//
KeyWriteDataRegister (ConsoleIn, Data);
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
KeyboardCommand (
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT8 Data
)
/*++
Routine Description:
GC_TODO: Add function description
Arguments:
ConsoleIn - GC_TODO: add argument description
Data - GC_TODO: add argument description
Returns:
EFI_TIMEOUT - GC_TODO: Add description for return value
EFI_TIMEOUT - GC_TODO: Add description for return value
EFI_SUCCESS - GC_TODO: Add description for return value
--*/
{
UINT32 TimeOut;
UINT32 RegEmptied;
TimeOut = 0;
RegEmptied = 0;
//
// Wait For Input Buffer Empty
//
for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
if (!(KeyReadStatusRegister (ConsoleIn) & 0x02)) {
RegEmptied = 1;
break;
}
gBS->Stall (30);
}
if (!RegEmptied) {
return EFI_TIMEOUT;
}
//
// issue the command
//
KeyWriteCommandRegister (ConsoleIn, Data);
//
// Wait For Input Buffer Empty again
//
RegEmptied = 0;
for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
if (!(KeyReadStatusRegister (ConsoleIn) & 0x02)) {
RegEmptied = 1;
break;
}
gBS->Stall (30);
}
if (!RegEmptied) {
return EFI_TIMEOUT;
}
return EFI_SUCCESS;
}
STATIC
EFI_STATUS
KeyboardWaitForValue (
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT8 Value
)
/*++
Routine Description:
wait for a specific value to be presented on
8042 Data register by keyboard and then read it,
used in keyboard commands ack
Arguments:
ConsoleIn - The KEYBOARD_CONSOLE_IN_DEV instance pointer
Value - The value to be waited for
Returns:
EFI_STATUS
--*/
// GC_TODO: EFI_SUCCESS - add return value to function comment
// GC_TODO: EFI_TIMEOUT - add return value to function comment
{
UINT8 Data;
UINT32 TimeOut;
UINT32 SumTimeOut;
UINT32 GotIt;
GotIt = 0;
TimeOut = 0;
SumTimeOut = 0;
//
// Make sure the initial value of 'Data' is different from 'Value'
//
Data = 0;
if (Data == Value) {
Data = 1;
}
//
// Read from 8042 (multiple times if needed)
// until the expected value appears
// use SumTimeOut to control the iteration
//
while (1) {
//
// Perform a read
//
for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
Data = KeyReadDataRegister (ConsoleIn);
break;
}
gBS->Stall (30);
}
SumTimeOut += TimeOut;
if (Data == Value) {
GotIt = 1;
break;
}
if (SumTimeOut >= mWaitForValueTimeOut) {
break;
}
}
//
// Check results
//
if (GotIt) {
return EFI_SUCCESS;
} else {
return EFI_TIMEOUT;
}
}
STATIC
EFI_STATUS
UpdateStatusLights (
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
)
/*++
Routine Description:
Show keyboard status lights according to
indicators in ConsoleIn.
Arguments:
Returns:
--*/
// GC_TODO: ConsoleIn - add argument and description to function comment
{
EFI_STATUS Status;
UINT8 Command;
//
// Send keyboard command
//
Status = KeyboardWrite (ConsoleIn, 0xed);
if (EFI_ERROR (Status)) {
return Status;
}
KeyboardWaitForValue (ConsoleIn, 0xfa);
//
// Light configuration
//
Command = 0;
if (ConsoleIn->CapsLock) {
Command |= 4;
}
if (ConsoleIn->NumLock) {
Command |= 2;
}
if (ConsoleIn->ScrollLock) {
Command |= 1;
}
Status = KeyboardWrite (ConsoleIn, Command);
if (EFI_ERROR (Status)) {
return Status;
}
KeyboardWaitForValue (ConsoleIn, 0xfa);
return Status;
}
EFI_STATUS
KeyGetchar (
IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
)
/*++
Routine Description:
Get scancode from scancode buffer
and translate into EFI-scancode and unicode defined by EFI spec
The function is always called in EFI_TPL_NOTIFY
Arguments:
ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer
Returns:
EFI_NOT_READY - Input from console not ready yet.
EFI_SUCCESS - Function executed successfully.
--*/
{
EFI_STATUS Status;
UINT8 ScanCode;
UINT8 Readed;
BOOLEAN Extended;
UINT8 ScancodeArr[4];
//
// 4 bytes most
//
UINT32 ScancodeArrPos;
//
// point to the current position in ScancodeArr
//
UINT32 TimeOut;
Readed = 0;
Extended = FALSE;
ScancodeArrPos = 0;
//
// Read one byte of the scan code and store it into the memory buffer
// This block of code is added to insert an action that is equivalent to
// the timer event handling function, so as to increase the frequency of
// detecting the availability of keys. Timer event has a max frequency of
// 18Hz which is insufficient
//
//
// If there is something error, issue a 'resend' command to keyboard
//
if (KeyReadStatusRegister (ConsoleIn) & 0xc0) {
//
// wait for input buffer empty
//
for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
if (!(KeyReadStatusRegister (ConsoleIn) & 0x02)) {
break;
}
gBS->Stall (30);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?