]> git.proxmox.com Git - mirror_edk2.git/blobdiff - IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
Remove IntelFrameworkModulePkg
[mirror_edk2.git] / IntelFrameworkModulePkg / Csm / BiosThunk / KeyboardDxe / BiosKeyboard.c
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
deleted file mode 100644 (file)
index 7f3f48b..0000000
+++ /dev/null
@@ -1,2514 +0,0 @@
-/** @file\r
-  ConsoleOut Routines that speak VGA.\r
-\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BiosKeyboard.h"\r
-\r
-//\r
-// EFI Driver Binding Protocol Instance\r
-//\r
-EFI_DRIVER_BINDING_PROTOCOL gBiosKeyboardDriverBinding = {\r
-  BiosKeyboardDriverBindingSupported,\r
-  BiosKeyboardDriverBindingStart,\r
-  BiosKeyboardDriverBindingStop,\r
-  0x3,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-\r
-/**\r
-  Enqueue the key.\r
-\r
-  @param  Queue                 The queue to be enqueued.\r
-  @param  KeyData               The key data to be enqueued.\r
-\r
-  @retval EFI_NOT_READY         The queue is full.\r
-  @retval EFI_SUCCESS           Successfully enqueued the key data.\r
-\r
-**/\r
-EFI_STATUS\r
-Enqueue (\r
-  IN SIMPLE_QUEUE         *Queue,\r
-  IN EFI_KEY_DATA         *KeyData\r
-  )\r
-{\r
-  if ((Queue->Rear + 1) % QUEUE_MAX_COUNT == Queue->Front) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  CopyMem (&Queue->Buffer[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));\r
-  Queue->Rear = (Queue->Rear + 1) % QUEUE_MAX_COUNT;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Dequeue the key.\r
-\r
-  @param  Queue                 The queue to be dequeued.\r
-  @param  KeyData               The key data to be dequeued.\r
-\r
-  @retval EFI_NOT_READY         The queue is empty.\r
-  @retval EFI_SUCCESS           Successfully dequeued the key data.\r
-\r
-**/\r
-EFI_STATUS\r
-Dequeue (\r
-  IN SIMPLE_QUEUE         *Queue,\r
-  IN EFI_KEY_DATA         *KeyData\r
-  )\r
-{\r
-  if (Queue->Front == Queue->Rear) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  CopyMem (KeyData, &Queue->Buffer[Queue->Front], sizeof (EFI_KEY_DATA));\r
-  Queue->Front  = (Queue->Front + 1) % QUEUE_MAX_COUNT;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Check whether the queue is empty.\r
-\r
-  @param  Queue                 The queue to be checked.\r
-\r
-  @retval EFI_NOT_READY         The queue is empty.\r
-  @retval EFI_SUCCESS           The queue is not empty.\r
-\r
-**/\r
-EFI_STATUS\r
-CheckQueue (\r
-  IN SIMPLE_QUEUE         *Queue\r
-  )\r
-{\r
-  if (Queue->Front == Queue->Rear) {\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// EFI Driver Binding Protocol Functions\r
-//\r
-\r
-/**\r
-  Check whether the driver supports this device.\r
-\r
-  @param  This                   The Udriver binding protocol.\r
-  @param  Controller             The controller handle to check.\r
-  @param  RemainingDevicePath    The remaining device path.\r
-\r
-  @retval EFI_SUCCESS            The driver supports this controller.\r
-  @retval other                  This device isn't supported.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardDriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS                                Status;\r
-  EFI_LEGACY_BIOS_PROTOCOL                  *LegacyBios;\r
-  EFI_ISA_IO_PROTOCOL                       *IsaIo;\r
-\r
-  //\r
-  // See if the Legacy BIOS Protocol is available\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiLegacyBiosProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &LegacyBios\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Open the IO Abstraction(s) needed to perform the supported test\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiIsaIoProtocolGuid,\r
-                  (VOID **) &IsaIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Use the ISA I/O Protocol to see if Controller is the Keyboard controller\r
-  //\r
-  if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303) || IsaIo->ResourceList->Device.UID != 0) {\r
-    Status = EFI_UNSUPPORTED;\r
-  }\r
-\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiIsaIoProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Starts the device with this driver.\r
-\r
-  @param  This                   The driver binding instance.\r
-  @param  Controller             Handle of device to bind driver to.\r
-  @param  RemainingDevicePath    Optional parameter use to pick a specific child\r
-                                 device to start.\r
-\r
-  @retval EFI_SUCCESS            The controller is controlled by the driver.\r
-  @retval Other                  This controller cannot be started.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardDriverBindingStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS                                Status;\r
-  EFI_LEGACY_BIOS_PROTOCOL                  *LegacyBios;\r
-  EFI_ISA_IO_PROTOCOL                       *IsaIo;\r
-  BIOS_KEYBOARD_DEV                         *BiosKeyboardPrivate;\r
-  EFI_IA32_REGISTER_SET                     Regs;\r
-  BOOLEAN                                   CarryFlag;\r
-  EFI_PS2_POLICY_PROTOCOL                   *Ps2Policy;\r
-  UINT8                                     Command;\r
-  EFI_STATUS_CODE_VALUE                     StatusCode;\r
-\r
-  BiosKeyboardPrivate = NULL;\r
-  IsaIo = NULL;\r
-  StatusCode          = 0;\r
-\r
-  //\r
-  // Get Ps2 policy to set. Will be use if present.\r
-  //\r
-  gBS->LocateProtocol (\r
-        &gEfiPs2PolicyProtocolGuid,\r
-        NULL,\r
-        (VOID **) &Ps2Policy\r
-        );\r
-\r
-  //\r
-  // See if the Legacy BIOS Protocol is available\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiLegacyBiosProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &LegacyBios\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Open the IO Abstraction(s) needed\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiIsaIoProtocolGuid,\r
-                  (VOID **) &IsaIo,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Allocate the private device structure\r
-  //\r
-    BiosKeyboardPrivate = (BIOS_KEYBOARD_DEV *) AllocateZeroPool (sizeof (BIOS_KEYBOARD_DEV));\r
-  if (NULL == BiosKeyboardPrivate) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Initialize the private device structure\r
-  //\r
-  BiosKeyboardPrivate->Signature                  = BIOS_KEYBOARD_DEV_SIGNATURE;\r
-  BiosKeyboardPrivate->Handle                     = Controller;\r
-  BiosKeyboardPrivate->LegacyBios                 = LegacyBios;\r
-  BiosKeyboardPrivate->IsaIo                      = IsaIo;\r
-\r
-  BiosKeyboardPrivate->SimpleTextIn.Reset         = BiosKeyboardReset;\r
-  BiosKeyboardPrivate->SimpleTextIn.ReadKeyStroke = BiosKeyboardReadKeyStroke;\r
-\r
-  BiosKeyboardPrivate->DataRegisterAddress        = KEYBOARD_8042_DATA_REGISTER;\r
-  BiosKeyboardPrivate->StatusRegisterAddress      = KEYBOARD_8042_STATUS_REGISTER;\r
-  BiosKeyboardPrivate->CommandRegisterAddress     = KEYBOARD_8042_COMMAND_REGISTER;\r
-  BiosKeyboardPrivate->ExtendedKeyboard           = TRUE;\r
-\r
-  BiosKeyboardPrivate->KeyState.KeyShiftState     = 0;\r
-  BiosKeyboardPrivate->KeyState.KeyToggleState    = 0;\r
-  BiosKeyboardPrivate->Queue.Front                = 0;\r
-  BiosKeyboardPrivate->Queue.Rear                 = 0;\r
-  BiosKeyboardPrivate->QueueForNotify.Front       = 0;\r
-  BiosKeyboardPrivate->QueueForNotify.Rear        = 0;\r
-  BiosKeyboardPrivate->SimpleTextInputEx.Reset               = BiosKeyboardResetEx;\r
-  BiosKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx     = BiosKeyboardReadKeyStrokeEx;\r
-  BiosKeyboardPrivate->SimpleTextInputEx.SetState            = BiosKeyboardSetState;\r
-  BiosKeyboardPrivate->SimpleTextInputEx.RegisterKeyNotify   = BiosKeyboardRegisterKeyNotify;\r
-  BiosKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify = BiosKeyboardUnregisterKeyNotify;\r
-  InitializeListHead (&BiosKeyboardPrivate->NotifyList);\r
-\r
-  //\r
-  // Report that the keyboard is being enabled\r
-  //\r
-  REPORT_STATUS_CODE (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE\r
-    );\r
-\r
-  //\r
-  // Setup the WaitForKey event\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_WAIT,\r
-                  TPL_NOTIFY,\r
-                  BiosKeyboardWaitForKey,\r
-                  &(BiosKeyboardPrivate->SimpleTextIn),\r
-                  &((BiosKeyboardPrivate->SimpleTextIn).WaitForKey)\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    (BiosKeyboardPrivate->SimpleTextIn).WaitForKey = NULL;\r
-    goto Done;\r
-  }\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_WAIT,\r
-                  TPL_NOTIFY,\r
-                  BiosKeyboardWaitForKeyEx,\r
-                  &(BiosKeyboardPrivate->SimpleTextInputEx),\r
-                  &(BiosKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx)\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    BiosKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx = NULL;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Setup a periodic timer, used for reading keystrokes at a fixed interval\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
-                  TPL_NOTIFY,\r
-                  BiosKeyboardTimerHandler,\r
-                  BiosKeyboardPrivate,\r
-                  &BiosKeyboardPrivate->TimerEvent\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    Status      = EFI_OUT_OF_RESOURCES;\r
-    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  Status = gBS->SetTimer (\r
-                  BiosKeyboardPrivate->TimerEvent,\r
-                  TimerPeriodic,\r
-                  KEYBOARD_TIMER_INTERVAL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    Status      = EFI_OUT_OF_RESOURCES;\r
-    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  KeyNotifyProcessHandler,\r
-                  BiosKeyboardPrivate,\r
-                  &BiosKeyboardPrivate->KeyNotifyProcessEvent\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    Status      = EFI_OUT_OF_RESOURCES;\r
-    StatusCode  = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;\r
-    goto Done;\r
-  }\r
-\r
-  //\r
-  // Report a Progress Code for an attempt to detect the precense of the keyboard device in the system\r
-  //\r
-  REPORT_STATUS_CODE (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT\r
-    );\r
-\r
-  //\r
-  // Reset the keyboard device\r
-  //\r
-  Status = BiosKeyboardPrivate->SimpleTextInputEx.Reset (\r
-                                                    &BiosKeyboardPrivate->SimpleTextInputEx,\r
-                                                    FeaturePcdGet (PcdPs2KbdExtendedVerification)\r
-                                                    );\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "[KBD]Reset Failed. Status - %r\n", Status));\r
-    StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;\r
-    goto Done;\r
-  }\r
-  //\r
-  // Do platform specific policy like port swapping and keyboard light default\r
-  //\r
-  if (Ps2Policy != NULL) {\r
-\r
-    Ps2Policy->Ps2InitHardware (Controller);\r
-\r
-    Command = 0;\r
-    if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_CAPSLOCK) == EFI_KEYBOARD_CAPSLOCK) {\r
-      Command |= 4;\r
-    }\r
-\r
-    if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_NUMLOCK) == EFI_KEYBOARD_NUMLOCK) {\r
-      Command |= 2;\r
-    }\r
-\r
-    if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_SCROLLLOCK) == EFI_KEYBOARD_SCROLLLOCK) {\r
-      Command |= 1;\r
-    }\r
-\r
-    KeyboardWrite (BiosKeyboardPrivate, 0xed);\r
-    KeyboardWaitForValue (BiosKeyboardPrivate, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT);\r
-    KeyboardWrite (BiosKeyboardPrivate, Command);\r
-    //\r
-    // Call Legacy BIOS Protocol to set whatever is necessary\r
-    //\r
-    LegacyBios->UpdateKeyboardLedStatus (LegacyBios, Command);\r
-  }\r
-  //\r
-  // Get Configuration\r
-  //\r
-  Regs.H.AH = 0xc0;\r
-  CarryFlag = BiosKeyboardPrivate->LegacyBios->Int86 (\r
-                                                 BiosKeyboardPrivate->LegacyBios,\r
-                                                 0x15,\r
-                                                 &Regs\r
-                                                 );\r
-\r
-  if (!CarryFlag) {\r
-    //\r
-    // Check bit 6 of Feature Byte 2.\r
-    // If it is set, then Int 16 Func 09 is supported\r
-    //\r
-    if (*(UINT8 *) (((UINTN) Regs.X.ES << 4) + Regs.X.BX + 0x06) & 0x40) {\r
-      //\r
-      // Get Keyboard Functionality\r
-      //\r
-      Regs.H.AH = 0x09;\r
-      CarryFlag = BiosKeyboardPrivate->LegacyBios->Int86 (\r
-                                                     BiosKeyboardPrivate->LegacyBios,\r
-                                                     0x16,\r
-                                                     &Regs\r
-                                                     );\r
-\r
-      if (!CarryFlag) {\r
-        //\r
-        // Check bit 5 of AH.\r
-        // If it is set, then INT 16 Finc 10-12 are supported.\r
-        //\r
-        if ((Regs.H.AL & 0x40) != 0) {\r
-          //\r
-          // Set the flag to use INT 16 Func 10-12\r
-          //\r
-          BiosKeyboardPrivate->ExtendedKeyboard = TRUE;\r
-        }\r
-      }\r
-    }\r
-  }\r
-  DEBUG ((EFI_D_INFO, "[KBD]Extended keystrokes supported by CSM16 - %02x\n", (UINTN)BiosKeyboardPrivate->ExtendedKeyboard));\r
-  //\r
-  // Install protocol interfaces for the keyboard device.\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &Controller,\r
-                  &gEfiSimpleTextInProtocolGuid,\r
-                  &BiosKeyboardPrivate->SimpleTextIn,\r
-                  &gEfiSimpleTextInputExProtocolGuid,\r
-                  &BiosKeyboardPrivate->SimpleTextInputEx,\r
-                  NULL\r
-                  );\r
-\r
-Done:\r
-  if (StatusCode != 0) {\r
-    //\r
-    // Report an Error Code for failing to start the keyboard device\r
-    //\r
-    REPORT_STATUS_CODE (\r
-      EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-      StatusCode\r
-      );\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-\r
-    if (BiosKeyboardPrivate != NULL) {\r
-      if ((BiosKeyboardPrivate->SimpleTextIn).WaitForKey != NULL) {\r
-        gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextIn).WaitForKey);\r
-      }\r
-\r
-      if ((BiosKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx != NULL) {\r
-        gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx);\r
-      }\r
-\r
-      if (BiosKeyboardPrivate->KeyNotifyProcessEvent != NULL) {\r
-        gBS->CloseEvent (BiosKeyboardPrivate->KeyNotifyProcessEvent);\r
-      }\r
-\r
-      BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate->NotifyList);\r
-\r
-      if (BiosKeyboardPrivate->TimerEvent != NULL) {\r
-        gBS->CloseEvent (BiosKeyboardPrivate->TimerEvent);\r
-      }\r
-\r
-      FreePool (BiosKeyboardPrivate);\r
-    }\r
-\r
-    if (IsaIo != NULL) {\r
-      gBS->CloseProtocol (\r
-             Controller,\r
-             &gEfiIsaIoProtocolGuid,\r
-             This->DriverBindingHandle,\r
-             Controller\r
-             );\r
-    }\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Stop the device handled by this driver.\r
-\r
-  @param  This                   The driver binding protocol.\r
-  @param  Controller             The controller to release.\r
-  @param  NumberOfChildren       The number of handles in ChildHandleBuffer.\r
-  @param  ChildHandleBuffer      The array of child handle.\r
-\r
-  @retval EFI_SUCCESS            The device was stopped.\r
-  @retval EFI_DEVICE_ERROR       The device could not be stopped due to a device error.\r
-  @retval Others                 Fail to uninstall protocols attached on the device.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardDriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL     *This,\r
-  IN  EFI_HANDLE                      Controller,\r
-  IN  UINTN                           NumberOfChildren,\r
-  IN  EFI_HANDLE                      *ChildHandleBuffer\r
-  )\r
-{\r
-  EFI_STATUS                     Status;\r
-  EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextIn;\r
-  BIOS_KEYBOARD_DEV              *BiosKeyboardPrivate;\r
-\r
-  //\r
-  // Disable Keyboard\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiSimpleTextInProtocolGuid,\r
-                  (VOID **) &SimpleTextIn,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiSimpleTextInputExProtocolGuid,\r
-                  NULL,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (SimpleTextIn);\r
-\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                  Controller,\r
-                  &gEfiSimpleTextInProtocolGuid,\r
-                  &BiosKeyboardPrivate->SimpleTextIn,\r
-                  &gEfiSimpleTextInputExProtocolGuid,\r
-                  &BiosKeyboardPrivate->SimpleTextInputEx,\r
-                  NULL\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  //\r
-  // Release the IsaIo protocol on the controller handle\r
-  //\r
-  gBS->CloseProtocol (\r
-         Controller,\r
-         &gEfiIsaIoProtocolGuid,\r
-         This->DriverBindingHandle,\r
-         Controller\r
-         );\r
-\r
-  //\r
-  // Free other resources\r
-  //\r
-  gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextIn).WaitForKey);\r
-  gBS->CloseEvent (BiosKeyboardPrivate->TimerEvent);\r
-  gBS->CloseEvent (BiosKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx);\r
-  gBS->CloseEvent (BiosKeyboardPrivate->KeyNotifyProcessEvent);\r
-  BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate->NotifyList);\r
-\r
-  FreePool (BiosKeyboardPrivate);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Read data byte from output buffer of Keyboard Controller without delay and waiting for buffer-empty state.\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-\r
-  @return  The data byte read from output buffer of Keyboard Controller from data port which often is port 60H.\r
-\r
-**/\r
-UINT8\r
-KeyReadDataRegister (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate\r
-  )\r
-{\r
-  UINT8 Data;\r
-\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  BiosKeyboardPrivate->IsaIo->Io.Read (\r
-                                   BiosKeyboardPrivate->IsaIo,\r
-                                   EfiIsaIoWidthUint8,\r
-                                   BiosKeyboardPrivate->DataRegisterAddress,\r
-                                   1,\r
-                                   &Data\r
-                                   );\r
-\r
-  return Data;\r
-}\r
-\r
-/**\r
-  Read status byte from status register of Keyboard Controller without delay and waiting for buffer-empty state.\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-\r
-  @return  The status byte read from status register of Keyboard Controller from command port which often is port 64H.\r
-\r
-**/\r
-UINT8\r
-KeyReadStatusRegister (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate\r
-  )\r
-{\r
-  UINT8 Data;\r
-\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  BiosKeyboardPrivate->IsaIo->Io.Read (\r
-                                   BiosKeyboardPrivate->IsaIo,\r
-                                   EfiIsaIoWidthUint8,\r
-                                   BiosKeyboardPrivate->StatusRegisterAddress,\r
-                                   1,\r
-                                   &Data\r
-                                   );\r
-\r
-  return Data;\r
-}\r
-\r
-/**\r
-  Write command byte to control register of Keyboard Controller without delay and waiting for buffer-empty state.\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-  @param   Data                 Data byte to write.\r
-\r
-**/\r
-VOID\r
-KeyWriteCommandRegister (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate,\r
-  IN UINT8              Data\r
-  )\r
-{\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  BiosKeyboardPrivate->IsaIo->Io.Write (\r
-                                   BiosKeyboardPrivate->IsaIo,\r
-                                   EfiIsaIoWidthUint8,\r
-                                   BiosKeyboardPrivate->CommandRegisterAddress,\r
-                                   1,\r
-                                   &Data\r
-                                   );\r
-}\r
-\r
-/**\r
-  Write data byte to input buffer or input/output ports of Keyboard Controller without delay and waiting for buffer-empty state.\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-  @param   Data                 Data byte to write.\r
-\r
-**/\r
-VOID\r
-KeyWriteDataRegister (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate,\r
-  IN UINT8              Data\r
-  )\r
-{\r
-  //\r
-  // Use IsaIo protocol to perform IO operations\r
-  //\r
-  BiosKeyboardPrivate->IsaIo->Io.Write (\r
-                                   BiosKeyboardPrivate->IsaIo,\r
-                                   EfiIsaIoWidthUint8,\r
-                                   BiosKeyboardPrivate->DataRegisterAddress,\r
-                                   1,\r
-                                   &Data\r
-                                   );\r
-}\r
-\r
-/**\r
-  Read data byte from output buffer of Keyboard Controller with delay and waiting for buffer-empty state.\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-  @param   Data                 The pointer for data that being read out.\r
-\r
-  @retval  EFI_SUCCESS          The data byte read out successfully.\r
-  @retval  EFI_TIMEOUT          Timeout occurred during reading out data byte.\r
-\r
-**/\r
-EFI_STATUS\r
-KeyboardRead (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate,\r
-  OUT UINT8             *Data\r
-  )\r
-{\r
-  UINT32  TimeOut;\r
-  UINT32  RegFilled;\r
-\r
-  TimeOut   = 0;\r
-  RegFilled = 0;\r
-\r
-  //\r
-  // wait till output buffer full then perform the read\r
-  //\r
-  for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_OUTB) != 0) {\r
-      RegFilled = 1;\r
-      *Data     = KeyReadDataRegister (BiosKeyboardPrivate);\r
-      break;\r
-    }\r
-\r
-    gBS->Stall (30);\r
-  }\r
-\r
-  if (RegFilled == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Write data byte to input buffer or input/output ports of Keyboard Controller with delay and waiting for buffer-empty state.\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-  @param   Data                 Data byte to write.\r
-\r
-  @retval  EFI_SUCCESS          The data byte is written successfully.\r
-  @retval  EFI_TIMEOUT          Timeout occurred during writing.\r
-\r
-**/\r
-EFI_STATUS\r
-KeyboardWrite (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate,\r
-  IN UINT8              Data\r
-  )\r
-{\r
-  UINT32  TimeOut;\r
-  UINT32  RegEmptied;\r
-\r
-  TimeOut     = 0;\r
-  RegEmptied  = 0;\r
-\r
-  //\r
-  // wait for input buffer empty\r
-  //\r
-  for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_INPB) == 0) {\r
-      RegEmptied = 1;\r
-      break;\r
-    }\r
-\r
-    gBS->Stall (30);\r
-  }\r
-\r
-  if (RegEmptied == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-  //\r
-  // Write it\r
-  //\r
-  KeyWriteDataRegister (BiosKeyboardPrivate, Data);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Write command byte to control register of Keyboard Controller with delay and waiting for buffer-empty state.\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-  @param   Data                 Command byte to write.\r
-\r
-  @retval  EFI_SUCCESS          The command byte is written successfully.\r
-  @retval  EFI_TIMEOUT          Timeout occurred during writing.\r
-\r
-**/\r
-EFI_STATUS\r
-KeyboardCommand (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate,\r
-  IN UINT8              Data\r
-  )\r
-{\r
-  UINT32  TimeOut;\r
-  UINT32  RegEmptied;\r
-\r
-  TimeOut     = 0;\r
-  RegEmptied  = 0;\r
-\r
-  //\r
-  // Wait For Input Buffer Empty\r
-  //\r
-  for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_INPB) == 0) {\r
-      RegEmptied = 1;\r
-      break;\r
-    }\r
-\r
-    gBS->Stall (30);\r
-  }\r
-\r
-  if (RegEmptied == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-  //\r
-  // issue the command\r
-  //\r
-  KeyWriteCommandRegister (BiosKeyboardPrivate, Data);\r
-\r
-  //\r
-  // Wait For Input Buffer Empty again\r
-  //\r
-  RegEmptied = 0;\r
-  for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-    if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_INPB) == 0) {\r
-      RegEmptied = 1;\r
-      break;\r
-    }\r
-\r
-    gBS->Stall (30);\r
-  }\r
-\r
-  if (RegEmptied == 0) {\r
-    return EFI_TIMEOUT;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Wait for a specific value to be presented in\r
-  Data register of Keyboard Controller by keyboard and then read it,\r
-  used in keyboard commands ack\r
-\r
-  @param   BiosKeyboardPrivate  Keyboard instance pointer.\r
-  @param   Value                The value to be waited for\r
-  @param   WaitForValueTimeOut  The limit of microseconds for timeout\r
-\r
-  @retval  EFI_SUCCESS          The command byte is written successfully.\r
-  @retval  EFI_TIMEOUT          Timeout occurred during writing.\r
-\r
-**/\r
-EFI_STATUS\r
-KeyboardWaitForValue (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate,\r
-  IN UINT8              Value,\r
-  IN UINTN              WaitForValueTimeOut\r
-  )\r
-{\r
-  UINT8   Data;\r
-  UINT32  TimeOut;\r
-  UINT32  SumTimeOut;\r
-  UINT32  GotIt;\r
-\r
-  GotIt       = 0;\r
-  TimeOut     = 0;\r
-  SumTimeOut  = 0;\r
-\r
-  //\r
-  // Make sure the initial value of 'Data' is different from 'Value'\r
-  //\r
-  Data = 0;\r
-  if (Data == Value) {\r
-    Data = 1;\r
-  }\r
-  //\r
-  // Read from 8042 (multiple times if needed)\r
-  // until the expected value appears\r
-  // use SumTimeOut to control the iteration\r
-  //\r
-  while (1) {\r
-    //\r
-    // Perform a read\r
-    //\r
-    for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {\r
-      if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_OUTB) != 0) {\r
-        Data = KeyReadDataRegister (BiosKeyboardPrivate);\r
-        break;\r
-      }\r
-\r
-      gBS->Stall (30);\r
-    }\r
-\r
-    SumTimeOut += TimeOut;\r
-\r
-    if (Data == Value) {\r
-      GotIt = 1;\r
-      break;\r
-    }\r
-\r
-    if (SumTimeOut >= WaitForValueTimeOut) {\r
-      break;\r
-    }\r
-  }\r
-  //\r
-  // Check results\r
-  //\r
-  if (GotIt != 0) {\r
-    return EFI_SUCCESS;\r
-  } else {\r
-    return EFI_TIMEOUT;\r
-  }\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
-\r
-  @param  BiosKeyboardPrivate   Bioskeyboard driver private structure.\r
-  @param  KeyData               A pointer to a buffer that is filled in with the keystroke\r
-                                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_DEVICE_ERROR      The keystroke information was not returned due to\r
-                                hardware errors.\r
-  @retval EFI_INVALID_PARAMETER KeyData is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-KeyboardReadKeyStrokeWorker (\r
-  IN BIOS_KEYBOARD_DEV  *BiosKeyboardPrivate,\r
-  OUT EFI_KEY_DATA      *KeyData\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_TPL                               OldTpl;\r
-  if (KeyData == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Use TimerEvent callback function to check whether there's any key pressed\r
-  //\r
-\r
-  //\r
-  // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.\r
-  // Csm will be used to check whether there is a key pending, but the csm will disable all\r
-  // interrupt before switch to compatibility16, which mean all the efiCompatibility timer\r
-  // event will stop work during the compatibility16. And If a caller recursivly invoke this function,\r
-  // e.g. OS loader, other drivers which are driven by timer event will have a bad performance during this period,\r
-  // e.g. usb keyboard driver.\r
-  // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.\r
-  // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.\r
-  //\r
-  gBS->Stall (1000);\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  BiosKeyboardTimerHandler (NULL, BiosKeyboardPrivate);\r
-  //\r
-  // If there's no key, just return\r
-  //\r
-  Status = CheckQueue (&BiosKeyboardPrivate->Queue);\r
-  if (EFI_ERROR (Status)) {\r
-    ZeroMem (&KeyData->Key, sizeof (KeyData->Key));\r
-    CopyMem (&KeyData->KeyState, &BiosKeyboardPrivate->KeyState, sizeof (EFI_KEY_STATE));\r
-    gBS->RestoreTPL (OldTpl);\r
-    return EFI_NOT_READY;\r
-  }\r
-\r
-  Status = Dequeue (&BiosKeyboardPrivate->Queue, KeyData);\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// EFI Simple Text In Protocol Functions\r
-//\r
-/**\r
-  Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.\r
-\r
-  @param  This                  Pointer of simple text Protocol.\r
-  @param  ExtendedVerification  Whether perform the extra validation of keyboard. True: perform; FALSE: skip.\r
-\r
-  @retval EFI_SUCCESS           The command byte is written successfully.\r
-  @retval EFI_DEVICE_ERROR      Errors occurred during resetting keyboard.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardReset (\r
-  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,\r
-  IN  BOOLEAN                         ExtendedVerification\r
-  )\r
-{\r
-  BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;\r
-  EFI_STATUS        Status;\r
-  EFI_TPL           OldTpl;\r
-  UINT8             CommandByte;\r
-  BOOLEAN           MouseEnable;\r
-  EFI_INPUT_KEY     Key;\r
-\r
-  MouseEnable         = FALSE;\r
-  BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // 1\r
-  // Report reset progress code\r
-  //\r
-  REPORT_STATUS_CODE (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET\r
-    );\r
-\r
-  //\r
-  // Report a Progress Code for clearing the keyboard buffer\r
-  //\r
-  REPORT_STATUS_CODE (\r
-    EFI_PROGRESS_CODE,\r
-    EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER\r
-    );\r
-\r
-  //\r
-  // 2\r
-  // Raise TPL to avoid mouse operation impact\r
-  //\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  //\r
-  //\r
-  // Exhaust output buffer data\r
-  //\r
-  do {\r
-    Status = BiosKeyboardReadKeyStroke (\r
-               This,\r
-               &Key\r
-               );\r
-  } while (!EFI_ERROR (Status));\r
-  //\r
-  // 3\r
-  // check for KBC itself firstly for setted-up already or not by reading SYSF (bit2) of status register via 64H\r
-  // if not skip step 4&5 and jump to step 6 to selftest KBC and report this\r
-  // else   go step 4\r
-  //\r
-  if (!PcdGetBool (PcdFastPS2Detection)) {\r
-    if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_SYSF) != 0) {\r
-      //\r
-      // 4\r
-      // CheckMouseStatus to decide enable it later or not\r
-      //\r
-      //\r
-      // Read the command byte of KBC\r
-      //\r
-      Status = KeyboardCommand (\r
-                 BiosKeyboardPrivate,\r
-                 KBC_CMDREG_VIA64_CMDBYTE_R\r
-                 );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        Status    = EFI_DEVICE_ERROR;\r
-        goto Exit;\r
-      }\r
-\r
-      Status = KeyboardRead (\r
-                 BiosKeyboardPrivate,\r
-                 &CommandByte\r
-                 );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        Status    = EFI_DEVICE_ERROR;\r
-        goto Exit;\r
-      }\r
-      //\r
-      // Check mouse enabled or not before\r
-      //\r
-      if ((CommandByte & KB_CMMBYTE_DISABLE_AUX) != 0) {\r
-        MouseEnable = FALSE;\r
-      } else {\r
-        MouseEnable = TRUE;\r
-      }\r
-      //\r
-      // 5\r
-      // disable mouse (via KBC) and Keyborad device\r
-      //\r
-      Status = KeyboardCommand (\r
-                 BiosKeyboardPrivate,\r
-                 KBC_CMDREG_VIA64_AUX_DISABLE\r
-                 );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        Status    = EFI_DEVICE_ERROR;\r
-        goto Exit;\r
-      }\r
-\r
-      Status = KeyboardCommand (\r
-                 BiosKeyboardPrivate,\r
-                 KBC_CMDREG_VIA64_KB_DISABLE\r
-                 );\r
-\r
-      if (EFI_ERROR (Status)) {\r
-        Status    = EFI_DEVICE_ERROR;\r
-        goto Exit;\r
-      }\r
-    } else {\r
-      //\r
-      // 6\r
-      // KBC Self Test\r
-      //\r
-      //\r
-      // Report a Progress Code for performing a self test on the keyboard controller\r
-      //\r
-      REPORT_STATUS_CODE (\r
-        EFI_PROGRESS_CODE,\r
-        EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST\r
-        );\r
-\r
-      Status = KeyboardCommand (\r
-                 BiosKeyboardPrivate,\r
-                 KBC_CMDREG_VIA64_KBC_SLFTEST\r
-                 );\r
-      if (EFI_ERROR (Status)) {\r
-        Status    = EFI_DEVICE_ERROR;\r
-        goto Exit;\r
-      }\r
-\r
-      Status = KeyboardWaitForValue (\r
-                 BiosKeyboardPrivate,\r
-                 KBC_CMDECHO_KBCSLFTEST_OK,\r
-                 KEYBOARD_WAITFORVALUE_TIMEOUT\r
-                 );\r
-      if (EFI_ERROR (Status)) {\r
-        Status    = EFI_DEVICE_ERROR;\r
-        goto Exit;\r
-      }\r
-    }\r
-  }\r
-  //\r
-  // 7\r
-  // Disable  Mouse interface, enable  Keyboard interface and declare selftest success\r
-  //\r
-  // Mouse device will block keyboard interface before it be configured, so we should disable mouse first.\r
-  //\r
-  Status = KeyboardCommand (\r
-             BiosKeyboardPrivate,\r
-             KBC_CMDREG_VIA64_CMDBYTE_W\r
-             );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    Status    = EFI_DEVICE_ERROR;\r
-    goto Exit;\r
-  }\r
-\r
-  //\r
-  // Write 8042 Command Byte, set System Flag\r
-  // While at the same time:\r
-  //  1. disable mouse interface,\r
-  //  2. enable kbd interface,\r
-  //  3. enable PC/XT kbd translation mode\r
-  //  4. enable mouse and kbd interrupts\r
-  //\r
-  //Command Byte bits:\r
-  //  7: Reserved\r
-  //  6: PC/XT translation mode\r
-  //  5: Disable Auxiliary device interface\r
-  //  4: Disable keyboard interface\r
-  //  3: Reserved\r
-  //  2: System Flag\r
-  //  1: Enable Auxiliary device interrupt\r
-  //  0: Enable Keyboard interrupt\r
-  //\r
-  CommandByte = 0;\r
-  Status = KeyboardWrite (\r
-             BiosKeyboardPrivate,\r
-             (UINT8) ((CommandByte &\r
-              (~KB_CMMBYTE_DISABLE_KB)) |\r
-              KB_CMMBYTE_KSCAN2UNI_COV |\r
-              KB_CMMBYTE_ENABLE_AUXINT |\r
-              KB_CMMBYTE_ENABLE_KBINT  |\r
-              KB_CMMBYTE_SLFTEST_SUCC  |\r
-              KB_CMMBYTE_DISABLE_AUX)\r
-             );\r
-\r
-  //\r
-  // For resetting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,\r
-  // so we only do the real resetting for keyboard when user asks, and normally during booting an OS, it's skipped.\r
-  // Call CheckKeyboardConnect() to check whether keyboard is connected, if it is not connected,\r
-  // Real reset will not do.\r
-  //\r
-  if (ExtendedVerification && CheckKeyboardConnect (BiosKeyboardPrivate)) {\r
-    //\r
-    // 8\r
-    // Send keyboard reset command then read ACK\r
-    //\r
-    Status = KeyboardWrite (\r
-               BiosKeyboardPrivate,\r
-               KBC_INPBUF_VIA60_KBRESET\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_ACK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-    //\r
-    // 9\r
-    // Wait for keyboard return test OK.\r
-    //\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_BATTEST_OK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-    //\r
-    // 10\r
-    // set keyboard scan code set = 02 (standard configuration)\r
-    //\r
-    Status = KeyboardWrite (\r
-               BiosKeyboardPrivate,\r
-               KBC_INPBUF_VIA60_KBSCODE\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_ACK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardWrite (\r
-               BiosKeyboardPrivate,\r
-               KBC_INPBUF_VIA60_SCODESET2\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_ACK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-    //\r
-    // 11\r
-    // enable keyboard itself (not via KBC) by writing CMD F4 via 60H\r
-    //\r
-    Status = KeyboardWrite (\r
-               BiosKeyboardPrivate,\r
-               KBC_INPBUF_VIA60_KBEN\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_ACK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-    //\r
-    // 12\r
-    // Additional validation, do it as follow:\r
-    // 1). check for status register of PARE && TIM via 64H\r
-    // 2). perform KB checking by writing ABh via 64H\r
-    //\r
-    if ((KeyReadStatusRegister (BiosKeyboardPrivate) & (KBC_STSREG_VIA64_PARE | KBC_STSREG_VIA64_TIM)) != 0) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardCommand (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDREG_VIA64_KB_CKECK\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_KBCHECK_OK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-  }\r
-  //\r
-  // 13\r
-  // Done for validating keyboard. Enable keyboard (via KBC)\r
-  // and recover the command byte to proper value\r
-  //\r
-  if (!PcdGetBool (PcdFastPS2Detection)) {\r
-    Status = KeyboardCommand (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDREG_VIA64_KB_ENABLE\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-      goto Exit;\r
-    }\r
-  }\r
-\r
-  //\r
-  // 14\r
-  // conditionally enable mouse (via KBC)\r
-  //\r
-  if (MouseEnable) {\r
-    Status = KeyboardCommand (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDREG_VIA64_AUX_ENABLE\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      Status    = EFI_DEVICE_ERROR;\r
-\r
-    }\r
-  }\r
-\r
-Exit:\r
-  //\r
-  // 15\r
-  // resume priority of task level\r
-  //\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
-\r
-}\r
-\r
-/**\r
-  Read out the scan code of the key that has just been stroked.\r
-\r
-  @param  This        Pointer of simple text Protocol.\r
-  @param  Key         Pointer for store the key that read out.\r
-\r
-  @retval EFI_SUCCESS The key is read out successfully.\r
-  @retval other       The key reading failed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardReadKeyStroke (\r
-  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,\r
-  OUT EFI_INPUT_KEY                   *Key\r
-  )\r
-{\r
-  BIOS_KEYBOARD_DEV     *BiosKeyboardPrivate;\r
-  EFI_STATUS            Status;\r
-  EFI_KEY_DATA          KeyData;\r
-\r
-  BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-\r
-  Status = KeyboardReadKeyStrokeWorker (BiosKeyboardPrivate, &KeyData);\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  //\r
-  // Convert the Ctrl+[a-z] to Ctrl+[1-26]\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
-    }\r
-  }\r
-\r
-  CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Waiting on the keyboard event, if there's any key pressed by the user, signal the event\r
-\r
-  @param  Event       The event that be siganlled when any key has been stroked.\r
-  @param  Context     Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BiosKeyboardWaitForKey (\r
-  IN  EFI_EVENT  Event,\r
-  IN  VOID       *Context\r
-  )\r
-{\r
-  //\r
-  // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.\r
-  // Csm will be used to check whether there is a key pending, but the csm will disable all\r
-  // interrupt before switch to compatibility16, which mean all the efiCompatibility timer\r
-  // event will stop work during the compatibility16. And If a caller recursivly invoke this function,\r
-  // e.g. UI setup or Shell, other drivers which are driven by timer event will have a bad performance during this period,\r
-  // e.g. usb keyboard driver.\r
-  // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.\r
-  // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.\r
-  //\r
-  gBS->Stall (1000);\r
-  //\r
-  // Use TimerEvent callback function to check whether there's any key pressed\r
-  //\r
-  BiosKeyboardTimerHandler (NULL, BIOS_KEYBOARD_DEV_FROM_THIS (Context));\r
-\r
-  if (!EFI_ERROR (BiosKeyboardCheckForKey (Context))) {\r
-    gBS->SignalEvent (Event);\r
-  }\r
-}\r
-\r
-/**\r
-  Check key buffer to get the key stroke status.\r
-\r
-  @param  This         Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL.\r
-\r
-  @retval EFI_SUCCESS  A key is being pressed now.\r
-  @retval Other        No key is now pressed.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardCheckForKey (\r
-  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This\r
-  )\r
-{\r
-  BIOS_KEYBOARD_DEV     *BiosKeyboardPrivate;\r
-\r
-  BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-\r
-  return CheckQueue (&BiosKeyboardPrivate->Queue);\r
-}\r
-//\r
-// Private worker functions\r
-//\r
-#define TABLE_END 0x0\r
-\r
-typedef struct _CONVERT_TABLE_ENTRY {\r
-  UINT16  ScanCode;\r
-  UINT16  EfiScanCode;\r
-} CONVERT_TABLE_ENTRY;\r
-\r
-CONVERT_TABLE_ENTRY mConvertTable[] = {\r
-  {\r
-    0x47,\r
-    SCAN_HOME\r
-  },\r
-  {\r
-    0x48,\r
-    SCAN_UP\r
-  },\r
-  {\r
-    0x49,\r
-    SCAN_PAGE_UP\r
-  },\r
-  {\r
-    0x4b,\r
-    SCAN_LEFT\r
-  },\r
-  {\r
-    0x4d,\r
-    SCAN_RIGHT\r
-  },\r
-  {\r
-    0x4f,\r
-    SCAN_END\r
-  },\r
-  {\r
-    0x50,\r
-    SCAN_DOWN\r
-  },\r
-  {\r
-    0x51,\r
-    SCAN_PAGE_DOWN\r
-  },\r
-  {\r
-    0x52,\r
-    SCAN_INSERT\r
-  },\r
-  {\r
-    0x53,\r
-    SCAN_DELETE\r
-  },\r
-  //\r
-  // Function Keys are only valid if KeyChar == 0x00\r
-  //  This function does not require KeyChar to be 0x00\r
-  //\r
-  {\r
-    0x3b,\r
-    SCAN_F1\r
-  },\r
-  {\r
-    0x3c,\r
-    SCAN_F2\r
-  },\r
-  {\r
-    0x3d,\r
-    SCAN_F3\r
-  },\r
-  {\r
-    0x3e,\r
-    SCAN_F4\r
-  },\r
-  {\r
-    0x3f,\r
-    SCAN_F5\r
-  },\r
-  {\r
-    0x40,\r
-    SCAN_F6\r
-  },\r
-  {\r
-    0x41,\r
-    SCAN_F7\r
-  },\r
-  {\r
-    0x42,\r
-    SCAN_F8\r
-  },\r
-  {\r
-    0x43,\r
-    SCAN_F9\r
-  },\r
-  {\r
-    0x44,\r
-    SCAN_F10\r
-  },\r
-  {\r
-    0x85,\r
-    SCAN_F11\r
-  },\r
-  {\r
-    0x86,\r
-    SCAN_F12\r
-  },\r
-  //\r
-  // Convert ALT + Fn keys\r
-  //\r
-  {\r
-    0x68,\r
-    SCAN_F1\r
-  },\r
-  {\r
-    0x69,\r
-    SCAN_F2\r
-  },\r
-  {\r
-    0x6a,\r
-    SCAN_F3\r
-  },\r
-  {\r
-    0x6b,\r
-    SCAN_F4\r
-  },\r
-  {\r
-    0x6c,\r
-    SCAN_F5\r
-  },\r
-  {\r
-    0x6d,\r
-    SCAN_F6\r
-  },\r
-  {\r
-    0x6e,\r
-    SCAN_F7\r
-  },\r
-  {\r
-    0x6f,\r
-    SCAN_F8\r
-  },\r
-  {\r
-    0x70,\r
-    SCAN_F9\r
-  },\r
-  {\r
-    0x71,\r
-    SCAN_F10\r
-  },\r
-  {\r
-    TABLE_END,\r
-    SCAN_NULL\r
-  },\r
-};\r
-\r
-/**\r
-  Convert unicode combined with scan code of key to the counterpart of EFIScancode of it.\r
-\r
-  @param  KeyChar      Unicode of key.\r
-  @param  ScanCode     Scan code of key.\r
-\r
-  @return The value of EFI Scancode for the key.\r
-  @retval SCAN_NULL   No corresponding value in the EFI convert table is found for the key.\r
-\r
-**/\r
-UINT16\r
-ConvertToEFIScanCode (\r
-  IN  CHAR16  KeyChar,\r
-  IN  UINT16  ScanCode\r
-  )\r
-{\r
-  UINT16  EfiScanCode;\r
-  UINT16  Index;\r
-\r
-  if (KeyChar == CHAR_ESC) {\r
-    EfiScanCode = SCAN_ESC;\r
-  } else if (KeyChar == 0x00 || KeyChar == 0xe0) {\r
-    //\r
-    // Movement & Function Keys\r
-    //\r
-    for (Index = 0; (Index < sizeof (mConvertTable) / sizeof (CONVERT_TABLE_ENTRY)) && (mConvertTable[Index].ScanCode != TABLE_END); Index += 1) {\r
-      if (ScanCode == mConvertTable[Index].ScanCode) {\r
-        return mConvertTable[Index].EfiScanCode;\r
-      }\r
-    }\r
-    //\r
-    // Reach Table end, return default value\r
-    //\r
-    return SCAN_NULL;\r
-  } else {\r
-    return SCAN_NULL;\r
-  }\r
-\r
-  return EfiScanCode;\r
-}\r
-\r
-/**\r
-  Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command\r
-  If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device\r
-  should not be in system.\r
-\r
-  @param  BiosKeyboardPrivate  Keyboard Private Data Struture\r
-\r
-  @retval TRUE  Keyboard in System.\r
-  @retval FALSE Keyboard not in System.\r
-\r
-**/\r
-BOOLEAN\r
-CheckKeyboardConnect (\r
-  IN  BIOS_KEYBOARD_DEV     *BiosKeyboardPrivate\r
-  )\r
-{\r
-  EFI_STATUS     Status;\r
-\r
-  Status         = EFI_SUCCESS;\r
-  //\r
-  // enable keyboard itself and wait for its ack\r
-  // If can't receive ack, Keyboard should not be connected.\r
-  //\r
-  if (!PcdGetBool (PcdFastPS2Detection)) {\r
-    Status = KeyboardWrite (\r
-               BiosKeyboardPrivate,\r
-               KBC_INPBUF_VIA60_KBEN\r
-               );\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Keyboard enable failed!\n"));\r
-      REPORT_STATUS_CODE (\r
-        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-        EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR\r
-        );\r
-      return FALSE;\r
-    }\r
-\r
-    Status = KeyboardWaitForValue (\r
-               BiosKeyboardPrivate,\r
-               KBC_CMDECHO_ACK,\r
-               KEYBOARD_WAITFORVALUE_TIMEOUT\r
-               );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_ERROR, "[KBD]CheckKeyboardConnect - Timeout!\n"));\r
-      REPORT_STATUS_CODE (\r
-        EFI_ERROR_CODE | EFI_ERROR_MINOR,\r
-        EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR\r
-        );\r
-      return FALSE;\r
-    }\r
-    return TRUE;\r
-  } else {\r
-    return TRUE;\r
-  }\r
-}\r
-\r
-/**\r
-  Timer event handler: read a series of key stroke from 8042\r
-  and put them into memory key buffer.\r
-  It is registered as running under TPL_NOTIFY\r
-\r
-  @param  Event   The timer event\r
-  @param  Context A BIOS_KEYBOARD_DEV pointer\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BiosKeyboardTimerHandler (\r
-  IN EFI_EVENT    Event,\r
-  IN VOID         *Context\r
-  )\r
-{\r
-  EFI_TPL                            OldTpl;\r
-  BIOS_KEYBOARD_DEV                  *BiosKeyboardPrivate;\r
-  EFI_IA32_REGISTER_SET              Regs;\r
-  UINT8                              KbFlag1;  // 0040h:0017h - KEYBOARD - STATUS FLAGS 1\r
-  UINT8                              KbFlag2;  // 0040h:0018h - KEYBOARD - STATUS FLAGS 2\r
-  EFI_KEY_DATA                       KeyData;\r
-  LIST_ENTRY                         *Link;\r
-  BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;\r
-\r
-  BiosKeyboardPrivate = Context;\r
-\r
-  //\r
-  // Enter critical section\r
-  //\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  //\r
-  // if there is no key present, just return\r
-  //\r
-  if (BiosKeyboardPrivate->ExtendedKeyboard) {\r
-    Regs.H.AH = 0x11;\r
-  } else {\r
-    Regs.H.AH = 0x01;\r
-  }\r
-\r
-  BiosKeyboardPrivate->LegacyBios->Int86 (\r
-                                     BiosKeyboardPrivate->LegacyBios,\r
-                                     0x16,\r
-                                     &Regs\r
-                                     );\r
-  if (Regs.X.Flags.ZF != 0) {\r
-    gBS->RestoreTPL (OldTpl);\r
-    return;\r
-  }\r
-\r
-  //\r
-  // Read the key\r
-  //\r
-  if (BiosKeyboardPrivate->ExtendedKeyboard) {\r
-    Regs.H.AH = 0x10;\r
-  } else {\r
-    Regs.H.AH = 0x00;\r
-  }\r
-\r
-  BiosKeyboardPrivate->LegacyBios->Int86 (\r
-                                     BiosKeyboardPrivate->LegacyBios,\r
-                                     0x16,\r
-                                     &Regs\r
-                                     );\r
-\r
-  KeyData.Key.ScanCode            = (UINT16) Regs.H.AH;\r
-  KeyData.Key.UnicodeChar         = (UINT16) Regs.H.AL;\r
-  DEBUG ((\r
-    EFI_D_INFO,\r
-    "[KBD]INT16 returns EFI_INPUT_KEY.ScanCode - %x, EFI_INPUT_KEY.UnicodeChar - %x\n",\r
-    KeyData.Key.ScanCode,\r
-    KeyData.Key.UnicodeChar\r
-    ));\r
-\r
-  KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;\r
-  KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;\r
-  //\r
-  // Leagcy Bios use Int 9 which is IRQ1 interrupt handler to get keystroke scancode to KB  buffer in BDA (BIOS DATE AREA),  then\r
-  // Int 16 depend  KB buffer and some key bits in BDA to translate the scancode to ASCII code, and  return both the scancode and ASCII\r
-  // code to Int 16 caller. This translation process works well if the Int 9  could response user input in time. But in Tiano enviorment,  the Int 9\r
-  // will be disabled after the thunk call finish, which means if user crazy input during int 9 being disabled, some keystrokes will be lost when\r
-  // KB device own hardware buffer overflows. And if the lost keystroke code is CTRL or ALT or SHIFT release code, these function key flags bit\r
-  // in BDA will not be updated. So the Int 16 will believe the CTRL or ALT or SHIFT is still pressed, and Int 16 will translate later scancode\r
-  // to wrong ASCII code. We can increase the Thunk frequence to let Int 9 response in time, but this way will much hurt other drivers\r
-  // performance, like USB.\r
-  //\r
-  // 1. If CTRL or ALT release code is missed,  all later input keys will be translated to wrong ASCII codes which the Tiano cannot support. In\r
-  //     this case, the KB input seems fail to work, and user input is blocked. To solve the problem, we can help to clear the CTRL or ALT flag in BDA\r
-  //    after every Int 16 finish. Thus persist to press CTRL or ALT has same effection as only press one time. It is Ok, since user not often use the\r
-  //    CTRL and ALT.\r
-  //\r
-  // 2. If SHIFT release code is missed, all later lowercase input will become capital. This is ugly, but not block user input. If user press the lost\r
-  //     SHIFT again,  the lowercase will come back to normal. Since user often use the SHIFT, it is not reasonable to help to clear the SHIFT flag in BDA,\r
-  //     which will let persist to press SHIFT has same effection as only press one time.\r
-  //\r
-  //0040h:0017h - KEYBOARD - STATUS FLAGS 1\r
-  //   7 INSert active\r
-  //   6 Caps Lock active\r
-  //   5 Num Lock active\r
-  //   4 Scroll Lock active\r
-  //   3 either Alt pressed\r
-  //   2 either Ctrl pressed\r
-  //   1 Left Shift pressed\r
-  //   0 Right Shift pressed\r
-\r
-\r
-  //\r
-  // Clear the CTRL and ALT BDA flag\r
-  //\r
-  ACCESS_PAGE0_CODE (\r
-    KbFlag1 = *((UINT8 *) (UINTN) 0x417); // read the STATUS FLAGS 1\r
-    KbFlag2 = *((UINT8 *) (UINTN) 0x418); // read STATUS FLAGS 2\r
-  );\r
-\r
-  DEBUG_CODE (\r
-    {\r
-      if ((KbFlag1 & KB_CAPS_LOCK_BIT) == KB_CAPS_LOCK_BIT) {\r
-        DEBUG ((EFI_D_INFO, "[KBD]Caps Lock Key is pressed.\n"));\r
-      }\r
-      if ((KbFlag1 & KB_NUM_LOCK_BIT) == KB_NUM_LOCK_BIT) {\r
-        DEBUG ((EFI_D_INFO, "[KBD]Num Lock Key is pressed.\n"));\r
-      }\r
-      if ((KbFlag1 & KB_SCROLL_LOCK_BIT) == KB_SCROLL_LOCK_BIT) {\r
-        DEBUG ((EFI_D_INFO, "[KBD]Scroll Lock Key is pressed.\n"));\r
-      }\r
-      if ((KbFlag1 & KB_ALT_PRESSED) == KB_ALT_PRESSED) {\r
-        if ((KbFlag2 & KB_LEFT_ALT_PRESSED) == KB_LEFT_ALT_PRESSED) {\r
-          DEBUG ((EFI_D_INFO, "[KBD]Left Alt Key is pressed.\n"));\r
-        } else {\r
-          DEBUG ((EFI_D_INFO, "[KBD]Right Alt Key is pressed.\n"));\r
-        }\r
-      }\r
-      if ((KbFlag1 & KB_CTRL_PRESSED) == KB_CTRL_PRESSED) {\r
-        if ((KbFlag2 & KB_LEFT_CTRL_PRESSED) == KB_LEFT_CTRL_PRESSED) {\r
-          DEBUG ((EFI_D_INFO, "[KBD]Left Ctrl Key is pressed.\n"));\r
-        } else {\r
-          DEBUG ((EFI_D_INFO, "[KBD]Right Ctrl Key is pressed.\n"));\r
-        }\r
-      }\r
-      if ((KbFlag1 & KB_LEFT_SHIFT_PRESSED) == KB_LEFT_SHIFT_PRESSED) {\r
-        DEBUG ((EFI_D_INFO, "[KBD]Left Shift Key is pressed.\n"));\r
-      }\r
-      if ((KbFlag1 & KB_RIGHT_SHIFT_PRESSED) == KB_RIGHT_SHIFT_PRESSED) {\r
-        DEBUG ((EFI_D_INFO, "[KBD]Right Shift Key is pressed.\n"));\r
-      }\r
-    }\r
-  );\r
-\r
-  //\r
-  // Record toggle state\r
-  //\r
-  if ((KbFlag1 & KB_CAPS_LOCK_BIT) == KB_CAPS_LOCK_BIT) {\r
-    KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;\r
-  }\r
-  if ((KbFlag1 & KB_NUM_LOCK_BIT) == KB_NUM_LOCK_BIT) {\r
-    KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;\r
-  }\r
-  if ((KbFlag1 & KB_SCROLL_LOCK_BIT) == KB_SCROLL_LOCK_BIT) {\r
-    KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;\r
-  }\r
-  //\r
-  // Record shift state\r
-  // BUGBUG: Need add Menu key and Left/Right Logo key state in the future\r
-  //\r
-  if ((KbFlag1 & KB_ALT_PRESSED) == KB_ALT_PRESSED) {\r
-    KeyData.KeyState.KeyShiftState  |= ((KbFlag2 & KB_LEFT_ALT_PRESSED) == KB_LEFT_ALT_PRESSED) ? EFI_LEFT_ALT_PRESSED : EFI_RIGHT_ALT_PRESSED;\r
-  }\r
-  if ((KbFlag1 & KB_CTRL_PRESSED) == KB_CTRL_PRESSED) {\r
-    KeyData.KeyState.KeyShiftState  |= ((KbFlag2 & KB_LEFT_CTRL_PRESSED) == KB_LEFT_CTRL_PRESSED) ? EFI_LEFT_CONTROL_PRESSED : EFI_RIGHT_CONTROL_PRESSED;\r
-  }\r
-  if ((KbFlag1 & KB_LEFT_SHIFT_PRESSED) == KB_LEFT_SHIFT_PRESSED) {\r
-    KeyData.KeyState.KeyShiftState  |= EFI_LEFT_SHIFT_PRESSED;\r
-  }\r
-  if ((KbFlag1 & KB_RIGHT_SHIFT_PRESSED) == KB_RIGHT_SHIFT_PRESSED) {\r
-    KeyData.KeyState.KeyShiftState  |= EFI_RIGHT_SHIFT_PRESSED;\r
-  }\r
-\r
-  //\r
-  // Clear left alt and left ctrl BDA flag\r
-  //\r
-  ACCESS_PAGE0_CODE (\r
-    KbFlag2 &= ~(KB_LEFT_ALT_PRESSED | KB_LEFT_CTRL_PRESSED);\r
-    *((UINT8 *) (UINTN) 0x418) = KbFlag2;\r
-    KbFlag1 &= ~0x0C;\r
-    *((UINT8 *) (UINTN) 0x417) = KbFlag1;\r
-  );\r
-\r
-  //\r
-  // Output EFI input key and shift/toggle state\r
-  //\r
-  if (KeyData.Key.UnicodeChar == CHAR_NULL || KeyData.Key.UnicodeChar == CHAR_SCANCODE || KeyData.Key.UnicodeChar == CHAR_ESC) {\r
-    KeyData.Key.ScanCode     = ConvertToEFIScanCode (KeyData.Key.UnicodeChar, KeyData.Key.ScanCode);\r
-    KeyData.Key.UnicodeChar  = CHAR_NULL;\r
-  } else {\r
-    KeyData.Key.ScanCode     = SCAN_NULL;\r
-  }\r
-\r
-  //\r
-  // CSM16 has converted the Ctrl+[a-z] to [1-26], converted it back.\r
-  //\r
-  if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {\r
-    if (KeyData.Key.UnicodeChar >= 1 && KeyData.Key.UnicodeChar <= 26) {\r
-      if (((KeyData.KeyState.KeyShiftState & (EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)) != 0) ==\r
-          ((KeyData.KeyState.KeyToggleState & EFI_CAPS_LOCK_ACTIVE) != 0)\r
-          ) {\r
-        KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar + L'a' - 1);\r
-      } else {\r
-        KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar + L'A' - 1);\r
-      }\r
-    }\r
-  }\r
-\r
-  DEBUG ((\r
-    EFI_D_INFO,\r
-    "[KBD]Convert to EFI Scan Code, EFI_INPUT_KEY.ScanCode - %x, EFI_INPUT_KEY.UnicodeChar - %x\n",\r
-    KeyData.Key.ScanCode,\r
-    KeyData.Key.UnicodeChar\r
-    ));\r
-\r
-  //\r
-  // Need not return associated shift state if a class of printable characters that\r
-  // are normally adjusted by shift modifiers.\r
-  // e.g. Shift Key + 'f' key = 'F'; Shift Key + 'F' key = 'f'.\r
-  //\r
-  if ((KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') ||\r
-      (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z')\r
-     ) {\r
-    DEBUG ((EFI_D_INFO, "[KBD]Shift key with a~z are pressed, remove shift state in EFI_KEY_STATE.\n"));\r
-    KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);\r
-  }\r
-\r
-  //\r
-  // Signal KeyNotify process event if this key pressed matches any key registered.\r
-  //\r
-  for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {\r
-    CurrentNotify = CR (\r
-                      Link,\r
-                      BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
-                      NotifyEntry,\r
-                      BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
-                      );\r
-    if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
-      //\r
-      // The key notification function needs to run at TPL_CALLBACK\r
-      // while current TPL is TPL_NOTIFY. It will be invoked in\r
-      // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.\r
-      //\r
-      Enqueue (&BiosKeyboardPrivate->QueueForNotify, &KeyData);\r
-      gBS->SignalEvent (BiosKeyboardPrivate->KeyNotifyProcessEvent);\r
-      break;\r
-    }\r
-  }\r
-\r
-  Enqueue (&BiosKeyboardPrivate->Queue, &KeyData);\r
-\r
-  //\r
-  // Save the current key state\r
-  //\r
-  CopyMem (&BiosKeyboardPrivate->KeyState, &KeyData.KeyState, sizeof (EFI_KEY_STATE));\r
-\r
-  //\r
-  // Leave critical section and return\r
-  //\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return ;\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
-  BIOS_KEYBOARD_DEV                     *BiosKeyboardPrivate;\r
-  EFI_KEY_DATA                          KeyData;\r
-  LIST_ENTRY                            *Link;\r
-  LIST_ENTRY                            *NotifyList;\r
-  BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *CurrentNotify;\r
-  EFI_TPL                               OldTpl;\r
-\r
-  BiosKeyboardPrivate = (BIOS_KEYBOARD_DEV *) Context;\r
-\r
-  //\r
-  // Invoke notification functions.\r
-  //\r
-  NotifyList = &BiosKeyboardPrivate->NotifyList;\r
-  while (TRUE) {\r
-    //\r
-    // Enter critical section\r
-    //\r
-    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-    Status = Dequeue (&BiosKeyboardPrivate->QueueForNotify, &KeyData);\r
-    //\r
-    // Leave critical section\r
-    //\r
-    gBS->RestoreTPL (OldTpl);\r
-    if (EFI_ERROR (Status)) {\r
-      break;\r
-    }\r
-    for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {\r
-      CurrentNotify = CR (Link, BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);\r
-      if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {\r
-        CurrentNotify->KeyNotificationFn (&KeyData);\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-/**\r
-  Free keyboard notify list.\r
-\r
-  @param  ListHead   The list head\r
-\r
-  @retval EFI_SUCCESS           Free the notify list successfully\r
-  @retval EFI_INVALID_PARAMETER ListHead is invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-BiosKeyboardFreeNotifyList (\r
-  IN OUT LIST_ENTRY           *ListHead\r
-  )\r
-{\r
-  BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
-\r
-  if (ListHead == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  while (!IsListEmpty (ListHead)) {\r
-    NotifyNode = CR (\r
-                   ListHead->ForwardLink,\r
-                   BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
-                   NotifyEntry,\r
-                   BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
-                   );\r
-    RemoveEntryList (ListHead->ForwardLink);\r
-    gBS->FreePool (NotifyNode);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  Check if key is registered.\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
-  @param  InputData         A pointer to a buffer that is filled in with the keystroke\r
-                            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
-\r
-**/\r
-BOOLEAN\r
-IsKeyRegistered (\r
-  IN EFI_KEY_DATA  *RegsiteredData,\r
-  IN EFI_KEY_DATA  *InputData\r
-  )\r
-{\r
-  ASSERT (RegsiteredData != NULL && InputData != NULL);\r
-\r
-  if ((RegsiteredData->Key.ScanCode    != InputData->Key.ScanCode) ||\r
-      (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {\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
-    return FALSE;\r
-  }\r
-  if (RegsiteredData->KeyState.KeyToggleState != 0 &&\r
-      RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {\r
-    return FALSE;\r
-  }\r
-\r
-  return TRUE;\r
-\r
-}\r
-\r
-/**\r
-  Waiting on the keyboard event, if there's any key pressed by the user, signal the event\r
-\r
-  @param  Event    The event that be siganlled when any key has been stroked.\r
-  @param  Context  Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BiosKeyboardWaitForKeyEx (\r
-  IN  EFI_EVENT  Event,\r
-  IN  VOID       *Context\r
-  )\r
-{\r
-  BIOS_KEYBOARD_DEV                     *BiosKeyboardPrivate;\r
-\r
-  BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (Context);\r
-  BiosKeyboardWaitForKey (Event, &BiosKeyboardPrivate->SimpleTextIn);\r
-\r
-}\r
-\r
-/**\r
-  Reset the input device and optionaly run diagnostics\r
-\r
-  @param  This                  Protocol instance pointer.\r
-  @param  ExtendedVerification  Driver may perform diagnostics on reset.\r
-\r
-  @retval EFI_SUCCESS           The device was reset.\r
-  @retval EFI_DEVICE_ERROR      The device is not functioning properly and could\r
-                                not be reset.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardResetEx (\r
-  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
-  IN BOOLEAN                            ExtendedVerification\r
-  )\r
-{\r
-  BIOS_KEYBOARD_DEV                     *BiosKeyboardPrivate;\r
-  EFI_STATUS                            Status;\r
-  EFI_TPL                               OldTpl;\r
-\r
-  BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-\r
-  Status = BiosKeyboardPrivate->SimpleTextIn.Reset (\r
-                                               &BiosKeyboardPrivate->SimpleTextIn,\r
-                                               ExtendedVerification\r
-                                               );\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return EFI_SUCCESS;\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
-\r
-  @param  This         Protocol instance pointer.\r
-  @param  KeyData      A pointer to a buffer that is filled in with the keystroke\r
-                       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_DEVICE_ERROR      The keystroke information was not returned due to\r
-                                 hardware errors.\r
-  @retval  EFI_INVALID_PARAMETER KeyData is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardReadKeyStrokeEx (\r
-  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,\r
-  OUT EFI_KEY_DATA                      *KeyData\r
-  )\r
-{\r
-  BIOS_KEYBOARD_DEV                     *BiosKeyboardPrivate;\r
-\r
-  if (KeyData == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-\r
-  return KeyboardReadKeyStrokeWorker (BiosKeyboardPrivate, KeyData);\r
-\r
-}\r
-\r
-/**\r
-  Set certain state for the input device.\r
-\r
-  @param  This              Protocol instance pointer.\r
-  @param  KeyToggleState    A pointer to the EFI_KEY_TOGGLE_STATE to set the\r
-                            state for the input device.\r
-\r
-  @retval EFI_SUCCESS           The device state was set successfully.\r
-  @retval EFI_DEVICE_ERROR      The device is not functioning correctly and could\r
-                                not have the setting adjusted.\r
-  @retval EFI_UNSUPPORTED       The device does not have the ability to set its state.\r
-  @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardSetState (\r
-  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
-  IN EFI_KEY_TOGGLE_STATE               *KeyToggleState\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  BIOS_KEYBOARD_DEV                     *BiosKeyboardPrivate;\r
-  EFI_TPL                               OldTpl;\r
-  EFI_LEGACY_BIOS_PROTOCOL              *LegacyBios;\r
-  UINT8                                 Command;\r
-\r
-  if (KeyToggleState == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Thunk keyboard driver doesn't support partial keystroke.\r
-  //\r
-  if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID ||\r
-      (*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED\r
-      ) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-  //\r
-  // See if the Legacy BIOS Protocol is available\r
-  //\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiLegacyBiosProtocolGuid,\r
-                  NULL,\r
-                  (VOID **) &LegacyBios\r
-                  );\r
-\r
-  ASSERT_EFI_ERROR (Status);\r
-  //\r
-  // Enter critical section\r
-  //\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  Command = 0;\r
-  if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {\r
-    Command |= 4;\r
-  }\r
-  if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {\r
-    Command |= 2;\r
-  }\r
-  if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {\r
-    Command |= 1;\r
-  }\r
-\r
-  Status = KeyboardWrite (BiosKeyboardPrivate, 0xed);\r
-  if (EFI_ERROR (Status)) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Exit;\r
-  }\r
-  Status = KeyboardWaitForValue (BiosKeyboardPrivate, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT);\r
-  if (EFI_ERROR (Status)) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Exit;\r
-  }\r
-  Status = KeyboardWrite (BiosKeyboardPrivate, Command);\r
-  if (EFI_ERROR (Status)) {\r
-    Status = EFI_DEVICE_ERROR;\r
-    goto Exit;\r
-  }\r
-  //\r
-  // Call Legacy BIOS Protocol to set whatever is necessary\r
-  //\r
-  LegacyBios->UpdateKeyboardLedStatus (LegacyBios, Command);\r
-\r
-  Status = EFI_SUCCESS;\r
-\r
-Exit:\r
-  //\r
-  // Leave critical section and return\r
-  //\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return Status;\r
-\r
-}\r
-\r
-/**\r
-  Register a notification function for a particular keystroke for the input device.\r
-\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. If KeyData.Key,\r
-                                  KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState\r
-                                  are 0, then any incomplete keystroke will trigger a notification of\r
-                                  the KeyNotificationFunction.\r
-  @param  KeyNotificationFunction Points to the function to be called when the key\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_INVALID_PARAMETER   KeyData or NotifyHandle is NULL.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardRegisterKeyNotify (\r
-  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
-  IN EFI_KEY_DATA                       *KeyData,\r
-  IN EFI_KEY_NOTIFY_FUNCTION            KeyNotificationFunction,\r
-  OUT VOID                              **NotifyHandle\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  BIOS_KEYBOARD_DEV                     *BiosKeyboardPrivate;\r
-  EFI_TPL                               OldTpl;\r
-  BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *NewNotify;\r
-  LIST_ENTRY                            *Link;\r
-  BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *CurrentNotify;\r
-\r
-  if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Enter critical section\r
-  //\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  //\r
-  // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.\r
-  //\r
-  for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {\r
-    CurrentNotify = CR (\r
-                      Link,\r
-                      BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
-                      NotifyEntry,\r
-                      BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
-                      );\r
-    if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {\r
-      if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {\r
-        *NotifyHandle = CurrentNotify;\r
-        Status = EFI_SUCCESS;\r
-        goto Exit;\r
-      }\r
-    }\r
-  }\r
-\r
-  //\r
-  // Allocate resource to save the notification function\r
-  //\r
-\r
-  NewNotify = (BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY));\r
-  if (NewNotify == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto Exit;\r
-  }\r
-\r
-  NewNotify->Signature         = BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;\r
-  NewNotify->KeyNotificationFn = KeyNotificationFunction;\r
-  CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));\r
-  InsertTailList (&BiosKeyboardPrivate->NotifyList, &NewNotify->NotifyEntry);\r
-\r
-  *NotifyHandle                = NewNotify;\r
-  Status                       = EFI_SUCCESS;\r
-\r
-Exit:\r
-  //\r
-  // Leave critical section and return\r
-  //\r
-  gBS->RestoreTPL (OldTpl);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Remove a registered notification function from a particular keystroke.\r
-\r
-  @param  This                 Protocol instance pointer.\r
-  @param  NotificationHandle   The handle of the notification function being unregistered.\r
-\r
-  @retval EFI_SUCCESS             The notification function was unregistered successfully.\r
-  @retval EFI_INVALID_PARAMETER   The NotificationHandle is invalid.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BiosKeyboardUnregisterKeyNotify (\r
-  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,\r
-  IN VOID                               *NotificationHandle\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  BIOS_KEYBOARD_DEV                     *BiosKeyboardPrivate;\r
-  EFI_TPL                               OldTpl;\r
-  LIST_ENTRY                            *Link;\r
-  BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *CurrentNotify;\r
-\r
-  //\r
-  // Check incoming notification handle\r
-  //\r
-  if (NotificationHandle == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (((BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);\r
-\r
-  //\r
-  // Enter critical section\r
-  //\r
-  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
-\r
-  for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {\r
-    CurrentNotify = CR (\r
-                      Link,\r
-                      BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,\r
-                      NotifyEntry,\r
-                      BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
-                      );\r
-    if (CurrentNotify == NotificationHandle) {\r
-      //\r
-      // Remove the notification function from NotifyList and free resources\r
-      //\r
-      RemoveEntryList (&CurrentNotify->NotifyEntry);\r
-\r
-      Status = EFI_SUCCESS;\r
-      goto Exit;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Can not find the specified Notification Handle\r
-  //\r
-  Status = EFI_INVALID_PARAMETER;\r
-\r
-Exit:\r
-  //\r
-  // Leave critical section and return\r
-  //\r
-  gBS->RestoreTPL (OldTpl);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  The user Entry Point for module BiosKeyboard. The user code starts with this function.\r
-\r
-  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
-  @param[in] SystemTable    A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS       The entry point is executed successfully.\r
-  @retval other             Some error occurs when executing this entry point.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeBiosKeyboard(\r
-  IN EFI_HANDLE           ImageHandle,\r
-  IN EFI_SYSTEM_TABLE     *SystemTable\r
-  )\r
-{\r
-  EFI_STATUS              Status;\r
-\r
-  //\r
-  // Install driver model protocol(s).\r
-  //\r
-  Status = EfiLibInstallDriverBindingComponentName2 (\r
-             ImageHandle,\r
-             SystemTable,\r
-             &gBiosKeyboardDriverBinding,\r
-             ImageHandle,\r
-             &gBiosKeyboardComponentName,\r
-             &gBiosKeyboardComponentName2\r
-             );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  return Status;\r
-}\r