]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Bus / Isa / Ps2KeyboardDxe / Ps2KbdTextIn.c
index f6ccd9598fb0b0e7d98043c85f4a59b891f9d8e8..b1ab17af37882c221ee613c64bf0e7e321e256ac 100644 (file)
@@ -2,18 +2,11 @@
   Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces\r
   provided by Ps2KbdCtrller.c.\r
 \r
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-\r
 #include "Ps2Keyboard.h"\r
 \r
 /**\r
@@ -26,10 +19,10 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 **/\r
 BOOLEAN\r
 IsEfikeyBufEmpty (\r
-  IN  EFI_KEY_QUEUE         *Queue\r
+  IN  EFI_KEY_QUEUE  *Queue\r
   )\r
 {\r
-  return (BOOLEAN) (Queue->Head == Queue->Tail);\r
+  return (BOOLEAN)(Queue->Head == Queue->Tail);\r
 }\r
 \r
 /**\r
@@ -43,19 +36,21 @@ IsEfikeyBufEmpty (
 **/\r
 EFI_STATUS\r
 PopEfikeyBufHead (\r
-  IN  EFI_KEY_QUEUE         *Queue,\r
-  OUT EFI_KEY_DATA          *KeyData OPTIONAL\r
+  IN  EFI_KEY_QUEUE  *Queue,\r
+  OUT EFI_KEY_DATA   *KeyData OPTIONAL\r
   )\r
 {\r
   if (IsEfikeyBufEmpty (Queue)) {\r
     return EFI_NOT_READY;\r
   }\r
+\r
   //\r
   // Retrieve and remove the values\r
   //\r
   if (KeyData != NULL) {\r
     CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));\r
   }\r
+\r
   Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
   return EFI_SUCCESS;\r
 }\r
@@ -68,8 +63,8 @@ PopEfikeyBufHead (
 **/\r
 VOID\r
 PushEfikeyBufTail (\r
-  IN  EFI_KEY_QUEUE         *Queue,\r
-  IN  EFI_KEY_DATA          *KeyData\r
+  IN  EFI_KEY_QUEUE  *Queue,\r
+  IN  EFI_KEY_DATA   *KeyData\r
   )\r
 {\r
   if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {\r
@@ -78,12 +73,13 @@ PushEfikeyBufTail (
     //\r
     PopEfikeyBufHead (Queue, NULL);\r
   }\r
+\r
   CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));\r
   Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;\r
 }\r
 \r
 /**\r
-  Judge whether is a registed key\r
+  Judge whether is a registered key\r
 \r
   @param RegsiteredData       A pointer to a buffer that is filled in with the keystroke\r
                               state data for the key that was registered.\r
@@ -91,7 +87,7 @@ PushEfikeyBufTail (
                               state data for the key that was pressed.\r
 \r
   @retval TRUE                Key be pressed matches a registered key.\r
-  @retval FLASE               Match failed.\r
+  @retval FALSE               Match failed.\r
 \r
 **/\r
 BOOLEAN\r
