Fix the PS2 keyboard driver to call hotkey callback even no one is calling ReadKeyStroke

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11564 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
niruiyu
2011-04-19 06:53:29 +00:00
parent c1fd2767c1
commit c220787b13
4 changed files with 400 additions and 520 deletions

View File

@ -1,7 +1,7 @@
/** @file /** @file
Routines that access 8042 keyboard controller Routines that access 8042 keyboard controller
Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -558,7 +558,6 @@ ConvertKeyboardScanCodeToEfiKey[] = {
}, },
}; };
// //
// The WaitForValue time out // The WaitForValue time out
// //
@ -566,6 +565,122 @@ UINTN mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
BOOLEAN mEnableMouseInterface; BOOLEAN mEnableMouseInterface;
/**
Return the count of scancode in the queue.
@param Queue Pointer to instance of SCAN_CODE_QUEUE.
@return Count of the scancode.
**/
UINTN
GetScancodeBufCount (
IN SCAN_CODE_QUEUE *Queue
)
{
if (Queue->Head <= Queue->Tail) {
return Queue->Tail - Queue->Head;
} else {
return Queue->Tail + KEYBOARD_SCAN_CODE_MAX_COUNT - Queue->Head;
}
}
/**
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.
@param Queue Pointer to instance of SCAN_CODE_QUEUE.
@param Count Number of bytes to be read
@param Buf Store the results
@retval EFI_SUCCESS success to scan the keyboard code
@retval EFI_NOT_READY invalid parameter
**/
EFI_STATUS
GetScancodeBufHead (
IN SCAN_CODE_QUEUE *Queue,
IN UINTN Count,
OUT UINT8 *Buf
)
{
UINTN Index;
UINTN Pos;
//
// check the valid range of parameter 'Count'
//
if (GetScancodeBufCount (Queue) < Count) {
return EFI_NOT_READY;
}
//
// retrieve the values
//
for (Index = 0, Pos = Queue->Head; Index < Count; Index++, Pos = (Pos + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
Buf[Index] = Queue->Buffer[Pos];
}
return EFI_SUCCESS;
}
/**
Push one byte to the scancode buffer.
@param Queue Pointer to instance of SCAN_CODE_QUEUE.
@param Scancode The byte to push.
**/
VOID
PushScancodeBufTail (
IN SCAN_CODE_QUEUE *Queue,
IN UINT8 Scancode
)
{
if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {
return;
}
Queue->Buffer[Queue->Tail] = Scancode;
Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;
}
/**
Read & remove several bytes from the scancode buffer.
This function is usually called after GetScancodeBufHead()
@param Queue Pointer to instance of SCAN_CODE_QUEUE.
@param Count Number of bytes to be read
@param Buf Store the results
@retval EFI_SUCCESS success to scan the keyboard code
@retval EFI_NOT_READY invalid parameter
**/
EFI_STATUS
PopScancodeBufHead (
IN SCAN_CODE_QUEUE *Queue,
IN UINTN Count,
OUT UINT8 *Buf
)
{
UINTN Index;
//
// Check the valid range of parameter 'Count'
//
if (GetScancodeBufCount (Queue) < Count) {
return EFI_NOT_READY;
}
//
// Retrieve and remove the values
//
for (Index = 0; Index < Count; Index++, Queue->Head = (Queue->Head + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
Buf[Index] = Queue->Buffer[Queue->Head];
}
return EFI_SUCCESS;
}
/** /**
Read data register . Read data register .
@ -611,23 +726,14 @@ KeyWriteDataRegister (
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn, IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT8 Data IN UINT8 Data
) )
{ {
EFI_ISA_IO_PROTOCOL *IsaIo; ConsoleIn->IsaIo->Io.Write (
ConsoleIn->IsaIo,
// EfiIsaIoWidthUint8,
// Use IsaIo protocol to perform IO operations ConsoleIn->DataRegisterAddress,
// 1,
IsaIo = ConsoleIn->IsaIo; &Data
);
IsaIo->Io.Write (
IsaIo,
EfiIsaIoWidthUint8,
ConsoleIn->DataRegisterAddress,
1,
&Data
);
} }
/** /**
@ -643,24 +749,15 @@ KeyReadStatusRegister (
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
) )
{ {
EFI_ISA_IO_PROTOCOL *IsaIo;
UINT8 Data; UINT8 Data;
ConsoleIn->IsaIo->Io.Read (
// ConsoleIn->IsaIo,
// Use IsaIo protocol to perform IO operations EfiIsaIoWidthUint8,
// ConsoleIn->StatusRegisterAddress,
IsaIo = ConsoleIn->IsaIo; 1,
&Data
IsaIo->Io.Read ( );
IsaIo,
EfiIsaIoWidthUint8,
ConsoleIn->StatusRegisterAddress,
1,
&Data
);
return Data; return Data;
} }
/** /**
@ -676,21 +773,13 @@ KeyWriteCommandRegister (
IN UINT8 Data IN UINT8 Data
) )
{ {
EFI_ISA_IO_PROTOCOL *IsaIo; ConsoleIn->IsaIo->Io.Write (
ConsoleIn->IsaIo,
// EfiIsaIoWidthUint8,
// Use IsaIo protocol to perform IO operations ConsoleIn->CommandRegisterAddress,
// 1,
IsaIo = ConsoleIn->IsaIo; &Data
);
IsaIo->Io.Write (
IsaIo,
EfiIsaIoWidthUint8,
ConsoleIn->CommandRegisterAddress,
1,
&Data
);
} }
/** /**
@ -732,7 +821,7 @@ KeyboardTimerHandler (
EFI_TPL OldTpl; EFI_TPL OldTpl;
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn; KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
ConsoleIn = Context; ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
// //
// Enter critical section // Enter critical section
@ -749,182 +838,27 @@ KeyboardTimerHandler (
// //
// To let KB driver support Hot plug, here should skip the 'resend' command for the case that // To let KB driver support Hot plug, here should skip the 'resend' command for the case that
// KB is not connected to system. If KB is not connected to system, driver will find there's something // KB is not connected to system. If KB is not connected to system, driver will find there's something
// error in the following code and wait for the input buffer empty, this waiting time shoulb be short enough since // error in the following code and wait for the input buffer empty, this waiting time shoulb be short enough since
// this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected. // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.
// Just skip the 'resend' process simply. // Just skip the 'resend' process simply.
// //
Data = 0; while ((KeyReadStatusRegister (ConsoleIn) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) ==
KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA
// ) {
// if there is no key present, just return
//
if ((KeyReadStatusRegister (Context) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) != KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {
// //
// Leave critical section and return // Read one byte of the scan code and store it into the memory buffer
// //
gBS->RestoreTPL (OldTpl); Data = KeyReadDataRegister (ConsoleIn);
PushScancodeBufTail (&ConsoleIn->ScancodeQueue, Data);
return ;
} }
// KeyGetchar (ConsoleIn);
// 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 // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL (OldTpl);
return ;
}
/**
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.
@param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
@param Count Number of bytes to be read
@param Buf Store the results
@retval EFI_SUCCESS success to scan the keyboard code
@retval EFI_NOT_READY invalid parameter
**/
EFI_STATUS
GetScancodeBufHead (
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT32 Count,
OUT UINT8 *Buf
)
{
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;
}
/**
Read & remove several bytes from the scancode buffer.
This function is usually called after GetScancodeBufHead()
@param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
@param Count Number of bytes to be read
@param Buf Store the results
@retval EFI_SUCCESS success to scan the keyboard code
@retval EFI_NOT_READY invalid parameter
**/
EFI_STATUS
PopScancodeBufHead (
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
IN UINT32 Count,
OUT UINT8 *Buf
)
{
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;
} }
/** /**
@ -1205,115 +1139,55 @@ UpdateStatusLights (
} }
/** /**
Get scancode from scancode buffer Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
and translate into EFI-scancode and unicode defined by EFI spec
The function is always called in TPL_NOTIFY The function is always called in TPL_NOTIFY.
@param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer
@retval EFI_NOT_READY Input from console not ready yet.
@retval EFI_SUCCESS Function executed successfully.
**/ **/
EFI_STATUS VOID
KeyGetchar ( KeyGetchar (
IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
UINT8 ScanCode; UINT8 ScanCode;
UINT8 Readed; BOOLEAN Extended;
BOOLEAN Extended; UINTN Index;
UINT8 ScancodeArr[4]; EFI_KEY_DATA KeyData;
UINTN Index; LIST_ENTRY *Link;
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
// //
// 4 bytes most // 4 bytes most
// //
UINT32 ScancodeArrPos; UINT8 ScancodeArr[4];
UINT32 ScancodeArrPos;
// //
// point to the current position in ScancodeArr // point to the current position in ScancodeArr
// //
Readed = 0;
Extended = FALSE; Extended = FALSE;
ScancodeArrPos = 0; 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
//
//
// To let KB driver support Hot plug, here should skip the 'resend' command for the case that
// KB is not connected to system. If KB is not connected to system, driver will find there's something
// error in the following code and wait for the input buffer empty, this waiting time shoulb be short enough since
// this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.
// Just skip the 'resend' process simply.
//
if (((KeyReadStatusRegister (ConsoleIn) & 0x21) == 0x1) && (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT)) {
Readed = KeyReadDataRegister (ConsoleIn);
//
// 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] = Readed;
//
// Handle Alt+Ctrl+Del Key combination
//
switch (Readed) {
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 && Readed == 0x53) {
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
}
}
// //
// Check if there are enough bytes of scancode representing a single key // Check if there are enough bytes of scancode representing a single key
// available in the buffer // available in the buffer
// //
while (TRUE) { while (TRUE) {
Status = GetScancodeBufHead (ConsoleIn, 1, ScancodeArr); Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 1, ScancodeArr);
ScancodeArrPos = 0; ScancodeArrPos = 0;
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_NOT_READY; return ;
} }
if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) { if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) {
Extended = TRUE; Extended = TRUE;
Status = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr); Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 2, ScancodeArr);
ScancodeArrPos = 1; ScancodeArrPos = 1;
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_NOT_READY; return ;
} }
} }
// //
@ -1322,29 +1196,29 @@ KeyGetchar (
// //
if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) { if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {
Status = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr); Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 2, ScancodeArr);
ScancodeArrPos = 1; ScancodeArrPos = 1;
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_NOT_READY; return ;
} }
Status = GetScancodeBufHead (ConsoleIn, 3, ScancodeArr); Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 3, ScancodeArr);
ScancodeArrPos = 2; ScancodeArrPos = 2;
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_NOT_READY; return ;
} }
PopScancodeBufHead (ConsoleIn, 3, ScancodeArr); PopScancodeBufHead (&ConsoleIn->ScancodeQueue, 3, ScancodeArr);
return EFI_NOT_READY; return ;
} }
// //
// if we reach this position, scancodes for a key is in buffer now,pop them // if we reach this position, scancodes for a key is in buffer now,pop them
// //
Status = PopScancodeBufHead (ConsoleIn, ScancodeArrPos + 1, ScancodeArr); Status = PopScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return EFI_NOT_READY; return ;
} }
// //
// store the last available byte, this byte of scancode will be checked // store the last available byte, this byte of scancode will be checked
@ -1446,55 +1320,56 @@ KeyGetchar (
break; break;
} }
} }
//
// Handle Ctrl+Alt+Del hotkey
//
if (ConsoleIn->Alt && ConsoleIn->Ctrl && ScanCode == SCANCODE_DELETE_MAKE) {
gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
}
KeyData.Key.ScanCode = SCAN_NULL;
KeyData.Key.UnicodeChar = CHAR_NULL;
KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
// //
// Treat Numeric Key Pad "/" specially // Treat Numeric Key Pad "/" specially
// //
if (Extended && ScanCode == 0x35) { if (Extended && ScanCode == 0x35) {
ConsoleIn->Key.ScanCode = SCAN_NULL; KeyData.Key.UnicodeChar = L'/';
ConsoleIn->Key.UnicodeChar = L'/'; KeyData.Key.ScanCode = SCAN_NULL;
return EFI_SUCCESS; } else {
} //
// // Convert Keyboard ScanCode into an EFI Key
// Convert Keyboard ScanCode into an EFI Key //
// for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {
for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) { if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {
if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) { KeyData.Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;
ConsoleIn->Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode; KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
if (ConsoleIn->Shift) {
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar; if (ConsoleIn->Shift &&
// (ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar)) {
// Need not return associated shift state if a class of printable characters that KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;
// are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F' //
// // Need not return associated shift state if a class of printable characters that
if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') { // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
//
ConsoleIn->LeftShift = FALSE; ConsoleIn->LeftShift = FALSE;
ConsoleIn->RightShift = FALSE; ConsoleIn->RightShift = FALSE;
} }
} else { //
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar; // alphabetic key is affected by CapsLock State
} //
// if (ConsoleIn->CapsLock) {
// alphabetic key is affected by CapsLock State if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
// KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + L'A');
if (ConsoleIn->CapsLock) { } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {
if (ConsoleIn->Key.UnicodeChar >= L'a' && ConsoleIn->Key.UnicodeChar <= L'z') { KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'A' + L'a');
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar; }
} else if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
} }
break;
} }
//
// Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
//
if (ConsoleIn->Ctrled) {
if (ConsoleIn->Key.UnicodeChar >= L'a' && ConsoleIn->Key.UnicodeChar <= L'z') {
ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - L'a' + 1);
} else if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {
ConsoleIn->Key.UnicodeChar = (UINT16) (ConsoleIn->Key.UnicodeChar - L'A' + 1);
}
}
break;
} }
} }
@ -1502,58 +1377,83 @@ KeyGetchar (
// distinguish numeric key pad keys' 'up symbol' and 'down symbol' // distinguish numeric key pad keys' 'up symbol' and 'down symbol'
// //
if (ScanCode >= 0x47 && ScanCode <= 0x53) { if (ScanCode >= 0x47 && ScanCode <= 0x53) {
if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) { if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) {
ConsoleIn->Key.ScanCode = SCAN_NULL; KeyData.Key.ScanCode = SCAN_NULL;
} else if (ScanCode != 0x4a && ScanCode != 0x4e) { } else if (ScanCode != 0x4a && ScanCode != 0x4e) {
ConsoleIn->Key.UnicodeChar = 0x0000; KeyData.Key.UnicodeChar = CHAR_NULL;
} }
} }
// //
// If the key can not be converted then just return. // If the key can not be converted then just return.
// //
if (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x0000) { if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
return EFI_NOT_READY; return ;
} }
// //
// Save the Shift/Toggle state // Save the Shift/Toggle state
// //
if (ConsoleIn->Ctrl) { if (ConsoleIn->Ctrl) {
ConsoleIn->KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_CONTROL_PRESSED : EFI_LEFT_CONTROL_PRESSED; KeyData.KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_CONTROL_PRESSED : EFI_LEFT_CONTROL_PRESSED;
} }
if (ConsoleIn->Alt) { if (ConsoleIn->Alt) {
ConsoleIn->KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_ALT_PRESSED : EFI_LEFT_ALT_PRESSED; KeyData.KeyState.KeyShiftState |= (Extended) ? EFI_RIGHT_ALT_PRESSED : EFI_LEFT_ALT_PRESSED;
} }
if (ConsoleIn->LeftShift) { if (ConsoleIn->LeftShift) {
ConsoleIn->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED; KeyData.KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
} }
if (ConsoleIn->RightShift) { if (ConsoleIn->RightShift) {
ConsoleIn->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED; KeyData.KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
} }
if (ConsoleIn->LeftLogo) { if (ConsoleIn->LeftLogo) {
ConsoleIn->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED; KeyData.KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
} }
if (ConsoleIn->RightLogo) { if (ConsoleIn->RightLogo) {
ConsoleIn->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED; KeyData.KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
} }
if (ConsoleIn->Menu) { if (ConsoleIn->Menu) {
ConsoleIn->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED; KeyData.KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
} }
if (ConsoleIn->SysReq) { if (ConsoleIn->SysReq) {
ConsoleIn->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED; KeyData.KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
} }
if (ConsoleIn->CapsLock) { if (ConsoleIn->CapsLock) {
ConsoleIn->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE; KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
} }
if (ConsoleIn->NumLock) { if (ConsoleIn->NumLock) {
ConsoleIn->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE; KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
} }
if (ConsoleIn->ScrollLock) { if (ConsoleIn->ScrollLock) {
ConsoleIn->KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE; KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
} }
return EFI_SUCCESS; //
// Invoke notification functions if exist
//
for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {
CurrentNotify = CR (
Link,
KEYBOARD_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
CurrentNotify->KeyNotificationFn (&KeyData);
}
}
//
// Translate the CTRL-Alpha characters to their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
//
if (ConsoleIn->Ctrl) {
if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + 1);
} else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {
KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'A' + 1);
}
}
PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, &KeyData);
} }
/** /**
@ -1737,11 +1637,10 @@ InitKeyboard (
// //
// Clear Memory Scancode Buffer // Clear Memory Scancode Buffer
// //
ConsoleIn->ScancodeBufStartPos = 0; ConsoleIn->ScancodeQueue.Head = 0;
ConsoleIn->ScancodeBufEndPos = KEYBOARD_BUFFER_MAX_COUNT - 1; ConsoleIn->ScancodeQueue.Tail = 0;
ConsoleIn->ScancodeBufCount = 0; ConsoleIn->EfiKeyQueue.Head = 0;
ConsoleIn->Ctrled = FALSE; ConsoleIn->EfiKeyQueue.Tail = 0;
ConsoleIn->Alted = FALSE;
// //
// Reset the status indicators // Reset the status indicators

View File

@ -2,7 +2,7 @@
Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces
provided by Ps2KbdCtrller.c. provided by Ps2KbdCtrller.c.
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -17,29 +17,66 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "Ps2Keyboard.h" #include "Ps2Keyboard.h"
/** /**
Check keyboard for given key value. Check whether the EFI key buffer is empty.
@param This Point to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL @param Queue Pointer to instance of EFI_KEY_QUEUE.
@retval EFI_SUCCESS success check keyboard value @retval TRUE The EFI key buffer is empty.
@retval !EFI_SUCCESS Fail to get char from keyboard @retval FALSE The EFI key buffer isn't empty.
**/ **/
EFI_STATUS BOOLEAN
KeyboardCheckForKey ( IsEfikeyBufEmpty (
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This IN EFI_KEY_QUEUE *Queue
) )
{ {
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn; return (BOOLEAN) (Queue->Head == Queue->Tail);
}
ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
//
// If ready to read next key, check it /**
// Push one key data to the EFI key buffer.
if (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x00) {
return KeyGetchar (ConsoleIn); @param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData The key data to push.
**/
VOID
PushEfikeyBufTail (
IN EFI_KEY_QUEUE *Queue,
IN EFI_KEY_DATA *KeyData
)
{
if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {
return;
} }
CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));
Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
}
/**
Read & remove one key data from the EFI key buffer.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData Receive the key data.
@retval EFI_SUCCESS The key data is popped successfully.
@retval EFI_NOT_READY There is no key data available.
**/
EFI_STATUS
PopEfikeyBufHead (
IN EFI_KEY_QUEUE *Queue,
OUT EFI_KEY_DATA *KeyData
)
{
if (IsEfikeyBufEmpty (Queue)) {
return EFI_NOT_READY;
}
//
// Retrieve and remove the values
//
CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));
Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
return EFI_SUCCESS; return EFI_SUCCESS;
} }
@ -110,9 +147,6 @@ KeyboardReadKeyStrokeWorker (
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_TPL OldTpl; EFI_TPL OldTpl;
LIST_ENTRY *Link;
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
EFI_KEY_DATA OriginalKeyData;
if (KeyData == NULL) { if (KeyData == NULL) {
return EFI_INVALID_PARAMETER; return EFI_INVALID_PARAMETER;
@ -123,58 +157,16 @@ KeyboardReadKeyStrokeWorker (
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
if (ConsoleInDev->KeyboardErr) { KeyboardTimerHandler (NULL, ConsoleInDev);
gBS->RestoreTPL (OldTpl);
return EFI_DEVICE_ERROR;
}
//
// If there's no key, just return
//
Status = KeyboardCheckForKey (&ConsoleInDev->ConIn);
if (EFI_ERROR (Status)) {
gBS->RestoreTPL (OldTpl);
return EFI_NOT_READY;
}
CopyMem (&KeyData->Key, &ConsoleInDev->Key, sizeof (EFI_INPUT_KEY)); if (ConsoleInDev->KeyboardErr) {
Status = EFI_DEVICE_ERROR;
} else {
Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);
}
ConsoleInDev->Key.ScanCode = SCAN_NULL;
ConsoleInDev->Key.UnicodeChar = 0x0000;
CopyMem (&KeyData->KeyState, &ConsoleInDev->KeyState, sizeof (EFI_KEY_STATE));
ConsoleInDev->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
ConsoleInDev->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL (OldTpl);
// return Status;
//Switch the control value to their original characters. In KeyGetchar() the CTRL-Alpha characters have been switched to
// their corresponding control value (ctrl-a = 0x0001 through ctrl-Z = 0x001A), here switch them back for notification function.
//
CopyMem (&OriginalKeyData, KeyData, sizeof (EFI_KEY_DATA));
if (ConsoleInDev->Ctrled) {
if (OriginalKeyData.Key.UnicodeChar >= 0x01 && OriginalKeyData.Key.UnicodeChar <= 0x1A) {
if (ConsoleInDev->CapsLock) {
OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + L'A' - 1);
} else {
OriginalKeyData.Key.UnicodeChar = (CHAR16)(OriginalKeyData.Key.UnicodeChar + L'a' - 1);
}
}
}
//
// Invoke notification functions if exist
//
for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
CurrentNotify = CR (
Link,
KEYBOARD_CONSOLE_IN_EX_NOTIFY,
NotifyEntry,
KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
);
if (IsKeyRegistered (&CurrentNotify->KeyData, &OriginalKeyData)) {
CurrentNotify->KeyNotificationFn (&OriginalKeyData);
}
}
return EFI_SUCCESS;
} }
/** /**
@ -224,11 +216,6 @@ KeyboardEfiReset (
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL (OldTpl);
return EFI_DEVICE_ERROR; return EFI_DEVICE_ERROR;
} }
//
// Clear the status of ConsoleIn.Key
//
ConsoleIn->Key.ScanCode = SCAN_NULL;
ConsoleIn->Key.UnicodeChar = 0x0000;
// //
// Leave critical section and return // Leave critical section and return
@ -304,36 +291,31 @@ KeyboardWaitForKey (
IN VOID *Context IN VOID *Context
) )
{ {
EFI_TPL OldTpl; EFI_TPL OldTpl;
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn; KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (Context); ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
// //
// Enter critical section // Enter critical section
// //
OldTpl = gBS->RaiseTPL (TPL_NOTIFY); OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
KeyboardTimerHandler (NULL, ConsoleIn);
if (ConsoleIn->KeyboardErr) { if (!ConsoleIn->KeyboardErr) {
// //
// Leave critical section and return // Someone is waiting on the keyboard event, if there's
// a key pending, signal the event
// //
gBS->RestoreTPL (OldTpl); if (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
return ; gBS->SignalEvent (Event);
} }
//
// Someone is waiting on the keyboard event, if there's
// a key pending, signal the event
//
if (!EFI_ERROR (KeyboardCheckForKey (Context))) {
gBS->SignalEvent (Event);
} }
// //
// Leave critical section and return // Leave critical section and return
// //
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL (OldTpl);
return ;
} }
/** /**
@ -352,11 +334,7 @@ KeyboardWaitForKeyEx (
) )
{ {
KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev; KeyboardWaitForKey (Event, Context);
ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (Context);
KeyboardWaitForKey (Event, &ConsoleInDev->ConIn);
} }
/** /**
@ -378,31 +356,14 @@ KeyboardEfiResetEx (
) )
{ {
EFI_STATUS Status;
KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev; KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
EFI_TPL OldTpl;
ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
if (ConsoleInDev->KeyboardErr) {
return EFI_DEVICE_ERROR;
}
Status = ConsoleInDev->ConIn.Reset ( return ConsoleInDev->ConIn.Reset (
&ConsoleInDev->ConIn, &ConsoleInDev->ConIn,
ExtendedVerification ExtendedVerification
); );
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
ConsoleInDev->KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
ConsoleInDev->KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
gBS->RestoreTPL (OldTpl);
return EFI_SUCCESS;
} }
/** /**
@ -482,8 +443,7 @@ KeyboardSetState (
goto Exit; goto Exit;
} }
if (((ConsoleInDev->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) || if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
Status = EFI_UNSUPPORTED; Status = EFI_UNSUPPORTED;
goto Exit; goto Exit;
} }
@ -510,8 +470,6 @@ KeyboardSetState (
Status = EFI_DEVICE_ERROR; Status = EFI_DEVICE_ERROR;
} }
ConsoleInDev->KeyState.KeyToggleState = *KeyToggleState;
Exit: Exit:
// //
// Leave critical section and return // Leave critical section and return

View File

@ -3,7 +3,7 @@
PS/2 Keyboard driver. Routines that interacts with callers, PS/2 Keyboard driver. Routines that interacts with callers,
conforming to EFI driver model conforming to EFI driver model
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -243,11 +243,6 @@ KbdControllerDriverStart (
ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER; ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;
ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER; ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
ConsoleIn->IsaIo = IsaIo; ConsoleIn->IsaIo = IsaIo;
ConsoleIn->ScancodeBufStartPos = 0;
ConsoleIn->ScancodeBufEndPos = KEYBOARD_BUFFER_MAX_COUNT - 1;
ConsoleIn->ScancodeBufCount = 0;
ConsoleIn->Ctrled = FALSE;
ConsoleIn->Alted = FALSE;
ConsoleIn->DevicePath = ParentDevicePath; ConsoleIn->DevicePath = ParentDevicePath;
ConsoleIn->ConInEx.Reset = KeyboardEfiResetEx; ConsoleIn->ConInEx.Reset = KeyboardEfiResetEx;
@ -279,7 +274,7 @@ KbdControllerDriverStart (
EVT_NOTIFY_WAIT, EVT_NOTIFY_WAIT,
TPL_NOTIFY, TPL_NOTIFY,
KeyboardWaitForKey, KeyboardWaitForKey,
&(ConsoleIn->ConIn), ConsoleIn,
&((ConsoleIn->ConIn).WaitForKey) &((ConsoleIn->ConIn).WaitForKey)
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
@ -294,7 +289,7 @@ KbdControllerDriverStart (
EVT_NOTIFY_WAIT, EVT_NOTIFY_WAIT,
TPL_NOTIFY, TPL_NOTIFY,
KeyboardWaitForKeyEx, KeyboardWaitForKeyEx,
&(ConsoleIn->ConInEx), ConsoleIn,
&(ConsoleIn->ConInEx.WaitForKeyEx) &(ConsoleIn->ConInEx.WaitForKeyEx)
); );
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {

View File

@ -1,7 +1,7 @@
/** @file /** @file
PS/2 keyboard driver header file PS/2 keyboard driver header file
Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR> Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at which accompanies this distribution. The full text of the license may be found at
@ -44,18 +44,30 @@ extern EFI_COMPONENT_NAME2_PROTOCOL gPs2KeyboardComponentName2;
// //
// Driver Private Data // Driver Private Data
// //
#define KEYBOARD_BUFFER_MAX_COUNT 32 #define KEYBOARD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32 ('k', 'k', 'e', 'y')
#define KEYBOARD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32 ('k', 'k', 'e', 'y')
#define KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n') #define KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n')
typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY { typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY {
UINTN Signature; UINTN Signature;
EFI_HANDLE NotifyHandle; EFI_HANDLE NotifyHandle;
EFI_KEY_DATA KeyData; EFI_KEY_DATA KeyData;
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn; EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
LIST_ENTRY NotifyEntry; LIST_ENTRY NotifyEntry;
} KEYBOARD_CONSOLE_IN_EX_NOTIFY; } KEYBOARD_CONSOLE_IN_EX_NOTIFY;
#define KEYBOARD_SCAN_CODE_MAX_COUNT 32
typedef struct {
UINT8 Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];
UINTN Head;
UINTN Tail;
} SCAN_CODE_QUEUE;
#define KEYBOARD_EFI_KEY_MAX_COUNT 256
typedef struct {
EFI_KEY_DATA Buffer[KEYBOARD_EFI_KEY_MAX_COUNT];
UINTN Head;
UINTN Tail;
} EFI_KEY_QUEUE;
typedef struct { typedef struct {
UINTN Signature; UINTN Signature;
@ -71,9 +83,6 @@ typedef struct {
UINT32 StatusRegisterAddress; UINT32 StatusRegisterAddress;
UINT32 CommandRegisterAddress; UINT32 CommandRegisterAddress;
EFI_INPUT_KEY Key;
EFI_KEY_STATE KeyState;
BOOLEAN LeftShift; BOOLEAN LeftShift;
BOOLEAN RightShift; BOOLEAN RightShift;
BOOLEAN LeftLogo; BOOLEAN LeftLogo;
@ -89,18 +98,10 @@ typedef struct {
BOOLEAN ScrollLock; BOOLEAN ScrollLock;
// //
// Buffer storing key scancodes // Queue storing key scancodes
// //
UINT8 ScancodeBuf[KEYBOARD_BUFFER_MAX_COUNT]; SCAN_CODE_QUEUE ScancodeQueue;
UINT32 ScancodeBufStartPos; EFI_KEY_QUEUE EfiKeyQueue;
UINT32 ScancodeBufEndPos;
UINT32 ScancodeBufCount;
//
// Indicators of the key pressing state, used in detecting Alt+Ctrl+Del
//
BOOLEAN Ctrled;
BOOLEAN Alted;
// //
// Error state // Error state
@ -171,6 +172,7 @@ InstallPs2KeyboardDriver (
#define SCANCODE_CAPS_LOCK_MAKE 0x3A #define SCANCODE_CAPS_LOCK_MAKE 0x3A
#define SCANCODE_NUM_LOCK_MAKE 0x45 #define SCANCODE_NUM_LOCK_MAKE 0x45
#define SCANCODE_SCROLL_LOCK_MAKE 0x46 #define SCANCODE_SCROLL_LOCK_MAKE 0x46
#define SCANCODE_DELETE_MAKE 0x53
#define SCANCODE_LEFT_LOGO_MAKE 0x5B //GUI key defined in Keyboard scan code #define SCANCODE_LEFT_LOGO_MAKE 0x5B //GUI key defined in Keyboard scan code
#define SCANCODE_LEFT_LOGO_BREAK 0xDB #define SCANCODE_LEFT_LOGO_BREAK 0xDB
#define SCANCODE_RIGHT_LOGO_MAKE 0x5C #define SCANCODE_RIGHT_LOGO_MAKE 0x5C
@ -246,17 +248,14 @@ KeyboardRead (
); );
/** /**
Get scancode from scancode buffer Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
and translate into EFI-scancode and unicode defined by EFI spec
The function is always called in TPL_NOTIFY The function is always called in TPL_NOTIFY.
@param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer
@retval EFI_NOT_READY - Input from console not ready yet.
@retval EFI_SUCCESS - Function executed successfully.
**/ **/
EFI_STATUS VOID
KeyGetchar ( KeyGetchar (
IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
); );
@ -511,4 +510,33 @@ KeyboardUnregisterKeyNotify (
IN EFI_HANDLE NotificationHandle IN EFI_HANDLE NotificationHandle
); );
/**
Push one key data to the EFI key buffer.
@param Queue Pointer to instance of EFI_KEY_QUEUE.
@param KeyData The key data to push.
**/
VOID
PushEfikeyBufTail (
IN EFI_KEY_QUEUE *Queue,
IN EFI_KEY_DATA *KeyData
);
/**
Judge whether is a registed key
@param RegsiteredData A pointer to a buffer that is filled in with the keystroke
state data for the key that was registered.
@param InputData A pointer to a buffer that is filled in with the keystroke
state data for the key that was pressed.
@retval TRUE Key be pressed matches a registered key.
@retval FLASE Match failed.
**/
BOOLEAN
IsKeyRegistered (
IN EFI_KEY_DATA *RegsiteredData,
IN EFI_KEY_DATA *InputData
);
#endif #endif