mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
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:
parent
c1fd2767c1
commit
c220787b13
@ -1,7 +1,7 @@
|
||||
/** @file
|
||||
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
|
||||
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
|
||||
@ -558,7 +558,6 @@ ConvertKeyboardScanCodeToEfiKey[] = {
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// The WaitForValue time out
|
||||
//
|
||||
@ -566,6 +565,122 @@ UINTN mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
|
||||
|
||||
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 .
|
||||
|
||||
@ -611,23 +726,14 @@ KeyWriteDataRegister (
|
||||
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
|
||||
IN UINT8 Data
|
||||
)
|
||||
|
||||
{
|
||||
EFI_ISA_IO_PROTOCOL *IsaIo;
|
||||
|
||||
//
|
||||
// Use IsaIo protocol to perform IO operations
|
||||
//
|
||||
IsaIo = ConsoleIn->IsaIo;
|
||||
|
||||
IsaIo->Io.Write (
|
||||
IsaIo,
|
||||
EfiIsaIoWidthUint8,
|
||||
ConsoleIn->DataRegisterAddress,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
|
||||
ConsoleIn->IsaIo->Io.Write (
|
||||
ConsoleIn->IsaIo,
|
||||
EfiIsaIoWidthUint8,
|
||||
ConsoleIn->DataRegisterAddress,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -643,24 +749,15 @@ KeyReadStatusRegister (
|
||||
IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
|
||||
)
|
||||
{
|
||||
EFI_ISA_IO_PROTOCOL *IsaIo;
|
||||
UINT8 Data;
|
||||
|
||||
//
|
||||
// Use IsaIo protocol to perform IO operations
|
||||
//
|
||||
IsaIo = ConsoleIn->IsaIo;
|
||||
|
||||
IsaIo->Io.Read (
|
||||
IsaIo,
|
||||
EfiIsaIoWidthUint8,
|
||||
ConsoleIn->StatusRegisterAddress,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
|
||||
ConsoleIn->IsaIo->Io.Read (
|
||||
ConsoleIn->IsaIo,
|
||||
EfiIsaIoWidthUint8,
|
||||
ConsoleIn->StatusRegisterAddress,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
return Data;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -676,21 +773,13 @@ KeyWriteCommandRegister (
|
||||
IN UINT8 Data
|
||||
)
|
||||
{
|
||||
EFI_ISA_IO_PROTOCOL *IsaIo;
|
||||
|
||||
//
|
||||
// Use IsaIo protocol to perform IO operations
|
||||
//
|
||||
IsaIo = ConsoleIn->IsaIo;
|
||||
|
||||
IsaIo->Io.Write (
|
||||
IsaIo,
|
||||
EfiIsaIoWidthUint8,
|
||||
ConsoleIn->CommandRegisterAddress,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
|
||||
ConsoleIn->IsaIo->Io.Write (
|
||||
ConsoleIn->IsaIo,
|
||||
EfiIsaIoWidthUint8,
|
||||
ConsoleIn->CommandRegisterAddress,
|
||||
1,
|
||||
&Data
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -732,7 +821,7 @@ KeyboardTimerHandler (
|
||||
EFI_TPL OldTpl;
|
||||
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
|
||||
|
||||
ConsoleIn = Context;
|
||||
ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
|
||||
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
|
||||
Data = 0;
|
||||
|
||||
//
|
||||
// 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) {
|
||||
while ((KeyReadStatusRegister (ConsoleIn) & (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);
|
||||
|
||||
return ;
|
||||
Data = KeyReadDataRegister (ConsoleIn);
|
||||
PushScancodeBufTail (&ConsoleIn->ScancodeQueue, Data);
|
||||
}
|
||||
//
|
||||
// Read one byte of the scan code and store it into the memory buffer
|
||||
//
|
||||
if (ConsoleIn->ScancodeBufCount < KEYBOARD_BUFFER_MAX_COUNT) {
|
||||
KeyGetchar (ConsoleIn);
|
||||
|
||||
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 ;
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
and translate into EFI-scancode and unicode defined by EFI spec
|
||||
The function is always called in TPL_NOTIFY
|
||||
Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
|
||||
|
||||
The function is always called in TPL_NOTIFY.
|
||||
|
||||
@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 (
|
||||
IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT8 ScanCode;
|
||||
UINT8 Readed;
|
||||
BOOLEAN Extended;
|
||||
UINT8 ScancodeArr[4];
|
||||
UINTN Index;
|
||||
EFI_STATUS Status;
|
||||
UINT8 ScanCode;
|
||||
BOOLEAN Extended;
|
||||
UINTN Index;
|
||||
EFI_KEY_DATA KeyData;
|
||||
LIST_ENTRY *Link;
|
||||
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
|
||||
//
|
||||
// 4 bytes most
|
||||
//
|
||||
UINT32 ScancodeArrPos;
|
||||
UINT8 ScancodeArr[4];
|
||||
UINT32 ScancodeArrPos;
|
||||
//
|
||||
// point to the current position in ScancodeArr
|
||||
//
|
||||
|
||||
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
|
||||
//
|
||||
//
|
||||
// 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
|
||||
// available in the buffer
|
||||
//
|
||||
while (TRUE) {
|
||||
|
||||
Status = GetScancodeBufHead (ConsoleIn, 1, ScancodeArr);
|
||||
ScancodeArrPos = 0;
|
||||
Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 1, ScancodeArr);
|
||||
ScancodeArrPos = 0;
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_READY;
|
||||
return ;
|
||||
}
|
||||
|
||||
if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED) {
|
||||
Extended = TRUE;
|
||||
Status = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);
|
||||
Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 2, ScancodeArr);
|
||||
ScancodeArrPos = 1;
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_READY;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
//
|
||||
@ -1322,29 +1196,29 @@ KeyGetchar (
|
||||
//
|
||||
if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {
|
||||
|
||||
Status = GetScancodeBufHead (ConsoleIn, 2, ScancodeArr);
|
||||
Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 2, ScancodeArr);
|
||||
ScancodeArrPos = 1;
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_READY;
|
||||
return ;
|
||||
}
|
||||
|
||||
Status = GetScancodeBufHead (ConsoleIn, 3, ScancodeArr);
|
||||
Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, 3, ScancodeArr);
|
||||
ScancodeArrPos = 2;
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_READY;
|
||||
return ;
|
||||
}
|
||||
|
||||
PopScancodeBufHead (ConsoleIn, 3, ScancodeArr);
|
||||
return EFI_NOT_READY;
|
||||
PopScancodeBufHead (&ConsoleIn->ScancodeQueue, 3, ScancodeArr);
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// 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)) {
|
||||
return EFI_NOT_READY;
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// store the last available byte, this byte of scancode will be checked
|
||||
@ -1446,55 +1320,56 @@ KeyGetchar (
|
||||
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
|
||||
//
|
||||
if (Extended && ScanCode == 0x35) {
|
||||
ConsoleIn->Key.ScanCode = SCAN_NULL;
|
||||
ConsoleIn->Key.UnicodeChar = L'/';
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// Convert Keyboard ScanCode into an EFI Key
|
||||
//
|
||||
for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {
|
||||
if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {
|
||||
ConsoleIn->Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;
|
||||
if (ConsoleIn->Shift) {
|
||||
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;
|
||||
//
|
||||
// Need not return associated shift state if a class of printable characters that
|
||||
// are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
|
||||
//
|
||||
if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {
|
||||
KeyData.Key.UnicodeChar = L'/';
|
||||
KeyData.Key.ScanCode = SCAN_NULL;
|
||||
} else {
|
||||
//
|
||||
// Convert Keyboard ScanCode into an EFI Key
|
||||
//
|
||||
for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index += 1) {
|
||||
if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {
|
||||
KeyData.Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;
|
||||
KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
|
||||
|
||||
if (ConsoleIn->Shift &&
|
||||
(ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar)) {
|
||||
KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;
|
||||
//
|
||||
// Need not return associated shift state if a class of printable characters that
|
||||
// are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
|
||||
//
|
||||
ConsoleIn->LeftShift = FALSE;
|
||||
ConsoleIn->RightShift = FALSE;
|
||||
}
|
||||
} else {
|
||||
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
|
||||
}
|
||||
//
|
||||
// alphabetic key is affected by CapsLock State
|
||||
//
|
||||
if (ConsoleIn->CapsLock) {
|
||||
if (ConsoleIn->Key.UnicodeChar >= L'a' && ConsoleIn->Key.UnicodeChar <= L'z') {
|
||||
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;
|
||||
} else if (ConsoleIn->Key.UnicodeChar >= L'A' && ConsoleIn->Key.UnicodeChar <= L'Z') {
|
||||
ConsoleIn->Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
|
||||
//
|
||||
// alphabetic key is affected by CapsLock State
|
||||
//
|
||||
if (ConsoleIn->CapsLock) {
|
||||
if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
|
||||
KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + L'A');
|
||||
} else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {
|
||||
KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'A' + L'a');
|
||||
}
|
||||
}
|
||||
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'
|
||||
//
|
||||
if (ScanCode >= 0x47 && ScanCode <= 0x53) {
|
||||
|
||||
if (ConsoleIn->NumLock && !ConsoleIn->Shift && !Extended) {
|
||||
ConsoleIn->Key.ScanCode = SCAN_NULL;
|
||||
KeyData.Key.ScanCode = SCAN_NULL;
|
||||
} 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 (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x0000) {
|
||||
return EFI_NOT_READY;
|
||||
if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {
|
||||
return ;
|
||||
}
|
||||
|
||||
//
|
||||
// Save the Shift/Toggle state
|
||||
//
|
||||
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) {
|
||||
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) {
|
||||
ConsoleIn->KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
|
||||
KeyData.KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
|
||||
}
|
||||
if (ConsoleIn->RightShift) {
|
||||
ConsoleIn->KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
|
||||
KeyData.KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
|
||||
}
|
||||
if (ConsoleIn->LeftLogo) {
|
||||
ConsoleIn->KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
|
||||
KeyData.KeyState.KeyShiftState |= EFI_LEFT_LOGO_PRESSED;
|
||||
}
|
||||
if (ConsoleIn->RightLogo) {
|
||||
ConsoleIn->KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
|
||||
KeyData.KeyState.KeyShiftState |= EFI_RIGHT_LOGO_PRESSED;
|
||||
}
|
||||
if (ConsoleIn->Menu) {
|
||||
ConsoleIn->KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
|
||||
KeyData.KeyState.KeyShiftState |= EFI_MENU_KEY_PRESSED;
|
||||
}
|
||||
if (ConsoleIn->SysReq) {
|
||||
ConsoleIn->KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
|
||||
KeyData.KeyState.KeyShiftState |= EFI_SYS_REQ_PRESSED;
|
||||
}
|
||||
if (ConsoleIn->CapsLock) {
|
||||
ConsoleIn->KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
|
||||
KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
|
||||
}
|
||||
if (ConsoleIn->NumLock) {
|
||||
ConsoleIn->KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
|
||||
KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
|
||||
}
|
||||
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
|
||||
//
|
||||
ConsoleIn->ScancodeBufStartPos = 0;
|
||||
ConsoleIn->ScancodeBufEndPos = KEYBOARD_BUFFER_MAX_COUNT - 1;
|
||||
ConsoleIn->ScancodeBufCount = 0;
|
||||
ConsoleIn->Ctrled = FALSE;
|
||||
ConsoleIn->Alted = FALSE;
|
||||
ConsoleIn->ScancodeQueue.Head = 0;
|
||||
ConsoleIn->ScancodeQueue.Tail = 0;
|
||||
ConsoleIn->EfiKeyQueue.Head = 0;
|
||||
ConsoleIn->EfiKeyQueue.Tail = 0;
|
||||
|
||||
//
|
||||
// Reset the status indicators
|
||||
|
@ -2,7 +2,7 @@
|
||||
Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces
|
||||
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
|
||||
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
|
||||
@ -17,29 +17,66 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
#include "Ps2Keyboard.h"
|
||||
|
||||
/**
|
||||
Check keyboard for given key value.
|
||||
|
||||
@param This Point to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
|
||||
|
||||
@retval EFI_SUCCESS success check keyboard value
|
||||
@retval !EFI_SUCCESS Fail to get char from keyboard
|
||||
Check whether the EFI key buffer is empty.
|
||||
|
||||
@param Queue Pointer to instance of EFI_KEY_QUEUE.
|
||||
|
||||
@retval TRUE The EFI key buffer is empty.
|
||||
@retval FALSE The EFI key buffer isn't empty.
|
||||
**/
|
||||
EFI_STATUS
|
||||
KeyboardCheckForKey (
|
||||
IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
|
||||
BOOLEAN
|
||||
IsEfikeyBufEmpty (
|
||||
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
|
||||
//
|
||||
if (ConsoleIn->Key.ScanCode == SCAN_NULL && ConsoleIn->Key.UnicodeChar == 0x00) {
|
||||
return KeyGetchar (ConsoleIn);
|
||||
|
||||
/**
|
||||
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
|
||||
)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -110,9 +147,6 @@ KeyboardReadKeyStrokeWorker (
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_TPL OldTpl;
|
||||
LIST_ENTRY *Link;
|
||||
KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
|
||||
EFI_KEY_DATA OriginalKeyData;
|
||||
|
||||
if (KeyData == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
@ -123,58 +157,16 @@ KeyboardReadKeyStrokeWorker (
|
||||
//
|
||||
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
if (ConsoleInDev->KeyboardErr) {
|
||||
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;
|
||||
}
|
||||
KeyboardTimerHandler (NULL, ConsoleInDev);
|
||||
|
||||
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);
|
||||
//
|
||||
//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;
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,11 +216,6 @@ KeyboardEfiReset (
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
//
|
||||
// Clear the status of ConsoleIn.Key
|
||||
//
|
||||
ConsoleIn->Key.ScanCode = SCAN_NULL;
|
||||
ConsoleIn->Key.UnicodeChar = 0x0000;
|
||||
|
||||
//
|
||||
// Leave critical section and return
|
||||
@ -304,36 +291,31 @@ KeyboardWaitForKey (
|
||||
IN VOID *Context
|
||||
)
|
||||
{
|
||||
EFI_TPL OldTpl;
|
||||
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
|
||||
EFI_TPL OldTpl;
|
||||
KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
|
||||
|
||||
ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (Context);
|
||||
ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;
|
||||
|
||||
//
|
||||
// Enter critical section
|
||||
//
|
||||
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);
|
||||
return ;
|
||||
}
|
||||
//
|
||||
// Someone is waiting on the keyboard event, if there's
|
||||
// a key pending, signal the event
|
||||
//
|
||||
if (!EFI_ERROR (KeyboardCheckForKey (Context))) {
|
||||
gBS->SignalEvent (Event);
|
||||
if (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
|
||||
gBS->SignalEvent (Event);
|
||||
}
|
||||
}
|
||||
//
|
||||
// Leave critical section and return
|
||||
//
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,11 +334,7 @@ KeyboardWaitForKeyEx (
|
||||
)
|
||||
|
||||
{
|
||||
KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
|
||||
|
||||
ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (Context);
|
||||
KeyboardWaitForKey (Event, &ConsoleInDev->ConIn);
|
||||
|
||||
KeyboardWaitForKey (Event, Context);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -378,31 +356,14 @@ KeyboardEfiResetEx (
|
||||
)
|
||||
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
|
||||
if (ConsoleInDev->KeyboardErr) {
|
||||
return EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
Status = ConsoleInDev->ConIn.Reset (
|
||||
&ConsoleInDev->ConIn,
|
||||
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;
|
||||
return ConsoleInDev->ConIn.Reset (
|
||||
&ConsoleInDev->ConIn,
|
||||
ExtendedVerification
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -482,8 +443,7 @@ KeyboardSetState (
|
||||
goto Exit;
|
||||
}
|
||||
|
||||
if (((ConsoleInDev->KeyState.KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) ||
|
||||
((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID)) {
|
||||
if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
|
||||
Status = EFI_UNSUPPORTED;
|
||||
goto Exit;
|
||||
}
|
||||
@ -510,8 +470,6 @@ KeyboardSetState (
|
||||
Status = EFI_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
ConsoleInDev->KeyState.KeyToggleState = *KeyToggleState;
|
||||
|
||||
Exit:
|
||||
//
|
||||
// Leave critical section and return
|
||||
|
@ -3,7 +3,7 @@
|
||||
PS/2 Keyboard driver. Routines that interacts with callers,
|
||||
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
|
||||
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
|
||||
@ -243,11 +243,6 @@ KbdControllerDriverStart (
|
||||
ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;
|
||||
ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
|
||||
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->ConInEx.Reset = KeyboardEfiResetEx;
|
||||
@ -279,7 +274,7 @@ KbdControllerDriverStart (
|
||||
EVT_NOTIFY_WAIT,
|
||||
TPL_NOTIFY,
|
||||
KeyboardWaitForKey,
|
||||
&(ConsoleIn->ConIn),
|
||||
ConsoleIn,
|
||||
&((ConsoleIn->ConIn).WaitForKey)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
@ -294,7 +289,7 @@ KbdControllerDriverStart (
|
||||
EVT_NOTIFY_WAIT,
|
||||
TPL_NOTIFY,
|
||||
KeyboardWaitForKeyEx,
|
||||
&(ConsoleIn->ConInEx),
|
||||
ConsoleIn,
|
||||
&(ConsoleIn->ConInEx.WaitForKeyEx)
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
/** @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
|
||||
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
|
||||
@ -44,18 +44,30 @@ extern EFI_COMPONENT_NAME2_PROTOCOL gPs2KeyboardComponentName2;
|
||||
//
|
||||
// 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')
|
||||
|
||||
typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY {
|
||||
UINTN Signature;
|
||||
EFI_HANDLE NotifyHandle;
|
||||
EFI_KEY_DATA KeyData;
|
||||
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
|
||||
LIST_ENTRY NotifyEntry;
|
||||
UINTN Signature;
|
||||
EFI_HANDLE NotifyHandle;
|
||||
EFI_KEY_DATA KeyData;
|
||||
EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
|
||||
LIST_ENTRY NotifyEntry;
|
||||
} 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 {
|
||||
UINTN Signature;
|
||||
@ -71,9 +83,6 @@ typedef struct {
|
||||
UINT32 StatusRegisterAddress;
|
||||
UINT32 CommandRegisterAddress;
|
||||
|
||||
EFI_INPUT_KEY Key;
|
||||
EFI_KEY_STATE KeyState;
|
||||
|
||||
BOOLEAN LeftShift;
|
||||
BOOLEAN RightShift;
|
||||
BOOLEAN LeftLogo;
|
||||
@ -89,18 +98,10 @@ typedef struct {
|
||||
BOOLEAN ScrollLock;
|
||||
|
||||
//
|
||||
// Buffer storing key scancodes
|
||||
// Queue storing key scancodes
|
||||
//
|
||||
UINT8 ScancodeBuf[KEYBOARD_BUFFER_MAX_COUNT];
|
||||
UINT32 ScancodeBufStartPos;
|
||||
UINT32 ScancodeBufEndPos;
|
||||
UINT32 ScancodeBufCount;
|
||||
|
||||
//
|
||||
// Indicators of the key pressing state, used in detecting Alt+Ctrl+Del
|
||||
//
|
||||
BOOLEAN Ctrled;
|
||||
BOOLEAN Alted;
|
||||
SCAN_CODE_QUEUE ScancodeQueue;
|
||||
EFI_KEY_QUEUE EfiKeyQueue;
|
||||
|
||||
//
|
||||
// Error state
|
||||
@ -171,6 +172,7 @@ InstallPs2KeyboardDriver (
|
||||
#define SCANCODE_CAPS_LOCK_MAKE 0x3A
|
||||
#define SCANCODE_NUM_LOCK_MAKE 0x45
|
||||
#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_BREAK 0xDB
|
||||
#define SCANCODE_RIGHT_LOGO_MAKE 0x5C
|
||||
@ -246,17 +248,14 @@ KeyboardRead (
|
||||
);
|
||||
|
||||
/**
|
||||
Get scancode from scancode buffer
|
||||
and translate into EFI-scancode and unicode defined by EFI spec
|
||||
The function is always called in TPL_NOTIFY
|
||||
Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
|
||||
|
||||
The function is always called in TPL_NOTIFY.
|
||||
|
||||
@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 (
|
||||
IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
|
||||
);
|
||||
@ -511,4 +510,33 @@ KeyboardUnregisterKeyNotify (
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user