@@ -104,29 +100,32 @@ IsKeyRegistered (
   ASSERT (RegsiteredData != NULL && InputData != NULL);\r
 \r
   if ((RegsiteredData->Key.ScanCode    != InputData->Key.ScanCode) ||\r
-      (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\r
+      (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))\r
+  {\r
     return FALSE;\r
   }\r
 \r
   //\r
   // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.\r
   //\r
-  if (RegsiteredData->KeyState.KeyShiftState != 0 &&\r
-      RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {\r
+  if ((RegsiteredData->KeyState.KeyShiftState != 0) &&\r
+      (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))\r
+  {\r
     return FALSE;\r
   }\r
-  if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
-      RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
+\r
+  if ((RegsiteredData->KeyState.KeyToggleState != 0) &&\r
+      (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))\r
+  {\r
     return FALSE;\r
   }\r
 \r
   return TRUE;\r
-\r
 }\r
 \r
 /**\r
     Reads the next keystroke from the input device. The WaitForKey Event can\r
-    be used to test for existance of a keystroke via WaitForEvent () call.\r
+    be used to test for existence of a keystroke via WaitForEvent () call.\r
 \r
     @param ConsoleInDev          Ps2 Keyboard private structure\r
     @param KeyData               A pointer to a buffer that is filled in with the keystroke\r
@@ -134,7 +133,7 @@ IsKeyRegistered (
 \r
 \r
     @retval EFI_SUCCESS             The keystroke information was returned.\r
-    @retval EFI_NOT_READY           There was no keystroke data availiable.\r
+    @retval EFI_NOT_READY           There was no keystroke data available.\r
     @retval EFI_DEVICE_ERROR        The keystroke information was not returned due to\r
                                     hardware errors.\r
     @retval EFI_INVALID_PARAMETER   KeyData is NULL.\r
@@ -142,13 +141,13 @@ IsKeyRegistered (
 **/\r
 EFI_STATUS\r
 KeyboardReadKeyStrokeWorker (\r
-  IN  KEYBOARD_CONSOLE_IN_DEV           *ConsoleInDev,\r
-  OUT EFI_KEY_DATA                      *KeyData\r
+  IN  KEYBOARD_CONSOLE_IN_DEV  *ConsoleInDev,\r
+  OUT EFI_KEY_DATA             *KeyData\r
   )\r
 \r
 {\r
-  EFI_STATUS                            Status;\r
-  EFI_TPL                               OldTpl;\r
+  EFI_STATUS  Status;\r
+  EFI_TPL     OldTpl;\r
 \r
   if (KeyData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -165,6 +164,10 @@ KeyboardReadKeyStrokeWorker (
     Status = EFI_DEVICE_ERROR;\r
   } else {\r
     Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);\r
+    if (Status == EFI_NOT_READY) {\r
+      ZeroMem (&KeyData->Key, sizeof (KeyData->Key));\r
+      InitializeKeyState (ConsoleInDev, &KeyData->KeyState);\r
+    }\r
   }\r
 \r
   gBS->RestoreTPL (OldTpl);\r
@@ -187,9 +190,9 @@ KeyboardEfiReset (
   IN  BOOLEAN                         ExtendedVerification\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
-  EFI_TPL                 OldTpl;\r
+  EFI_STATUS               Status;\r
+  KEYBOARD_CONSOLE_IN_DEV  *ConsoleIn;\r
+  EFI_TPL                  OldTpl;\r
 \r
   ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
   if (ConsoleIn->KeyboardErr) {\r
@@ -234,6 +237,7 @@ KeyboardEfiReset (
       ConsoleIn->DevicePath\r
       );\r
   }\r
+\r
   //\r
   // Report the status If keyboard is locked\r
   //\r
@@ -263,9 +267,9 @@ KeyboardReadKeyStroke (
   OUT EFI_INPUT_KEY                   *Key\r
   )\r
 {\r
-  EFI_STATUS              Status;\r
-  KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;\r
-  EFI_KEY_DATA            KeyData;\r
+  EFI_STATUS               Status;\r
+  KEYBOARD_CONSOLE_IN_DEV  *ConsoleIn;\r
+  EFI_KEY_DATA             KeyData;\r
 \r
   ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
 \r
@@ -282,21 +286,23 @@ KeyboardReadKeyStroke (
     if (EFI_ERROR (Status)) {\r
       return Status;\r
     }\r
+\r
     //\r
     // If it is partial keystroke, skip it.\r
     //\r
-    if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+    if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {\r
       continue;\r
     }\r
+\r
     //\r
     // Translate the CTRL-Alpha characters to their corresponding control value\r
     // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)\r
     //\r
     if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
-      if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {\r
-        KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'a' + 1);\r
-      } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {\r
-        KeyData.Key.UnicodeChar = (CHAR16) (KeyData.Key.UnicodeChar - L'A' + 1);\r
+      if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {\r
+        KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'a' + 1);\r
+      } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {\r
+        KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'A' + 1);\r
       }\r
     }\r
 \r
@@ -310,21 +316,21 @@ KeyboardReadKeyStroke (
   Signal the event if there is key available\r
 \r
   @param Event    the event object\r
-  @param Context  waitting context\r
+  @param Context  waiting context\r
 \r
 **/\r
 VOID\r
 EFIAPI\r
 KeyboardWaitForKey (\r
-  IN  EFI_EVENT               Event,\r
-  IN  VOID                    *Context\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
   )\r
 {\r
-  EFI_TPL                     OldTpl;\r
-  KEYBOARD_CONSOLE_IN_DEV     *ConsoleIn;\r
-  EFI_KEY_DATA                KeyData;\r
+  EFI_TPL                  OldTpl;\r
+  KEYBOARD_CONSOLE_IN_DEV  *ConsoleIn;\r
+  EFI_KEY_DATA             KeyData;\r
 \r
-  ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *) Context;\r
+  ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;\r
 \r
   //\r
   // Enter critical section\r
@@ -335,7 +341,7 @@ KeyboardWaitForKey (
 \r
   if (!ConsoleIn->KeyboardErr) {\r
     //\r
-    // WaitforKey doesn't suppor the partial key.\r
+    // WaitforKey doesn't support the partial key.\r
     // Considering if the partial keystroke is enabled, there maybe a partial\r
     // keystroke in the queue, so here skip the partial keystroke and get the\r
     // next key from the queue\r
@@ -346,10 +352,11 @@ KeyboardWaitForKey (
         &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),\r
         sizeof (EFI_KEY_DATA)\r
         );\r
-      if (KeyData.Key.ScanCode == SCAN_NULL && KeyData.Key.UnicodeChar == CHAR_NULL) {\r
+      if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {\r
         PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);\r
         continue;\r
       }\r
+\r
       //\r
       // if there is pending value key, signal the event.\r
       //\r
@@ -357,6 +364,7 @@ KeyboardWaitForKey (
       break;\r
     }\r
   }\r
+\r
   //\r
   // Leave critical section and return\r
   //\r
@@ -374,8 +382,8 @@ KeyboardWaitForKey (
 VOID\r
 EFIAPI\r
 KeyboardWaitForKeyEx (\r
-  IN  EFI_EVENT               Event,\r
-  IN  VOID                    *Context\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
   )\r
 \r
 {\r
@@ -383,7 +391,7 @@ KeyboardWaitForKeyEx (
 }\r
 \r
 /**\r
-  Reset the input device and optionaly run diagnostics\r
+  Reset the input device and optionally run diagnostics\r
 \r
   @param This                     Protocol instance pointer.\r
   @param ExtendedVerification     Driver may perform diagnostics on reset.\r
@@ -401,7 +409,7 @@ KeyboardEfiResetEx (
   )\r
 \r
 {\r
-  KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
+  KEYBOARD_CONSOLE_IN_DEV  *ConsoleInDev;\r
 \r
   ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);\r
 \r
@@ -413,7 +421,7 @@ KeyboardEfiResetEx (
 \r
 /**\r
     Reads the next keystroke from the input device. The WaitForKey Event can\r
-    be used to test for existance of a keystroke via WaitForEvent () call.\r
+    be used to test for existence of a keystroke via WaitForEvent () call.\r
 \r
 \r
     @param This         Protocol instance pointer.\r
@@ -421,7 +429,7 @@ KeyboardEfiResetEx (
                         state data for the key that was pressed.\r
 \r
     @retval EFI_SUCCESS           The keystroke information was returned.\r
-    @retval EFI_NOT_READY         There was no keystroke data availiable.\r
+    @retval EFI_NOT_READY         There was no keystroke data available.\r
     @retval EFI_DEVICE_ERROR      The keystroke information was not returned due to\r
                                   hardware errors.\r
     @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
@@ -430,12 +438,12 @@ KeyboardEfiResetEx (
 EFI_STATUS\r
 EFIAPI\r
 KeyboardReadKeyStrokeEx (\r
-  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
-  OUT EFI_KEY_DATA                      *KeyData\r
+  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
+  OUT EFI_KEY_DATA                       *KeyData\r
   )\r
 \r
 {\r
-  KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
+  KEYBOARD_CONSOLE_IN_DEV  *ConsoleInDev;\r
 \r
   if (KeyData == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -467,9 +475,9 @@ KeyboardSetState (
   )\r
 \r
 {\r
-  EFI_STATUS                            Status;\r
-  KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
-  EFI_TPL                               OldTpl;\r
+  EFI_STATUS               Status;\r
+  KEYBOARD_CONSOLE_IN_DEV  *ConsoleInDev;\r
+  EFI_TPL                  OldTpl;\r
 \r
   if (KeyToggleState == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -503,12 +511,15 @@ KeyboardSetState (
   if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
     ConsoleInDev->ScrollLock = TRUE;\r
   }\r
+\r
   if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
     ConsoleInDev->NumLock = TRUE;\r
   }\r
+\r
   if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
     ConsoleInDev->CapsLock = TRUE;\r
   }\r
+\r
   if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {\r
     ConsoleInDev->IsSupportPartialKey = TRUE;\r
   }\r
@@ -525,7 +536,6 @@ Exit:
   gBS->RestoreTPL (OldTpl);\r
 \r
   return Status;\r
-\r
 }\r
 \r
 /**\r
@@ -533,13 +543,16 @@ Exit:
 \r
     @param This                       Protocol instance pointer.\r
     @param KeyData                    A pointer to a buffer that is filled in with the keystroke\r
-                                      information data for the key that was pressed.\r
+                                      information data for the key that was pressed. If KeyData.Key,\r
+                                      KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0,\r
+                                      then any incomplete keystroke will trigger a notification of the KeyNotificationFunction.\r
     @param KeyNotificationFunction    Points to the function to be called when the key\r
-                                      sequence is typed specified by KeyData.\r
+                                      sequence is typed specified by KeyData. This notification function\r
+                                      should be called at <=TPL_CALLBACK.\r
     @param NotifyHandle               Points to the unique handle assigned to the registered notification.\r
 \r
     @retval EFI_SUCCESS               The notification function was registered successfully.\r
-    @retval EFI_OUT_OF_RESOURCES      Unable to allocate resources for necesssary data structures.\r
+    @retval EFI_OUT_OF_RESOURCES      Unable to allocate resources for necessary data structures.\r
     @retval EFI_INVALID_PARAMETER     KeyData or NotifyHandle or KeyNotificationFunction is NULL.\r
 \r
 **/\r
@@ -552,14 +565,14 @@ KeyboardRegisterKeyNotify (
   OUT VOID                              **NotifyHandle\r
   )\r
 {\r
-  EFI_STATUS                            Status;\r
-  KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
-  EFI_TPL                               OldTpl;\r
-  LIST_ENTRY                            *Link;\r
-  KEYBOARD_CONSOLE_IN_EX_NOTIFY         *CurrentNotify;\r
-  KEYBOARD_CONSOLE_IN_EX_NOTIFY         *NewNotify;\r
-\r
-  if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
+  EFI_STATUS                     Status;\r
+  KEYBOARD_CONSOLE_IN_DEV        *ConsoleInDev;\r
+  EFI_TPL                        OldTpl;\r
+  LIST_ENTRY                     *Link;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY  *CurrentNotify;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY  *NewNotify;\r
+\r
+  if ((KeyData == NULL) || (NotifyHandle == NULL) || (KeyNotificationFunction == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
   }\r
 \r
@@ -583,7 +596,7 @@ KeyboardRegisterKeyNotify (
     if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
       if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
         *NotifyHandle = CurrentNotify;\r
-        Status = EFI_SUCCESS;\r
+        Status        = EFI_SUCCESS;\r
         goto Exit;\r
       }\r
     }\r
@@ -592,7 +605,7 @@ KeyboardRegisterKeyNotify (
   //\r
   // Allocate resource to save the notification function\r
   //\r
-  NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
+  NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *)AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
   if (NewNotify == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto Exit;\r
@@ -603,8 +616,8 @@ KeyboardRegisterKeyNotify (
   CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
   InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);\r
 \r
-  *NotifyHandle                = NewNotify;\r
-  Status                       = EFI_SUCCESS;\r
+  *NotifyHandle = NewNotify;\r
+  Status        = EFI_SUCCESS;\r
 \r
 Exit:\r
   //\r
@@ -612,7 +625,6 @@ Exit:
   //\r
   gBS->RestoreTPL (OldTpl);\r
   return Status;\r
-\r
 }\r
 \r
 /**\r
@@ -633,11 +645,11 @@ KeyboardUnregisterKeyNotify (
   IN VOID                               *NotificationHandle\r
   )\r
 {\r
-  EFI_STATUS                            Status;\r
-  KEYBOARD_CONSOLE_IN_DEV               *ConsoleInDev;\r
-  EFI_TPL                               OldTpl;\r
-  LIST_ENTRY                            *Link;\r
-  KEYBOARD_CONSOLE_IN_EX_NOTIFY         *CurrentNotify;\r
+  EFI_STATUS                     Status;\r
+  KEYBOARD_CONSOLE_IN_DEV        *ConsoleInDev;\r
+  EFI_TPL                        OldTpl;\r
+  LIST_ENTRY                     *Link;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY  *CurrentNotify;\r
 \r
   if (NotificationHandle == NULL) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -681,3 +693,52 @@ Exit:
   return Status;\r
 }\r
 \r
+/**\r
+  Process key notify.\r
+\r
+  @param  Event                 Indicates the event that invoke this function.\r
+  @param  Context               Indicates the calling context.\r
+**/\r
+VOID\r
+EFIAPI\r
+KeyNotifyProcessHandler (\r
+  IN  EFI_EVENT  Event,\r
+  IN  VOID       *Context\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+  KEYBOARD_CONSOLE_IN_DEV        *ConsoleIn;\r
+  EFI_KEY_DATA                   KeyData;\r
+  LIST_ENTRY                     *Link;\r
+  LIST_ENTRY                     *NotifyList;\r
+  KEYBOARD_CONSOLE_IN_EX_NOTIFY  *CurrentNotify;\r
+  EFI_TPL                        OldTpl;\r
+\r
+  ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;\r
+\r
+  //\r
+  // Invoke notification functions.\r
+  //\r
+  NotifyList = &ConsoleIn->NotifyList;\r
+  while (TRUE) {\r
+    //\r
+    // Enter critical section\r
+    //\r
+    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+    Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);\r
+    //\r
+    // Leave critical section\r
+    //\r
+    gBS->RestoreTPL (OldTpl);\r
+    if (EFI_ERROR (Status)) {\r
+      break;\r
+    }\r
+\r
+    for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
+      CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
+      if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
+        CurrentNotify->KeyNotificationFn (&KeyData);\r
+      }\r
+    }\r
+  }\r
+}\r