diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c index 2c288d0a7e..e8f474a326 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c @@ -537,13 +537,13 @@ ConvertKeyboardScanCodeToEfiKey[] = { SCAN_NULL, 0x0000, 0x0000 - }, + }, { 0x5C, //Right LOGO SCAN_NULL, 0x0000, 0x0000 - }, + }, { 0x5D, //Menu key SCAN_NULL, @@ -569,7 +569,7 @@ BOOLEAN mEnableMouseInterface; /** Return the count of scancode in the queue. - + @param Queue Pointer to instance of SCAN_CODE_QUEUE. @return Count of the scancode. @@ -590,7 +590,7 @@ GetScancodeBufCount ( 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 @@ -624,31 +624,11 @@ GetScancodeBufHead ( 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 @@ -660,7 +640,7 @@ EFI_STATUS PopScancodeBufHead ( IN SCAN_CODE_QUEUE *Queue, IN UINTN Count, - OUT UINT8 *Buf + OUT UINT8 *Buf OPTIONAL ) { UINTN Index; @@ -675,18 +655,40 @@ PopScancodeBufHead ( // 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]; + if (Buf != NULL) { + Buf[Index] = Queue->Buffer[Queue->Head]; + } } 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) { + PopScancodeBufHead (Queue, 1, NULL); + } + + Queue->Buffer[Queue->Tail] = Scancode; + Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT; +} + /** Read data register . @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV - @return return the value + @return return the value **/ UINT8 @@ -787,7 +789,7 @@ KeyWriteCommandRegister ( @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV @param ErrMsg Unicode string of error message - + **/ VOID KeyboardError ( @@ -953,9 +955,9 @@ KeyboardWrite ( Issue keyboard command. @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV - @param Data The buff holding the command + @param Data The buff holding the command - @retval EFI_TIMEOUT Keyboard is not ready to issuing + @retval EFI_TIMEOUT Keyboard is not ready to issuing @retval EFI_SUCCESS Success to issue keyboard command **/ @@ -1021,7 +1023,7 @@ KeyboardCommand ( @retval EFI_TIMEOUT Fail to get specific value in given time @retval EFI_SUCCESS Success to get specific value in given time. - + **/ EFI_STATUS KeyboardWaitForValue ( @@ -1090,7 +1092,7 @@ KeyboardWaitForValue ( indicators in ConsoleIn. @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV - + @return status of updating keyboard register **/ @@ -1164,7 +1166,7 @@ KeyGetchar ( // UINT8 ScancodeArr[3]; UINT32 ScancodeArrPos; - + // // Check if there are enough bytes of scancode representing a single key // available in the buffer @@ -1215,14 +1217,14 @@ KeyGetchar ( // Check for special keys and update the driver state. // switch (ScanCode) { - + case SCANCODE_CTRL_MAKE: if (Extend0) { ConsoleIn->RightCtrl = TRUE; } else { ConsoleIn->LeftCtrl = TRUE; } - break; + break; case SCANCODE_CTRL_BREAK: if (Extend0) { ConsoleIn->RightCtrl = FALSE; @@ -1237,7 +1239,7 @@ KeyGetchar ( } else { ConsoleIn->LeftAlt = TRUE; } - break; + break; case SCANCODE_ALT_BREAK: if (Extend0) { ConsoleIn->RightAlt = FALSE; @@ -1249,12 +1251,15 @@ KeyGetchar ( case SCANCODE_LEFT_SHIFT_MAKE: // // To avoid recognize PRNT_SCRN key as a L_SHIFT key - // because PRNT_SCRN key generates E0 followed by L_SHIFT scan code + // because PRNT_SCRN key generates E0 followed by L_SHIFT scan code. + // If it the second byte of the PRNT_ScRN skip it. // if (!Extend0) { ConsoleIn->LeftShift = TRUE; + break; } - break; + continue; + case SCANCODE_LEFT_SHIFT_BREAK: if (!Extend0) { ConsoleIn->LeftShift = FALSE; @@ -1267,7 +1272,7 @@ KeyGetchar ( case SCANCODE_RIGHT_SHIFT_BREAK: ConsoleIn->RightShift = FALSE; break; - + case SCANCODE_LEFT_LOGO_MAKE: ConsoleIn->LeftLogo = TRUE; break; @@ -1323,7 +1328,7 @@ KeyGetchar ( break; } } - + // // If this is above the valid range, ignore it // @@ -1358,14 +1363,14 @@ KeyGetchar ( | (ConsoleIn->RightLogo ? EFI_RIGHT_LOGO_PRESSED : 0) | (ConsoleIn->Menu ? EFI_MENU_KEY_PRESSED : 0) | (ConsoleIn->SysReq ? EFI_SYS_REQ_PRESSED : 0) - ) - ; + ); KeyData.KeyState.KeyToggleState = (EFI_KEY_TOGGLE_STATE) (EFI_TOGGLE_STATE_VALID | (ConsoleIn->CapsLock ? EFI_CAPS_LOCK_ACTIVE : 0) | (ConsoleIn->NumLock ? EFI_NUM_LOCK_ACTIVE : 0) | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0) - ) - ; + | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0) + ); + KeyData.Key.ScanCode = SCAN_NULL; KeyData.Key.UnicodeChar = CHAR_NULL; @@ -1406,7 +1411,7 @@ KeyGetchar ( KeyData.Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode; KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar; - if ((ConsoleIn->LeftShift || ConsoleIn->RightShift) && + if ((ConsoleIn->LeftShift || ConsoleIn->RightShift) && (ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar)) { KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar; // @@ -1440,11 +1445,14 @@ KeyGetchar ( KeyData.Key.UnicodeChar = CHAR_NULL; } } + // // If the key can not be converted then just return. // if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) { - return ; + if (!ConsoleIn->IsSupportPartialKey) { + return ; + } } // @@ -1452,16 +1460,16 @@ KeyGetchar ( // for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) { CurrentNotify = CR ( - Link, - KEYBOARD_CONSOLE_IN_EX_NOTIFY, - NotifyEntry, + Link, + KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE ); - if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) { + 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) // @@ -1477,7 +1485,7 @@ KeyGetchar ( } /** - Perform 8042 controller and keyboard Initialization. + Perform 8042 controller and keyboard Initialization. If ExtendedVerification is TRUE, do additional test for the keyboard interface @@ -1671,14 +1679,15 @@ InitKeyboard ( ConsoleIn->LeftCtrl = FALSE; ConsoleIn->RightCtrl = FALSE; ConsoleIn->LeftAlt = FALSE; - ConsoleIn->RightAlt = FALSE; + ConsoleIn->RightAlt = FALSE; ConsoleIn->LeftShift = FALSE; ConsoleIn->RightShift = FALSE; ConsoleIn->LeftLogo = FALSE; ConsoleIn->RightLogo = FALSE; ConsoleIn->Menu = FALSE; - ConsoleIn->SysReq = FALSE; + ConsoleIn->SysReq = FALSE; + ConsoleIn->IsSupportPartialKey = FALSE; // // For reseting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow, // and to support KB hot plug, we need to let the InitKB succeed no matter whether there is a KB device connected diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c index eb3c9338ce..a968a3b5f3 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c @@ -32,7 +32,33 @@ IsEfikeyBufEmpty ( return (BOOLEAN) (Queue->Head == Queue->Tail); } +/** + 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 OPTIONAL + ) +{ + if (IsEfikeyBufEmpty (Queue)) { + return EFI_NOT_READY; + } + // + // Retrieve and remove the values + // + if (KeyData != NULL) { + CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA)); + } + Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT; + return EFI_SUCCESS; +} /** Push one key data to the EFI key buffer. @@ -47,50 +73,26 @@ PushEfikeyBufTail ( ) { if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) { - return; + // + // If Queue is full, pop the one from head. + // + PopEfikeyBufHead (Queue, NULL); } - 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; -} - /** Judge whether is a registed key - @param RegsiteredData A pointer to a buffer that is filled in with the keystroke + @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 + @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. - + @retval FLASE Match failed. + **/ BOOLEAN IsKeyRegistered ( @@ -100,42 +102,42 @@ IsKeyRegistered ( { ASSERT (RegsiteredData != NULL && InputData != NULL); - + if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) || (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) { - return FALSE; - } - + return FALSE; + } + // // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored. // if (RegsiteredData->KeyState.KeyShiftState != 0 && RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) { - return FALSE; - } + return FALSE; + } if (RegsiteredData->KeyState.KeyToggleState != 0 && RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) { - return FALSE; - } - + return FALSE; + } + return TRUE; } /** - Reads the next keystroke from the input device. The WaitForKey Event can + Reads the next keystroke from the input device. The WaitForKey Event can be used to test for existance of a keystroke via WaitForEvent () call. - + @param ConsoleInDev Ps2 Keyboard private structure - @param KeyData A pointer to a buffer that is filled in with the keystroke + @param KeyData A pointer to a buffer that is filled in with the keystroke state data for the key that was pressed. - + @retval EFI_SUCCESS The keystroke information was returned. @retval EFI_NOT_READY There was no keystroke data availiable. - @retval EFI_DEVICE_ERROR The keystroke information was not returned due to + @retval EFI_DEVICE_ERROR The keystroke information was not returned due to hardware errors. - @retval EFI_INVALID_PARAMETER KeyData is NULL. + @retval EFI_INVALID_PARAMETER KeyData is NULL. **/ EFI_STATUS @@ -147,18 +149,18 @@ KeyboardReadKeyStrokeWorker ( { EFI_STATUS Status; EFI_TPL OldTpl; - + if (KeyData == NULL) { return EFI_INVALID_PARAMETER; } - + // // Enter critical section // OldTpl = gBS->RaiseTPL (TPL_NOTIFY); KeyboardTimerHandler (NULL, ConsoleInDev); - + if (ConsoleInDev->KeyboardErr) { Status = EFI_DEVICE_ERROR; } else { @@ -173,9 +175,9 @@ KeyboardReadKeyStrokeWorker ( Perform 8042 controller and keyboard initialization which implement SIMPLE_TEXT_IN.Reset() @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL - @param ExtendedVerification Indicate that the driver may perform a more - exhaustive verification operation of the device during - reset, now this par is ignored in this driver + @param ExtendedVerification Indicate that the driver may perform a more + exhaustive verification operation of the device during + reset, now this par is ignored in this driver **/ EFI_STATUS @@ -250,7 +252,7 @@ KeyboardEfiReset ( Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke(). @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL - @param Key The output buffer for key value + @param Key The output buffer for key value @retval EFI_SUCCESS success to read key stroke **/ @@ -266,14 +268,29 @@ KeyboardReadKeyStroke ( EFI_KEY_DATA KeyData; ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); - Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData); - if (EFI_ERROR (Status)) { - return Status; - } - - CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); - return EFI_SUCCESS; + // + // Considering if the partial keystroke is enabled, there maybe a partial + // keystroke in the queue, so here skip the partial keystroke and get the + // next key from the queue + // + while (1) { + // + // If there is no pending key, then return. + // + Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData); + if (EFI_ERROR (Status)) { + return Status; + } + // + // If it is partial keystroke, skip it. + // + if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) { + continue; + } + CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY)); + return EFI_SUCCESS; + } } /** @@ -293,6 +310,7 @@ KeyboardWaitForKey ( { EFI_TPL OldTpl; KEYBOARD_CONSOLE_IN_DEV *ConsoleIn; + EFI_KEY_DATA KeyData; ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context; @@ -300,16 +318,31 @@ KeyboardWaitForKey ( // Enter critical section // OldTpl = gBS->RaiseTPL (TPL_NOTIFY); - + KeyboardTimerHandler (NULL, ConsoleIn); if (!ConsoleIn->KeyboardErr) { // - // Someone is waiting on the keyboard event, if there's - // a key pending, signal the event + // WaitforKey doesn't suppor the partial key. + // Considering if the partial keystroke is enabled, there maybe a partial + // keystroke in the queue, so here skip the partial keystroke and get the + // next key from the queue // - if (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) { + while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) { + CopyMem ( + &KeyData, + &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]), + sizeof (EFI_KEY_DATA) + ); + if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) { + PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData); + continue; + } + // + // if there is pending value key, signal the event. + // gBS->SignalEvent (Event); + break; } } // @@ -344,7 +377,7 @@ KeyboardWaitForKeyEx ( @param ExtendedVerification Driver may perform diagnostics on reset. @retval EFI_SUCCESS The device was reset. - @retval EFI_DEVICE_ERROR The device is not functioning properly and could + @retval EFI_DEVICE_ERROR The device is not functioning properly and could not be reset. **/ @@ -358,28 +391,28 @@ KeyboardEfiResetEx ( { KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev; - ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); + ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); return ConsoleInDev->ConIn.Reset ( - &ConsoleInDev->ConIn, + &ConsoleInDev->ConIn, ExtendedVerification ); } /** - Reads the next keystroke from the input device. The WaitForKey Event can + Reads the next keystroke from the input device. The WaitForKey Event can be used to test for existance of a keystroke via WaitForEvent () call. @param This Protocol instance pointer. - @param KeyData A pointer to a buffer that is filled in with the keystroke + @param KeyData A pointer to a buffer that is filled in with the keystroke state data for the key that was pressed. @retval EFI_SUCCESS The keystroke information was returned. @retval EFI_NOT_READY There was no keystroke data availiable. - @retval EFI_DEVICE_ERROR The keystroke information was not returned due to + @retval EFI_DEVICE_ERROR The keystroke information was not returned due to hardware errors. - @retval EFI_INVALID_PARAMETER KeyData is NULL. + @retval EFI_INVALID_PARAMETER KeyData is NULL. **/ EFI_STATUS @@ -398,23 +431,22 @@ KeyboardReadKeyStrokeEx ( ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); return KeyboardReadKeyStrokeWorker (ConsoleInDev, KeyData); - } /** Set certain state for the input device. @param This Protocol instance pointer. - @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the + @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the state for the input device. @retval EFI_SUCCESS The device state was set successfully. - @retval EFI_DEVICE_ERROR The device is not functioning correctly and could + @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not have the setting adjusted. @retval EFI_UNSUPPORTED The device does not have the ability to set its state. - @retval EFI_INVALID_PARAMETER KeyToggleState is NULL. + @retval EFI_INVALID_PARAMETER KeyToggleState is NULL. -**/ +**/ EFI_STATUS EFIAPI KeyboardSetState ( @@ -430,7 +462,7 @@ KeyboardSetState ( if (KeyToggleState == NULL) { return EFI_INVALID_PARAMETER; } - + ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); // @@ -447,30 +479,34 @@ KeyboardSetState ( Status = EFI_UNSUPPORTED; goto Exit; } - + // // Update the status light // - ConsoleInDev->ScrollLock = FALSE; - ConsoleInDev->NumLock = FALSE; - ConsoleInDev->CapsLock = FALSE; + ConsoleInDev->ScrollLock = FALSE; + ConsoleInDev->NumLock = FALSE; + ConsoleInDev->CapsLock = FALSE; + ConsoleInDev->IsSupportPartialKey = FALSE; if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) { ConsoleInDev->ScrollLock = TRUE; - } + } if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) { ConsoleInDev->NumLock = TRUE; } if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) { ConsoleInDev->CapsLock = TRUE; } + if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) { + ConsoleInDev->IsSupportPartialKey = TRUE; + } Status = UpdateStatusLights (ConsoleInDev); if (EFI_ERROR (Status)) { - Status = EFI_DEVICE_ERROR; + Status = EFI_DEVICE_ERROR; } -Exit: +Exit: // // Leave critical section and return // @@ -484,17 +520,17 @@ Exit: Register a notification function for a particular keystroke for the input device. @param This Protocol instance pointer. - @param KeyData A pointer to a buffer that is filled in with the keystroke + @param KeyData A pointer to a buffer that is filled in with the keystroke information data for the key that was pressed. - @param KeyNotificationFunction Points to the function to be called when the key - sequence is typed specified by KeyData. - @param NotifyHandle Points to the unique handle assigned to the registered notification. + @param KeyNotificationFunction Points to the function to be called when the key + sequence is typed specified by KeyData. + @param NotifyHandle Points to the unique handle assigned to the registered notification. @retval EFI_SUCCESS The notification function was registered successfully. @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures. - @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL. - -**/ + @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL. + +**/ EFI_STATUS EFIAPI KeyboardRegisterKeyNotify ( @@ -508,13 +544,13 @@ KeyboardRegisterKeyNotify ( KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev; EFI_TPL OldTpl; LIST_ENTRY *Link; - KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; + KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify; if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) { return EFI_INVALID_PARAMETER; } - + ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); // @@ -527,36 +563,36 @@ KeyboardRegisterKeyNotify ( // for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) { CurrentNotify = CR ( - Link, - KEYBOARD_CONSOLE_IN_EX_NOTIFY, - NotifyEntry, + Link, + KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE ); - if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { + if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) { if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) { - *NotifyHandle = CurrentNotify->NotifyHandle; + *NotifyHandle = CurrentNotify->NotifyHandle; Status = EFI_SUCCESS; goto Exit; } } - } - + } + // // Allocate resource to save the notification function - // + // NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY)); if (NewNotify == NULL) { Status = EFI_OUT_OF_RESOURCES; goto Exit; } - NewNotify->Signature = KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE; + NewNotify->Signature = KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE; NewNotify->KeyNotificationFn = KeyNotificationFunction; NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify; CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA)); InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry); - *NotifyHandle = NewNotify->NotifyHandle; + *NotifyHandle = NewNotify->NotifyHandle; Status = EFI_SUCCESS; Exit: @@ -564,21 +600,21 @@ Exit: // Leave critical section and return // gBS->RestoreTPL (OldTpl); - return Status; + return Status; } /** Remove a registered notification function from a particular keystroke. - @param This Protocol instance pointer. + @param This Protocol instance pointer. @param NotificationHandle The handle of the notification function being unregistered. - + @retval EFI_SUCCESS The notification function was unregistered successfully. @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid. - -**/ + +**/ EFI_STATUS EFIAPI KeyboardUnregisterKeyNotify ( @@ -590,37 +626,37 @@ KeyboardUnregisterKeyNotify ( KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev; EFI_TPL OldTpl; LIST_ENTRY *Link; - KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; + KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify; if (NotificationHandle == NULL) { return EFI_INVALID_PARAMETER; - } + } if (((KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) { return EFI_INVALID_PARAMETER; - } - + } + ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This); - + // // Enter critical section // - OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) { CurrentNotify = CR ( - Link, - KEYBOARD_CONSOLE_IN_EX_NOTIFY, - NotifyEntry, + Link, + KEYBOARD_CONSOLE_IN_EX_NOTIFY, + NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE - ); + ); if (CurrentNotify->NotifyHandle == NotificationHandle) { // // Remove the notification function from NotifyList and free resources // - RemoveEntryList (&CurrentNotify->NotifyEntry); - - gBS->FreePool (CurrentNotify); + RemoveEntryList (&CurrentNotify->NotifyEntry); + + gBS->FreePool (CurrentNotify); Status = EFI_SUCCESS; goto Exit; } diff --git a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h index deeb59b951..704c03618e 100644 --- a/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h +++ b/IntelFrameworkModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h @@ -89,7 +89,7 @@ typedef struct { BOOLEAN LeftAlt; BOOLEAN RightAlt; BOOLEAN LeftShift; - BOOLEAN RightShift; + BOOLEAN RightShift; BOOLEAN LeftLogo; BOOLEAN RightLogo; BOOLEAN Menu; @@ -99,6 +99,7 @@ typedef struct { BOOLEAN NumLock; BOOLEAN ScrollLock; + BOOLEAN IsSupportPartialKey; // // Queue storing key scancodes // @@ -135,9 +136,9 @@ typedef struct { /** The user Entry Point for module Ps2Keyboard. The user code starts with this function. - @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. - + @retval EFI_SUCCESS The entry point is executed successfully. @retval other Some error occurs when executing this entry point. @@ -179,7 +180,7 @@ InstallPs2KeyboardDriver ( #define SCANCODE_LEFT_LOGO_BREAK 0xDB #define SCANCODE_RIGHT_LOGO_MAKE 0x5C #define SCANCODE_RIGHT_LOGO_BREAK 0xDC -#define SCANCODE_MENU_MAKE 0x5D //APPS key defined in Keyboard scan code +#define SCANCODE_MENU_MAKE 0x5D //APPS key defined in Keyboard scan code #define SCANCODE_MENU_BREAK 0xDD #define SCANCODE_SYS_REQ_MAKE 0x37 #define SCANCODE_SYS_REQ_BREAK 0xB7 @@ -229,7 +230,7 @@ InstallPs2KeyboardDriver ( indicators in ConsoleIn. @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV - + @return status **/ @@ -321,9 +322,9 @@ KeyboardTimerHandler ( Perform 8042 controller and keyboard initialization @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL - @param ExtendedVerification Indicate that the driver may perform a more - exhaustive verification operation of the device during - reset, now this par is ignored in this driver + @param ExtendedVerification Indicate that the driver may perform a more + exhaustive verification operation of the device during + reset, now this par is ignored in this driver **/ EFI_STATUS @@ -338,7 +339,7 @@ KeyboardEfiReset ( Retrieve key values for driver user. @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL - @param Key The output buffer for key value + @param Key The output buffer for key value @retval EFI_SUCCESS success to read key stroke **/ @@ -406,7 +407,7 @@ EFIAPI KeyboardWaitForKeyEx ( IN EFI_EVENT Event, IN VOID *Context - ); + ); // // Simple Text Input Ex protocol function prototypes @@ -419,7 +420,7 @@ KeyboardWaitForKeyEx ( @param ExtendedVerification - Driver may perform diagnostics on reset. @retval EFI_SUCCESS - The device was reset. - @retval EFI_DEVICE_ERROR - The device is not functioning properly and could + @retval EFI_DEVICE_ERROR - The device is not functioning properly and could not be reset. **/ @@ -431,19 +432,19 @@ KeyboardEfiResetEx ( ); /** - Reads the next keystroke from the input device. The WaitForKey Event can + Reads the next keystroke from the input device. The WaitForKey Event can be used to test for existance of a keystroke via WaitForEvent () call. @param This - Protocol instance pointer. - @param KeyData - A pointer to a buffer that is filled in with the keystroke + @param KeyData - A pointer to a buffer that is filled in with the keystroke state data for the key that was pressed. @retval EFI_SUCCESS - The keystroke information was returned. @retval EFI_NOT_READY - There was no keystroke data availiable. - @retval EFI_DEVICE_ERROR - The keystroke information was not returned due to + @retval EFI_DEVICE_ERROR - The keystroke information was not returned due to hardware errors. - @retval EFI_INVALID_PARAMETER - KeyData is NULL. + @retval EFI_INVALID_PARAMETER - KeyData is NULL. **/ EFI_STATUS @@ -457,14 +458,14 @@ KeyboardReadKeyStrokeEx ( Set certain state for the input device. @param This - Protocol instance pointer. - @param KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the + @param KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the state for the input device. @retval EFI_SUCCESS - The device state was set successfully. - @retval EFI_DEVICE_ERROR - The device is not functioning correctly and could + @retval EFI_DEVICE_ERROR - The device is not functioning correctly and could not have the setting adjusted. @retval EFI_UNSUPPORTED - The device does not have the ability to set its state. - @retval EFI_INVALID_PARAMETER - KeyToggleState is NULL. + @retval EFI_INVALID_PARAMETER - KeyToggleState is NULL. **/ EFI_STATUS @@ -478,17 +479,17 @@ KeyboardSetState ( Register a notification function for a particular keystroke for the input device. @param This - Protocol instance pointer. - @param KeyData - A pointer to a buffer that is filled in with the keystroke + @param KeyData - A pointer to a buffer that is filled in with the keystroke information data for the key that was pressed. - @param KeyNotificationFunction - Points to the function to be called when the key - sequence is typed specified by KeyData. - @param NotifyHandle - Points to the unique handle assigned to the registered notification. + @param KeyNotificationFunction - Points to the function to be called when the key + sequence is typed specified by KeyData. + @param NotifyHandle - Points to the unique handle assigned to the registered notification. @retval EFI_SUCCESS - The notification function was registered successfully. @retval EFI_OUT_OF_RESOURCES - Unable to allocate resources for necesssary data structures. - @retval EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. - -**/ + @retval EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL. + +**/ EFI_STATUS EFIAPI KeyboardRegisterKeyNotify ( @@ -501,15 +502,15 @@ KeyboardRegisterKeyNotify ( /** Remove a registered notification function from a particular keystroke. - @param This - Protocol instance pointer. + @param This - Protocol instance pointer. @param NotificationHandle - The handle of the notification function being unregistered. - + @retval EFI_SUCCESS - The notification function was unregistered successfully. @retval EFI_INVALID_PARAMETER - The NotificationHandle is invalid. - @retval EFI_NOT_FOUND - Can not find the matching entry in database. - -**/ + @retval EFI_NOT_FOUND - Can not find the matching entry in database. + +**/ EFI_STATUS EFIAPI KeyboardUnregisterKeyNotify ( @@ -532,18 +533,19 @@ PushEfikeyBufTail ( /** Judge whether is a registed key - @param RegsiteredData A pointer to a buffer that is filled in with the keystroke + @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 + @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. - + @retval FLASE Match failed. + **/ BOOLEAN IsKeyRegistered ( IN EFI_KEY_DATA *RegsiteredData, IN EFI_KEY_DATA *InputData ); + #endif diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c index 24578aab81..2729d0b441 100644 --- a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c +++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c @@ -2171,7 +2171,12 @@ BiosKeyboardSetState ( return EFI_INVALID_PARAMETER; } - if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) { + // + // Thunk keyboard driver doesn't support partial keystroke. + // + if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID || + (*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED + ) { return EFI_UNSUPPORTED; }