summaryrefslogtreecommitdiff
path: root/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe
diff options
context:
space:
mode:
Diffstat (limited to 'IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe')
-rw-r--r--IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c2365
-rw-r--r--IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h744
-rw-r--r--IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.c183
-rw-r--r--IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.h153
-rw-r--r--IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf68
5 files changed, 3513 insertions, 0 deletions
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
new file mode 100644
index 0000000..06ef9d3
--- /dev/null
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.c
@@ -0,0 +1,2365 @@
+/** @file
+ ConsoleOut Routines that speak VGA.
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the BSD License which accompanies this distribution. The
+full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "BiosKeyboard.h"
+
+//
+// EFI Driver Binding Protocol Instance
+//
+EFI_DRIVER_BINDING_PROTOCOL gBiosKeyboardDriverBinding = {
+ BiosKeyboardDriverBindingSupported,
+ BiosKeyboardDriverBindingStart,
+ BiosKeyboardDriverBindingStop,
+ 0x3,
+ NULL,
+ NULL
+};
+
+
+/**
+ Enqueue the key.
+
+ @param Queue The queue to be enqueued.
+ @param KeyData The key data to be enqueued.
+
+ @retval EFI_NOT_READY The queue is full.
+ @retval EFI_SUCCESS Successfully enqueued the key data.
+
+**/
+EFI_STATUS
+Enqueue (
+ IN SIMPLE_QUEUE *Queue,
+ IN EFI_KEY_DATA *KeyData
+ )
+{
+ if ((Queue->Rear + 1) % QUEUE_MAX_COUNT == Queue->Front) {
+ return EFI_NOT_READY;
+ }
+
+ CopyMem (&Queue->Buffer[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));
+ Queue->Rear = (Queue->Rear + 1) % QUEUE_MAX_COUNT;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Dequeue the key.
+
+ @param Queue The queue to be dequeued.
+ @param KeyData The key data to be dequeued.
+
+ @retval EFI_NOT_READY The queue is empty.
+ @retval EFI_SUCCESS Successfully dequeued the key data.
+
+**/
+EFI_STATUS
+Dequeue (
+ IN SIMPLE_QUEUE *Queue,
+ IN EFI_KEY_DATA *KeyData
+ )
+{
+ if (Queue->Front == Queue->Rear) {
+ return EFI_NOT_READY;
+ }
+
+ CopyMem (KeyData, &Queue->Buffer[Queue->Front], sizeof (EFI_KEY_DATA));
+ Queue->Front = (Queue->Front + 1) % QUEUE_MAX_COUNT;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Check whether the queue is empty.
+
+ @param Queue The queue to be checked.
+
+ @retval EFI_NOT_READY The queue is empty.
+ @retval EFI_SUCCESS The queue is not empty.
+
+**/
+EFI_STATUS
+CheckQueue (
+ IN SIMPLE_QUEUE *Queue
+ )
+{
+ if (Queue->Front == Queue->Rear) {
+ return EFI_NOT_READY;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//
+// EFI Driver Binding Protocol Functions
+//
+
+/**
+ Check whether the driver supports this device.
+
+ @param This The Udriver binding protocol.
+ @param Controller The controller handle to check.
+ @param RemainingDevicePath The remaining device path.
+
+ @retval EFI_SUCCESS The driver supports this controller.
+ @retval other This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_ISA_IO_PROTOCOL *IsaIo;
+
+ //
+ // See if the Legacy BIOS Protocol is available
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ (VOID **) &LegacyBios
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ (VOID **) &IsaIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Use the ISA I/O Protocol to see if Controller is the Keyboard controller
+ //
+ if (IsaIo->ResourceList->Device.HID != EISA_PNP_ID (0x303) || IsaIo->ResourceList->Device.UID != 0) {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+/**
+ Starts the device with this driver.
+
+ @param This The driver binding instance.
+ @param Controller Handle of device to bind driver to.
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS The controller is controlled by the driver.
+ @retval Other This controller cannot be started.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_ISA_IO_PROTOCOL *IsaIo;
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_IA32_REGISTER_SET Regs;
+ BOOLEAN CarryFlag;
+ EFI_PS2_POLICY_PROTOCOL *Ps2Policy;
+ UINT8 Command;
+ EFI_STATUS_CODE_VALUE StatusCode;
+
+ BiosKeyboardPrivate = NULL;
+ IsaIo = NULL;
+ StatusCode = 0;
+
+ //
+ // Get Ps2 policy to set. Will be use if present.
+ //
+ gBS->LocateProtocol (
+ &gEfiPs2PolicyProtocolGuid,
+ NULL,
+ (VOID **) &Ps2Policy
+ );
+
+ //
+ // See if the Legacy BIOS Protocol is available
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ (VOID **) &LegacyBios
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Open the IO Abstraction(s) needed
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ (VOID **) &IsaIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Allocate the private device structure
+ //
+ BiosKeyboardPrivate = (BIOS_KEYBOARD_DEV *) AllocateZeroPool (sizeof (BIOS_KEYBOARD_DEV));
+ if (NULL == BiosKeyboardPrivate) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Initialize the private device structure
+ //
+ BiosKeyboardPrivate->Signature = BIOS_KEYBOARD_DEV_SIGNATURE;
+ BiosKeyboardPrivate->Handle = Controller;
+ BiosKeyboardPrivate->LegacyBios = LegacyBios;
+ BiosKeyboardPrivate->IsaIo = IsaIo;
+
+ BiosKeyboardPrivate->SimpleTextIn.Reset = BiosKeyboardReset;
+ BiosKeyboardPrivate->SimpleTextIn.ReadKeyStroke = BiosKeyboardReadKeyStroke;
+
+ BiosKeyboardPrivate->DataRegisterAddress = KEYBOARD_8042_DATA_REGISTER;
+ BiosKeyboardPrivate->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;
+ BiosKeyboardPrivate->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
+ BiosKeyboardPrivate->ExtendedKeyboard = TRUE;
+
+ BiosKeyboardPrivate->Queue.Front = 0;
+ BiosKeyboardPrivate->Queue.Rear = 0;
+ BiosKeyboardPrivate->SimpleTextInputEx.Reset = BiosKeyboardResetEx;
+ BiosKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx = BiosKeyboardReadKeyStrokeEx;
+ BiosKeyboardPrivate->SimpleTextInputEx.SetState = BiosKeyboardSetState;
+ BiosKeyboardPrivate->SimpleTextInputEx.RegisterKeyNotify = BiosKeyboardRegisterKeyNotify;
+ BiosKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify = BiosKeyboardUnregisterKeyNotify;
+ InitializeListHead (&BiosKeyboardPrivate->NotifyList);
+
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &BiosKeyboardPrivate->DevicePath
+ );
+
+ //
+ // Report that the keyboard is being enabled
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
+ BiosKeyboardPrivate->DevicePath
+ );
+
+ //
+ // Setup the WaitForKey event
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ BiosKeyboardWaitForKey,
+ &(BiosKeyboardPrivate->SimpleTextIn),
+ &((BiosKeyboardPrivate->SimpleTextIn).WaitForKey)
+ );
+ if (EFI_ERROR (Status)) {
+ (BiosKeyboardPrivate->SimpleTextIn).WaitForKey = NULL;
+ goto Done;
+ }
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ BiosKeyboardWaitForKeyEx,
+ &(BiosKeyboardPrivate->SimpleTextInputEx),
+ &(BiosKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx)
+ );
+ if (EFI_ERROR (Status)) {
+ BiosKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx = NULL;
+ goto Done;
+ }
+
+ //
+ // Setup a periodic timer, used for reading keystrokes at a fixed interval
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ BiosKeyboardTimerHandler,
+ BiosKeyboardPrivate,
+ &BiosKeyboardPrivate->TimerEvent
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto Done;
+ }
+
+ Status = gBS->SetTimer (
+ BiosKeyboardPrivate->TimerEvent,
+ TimerPeriodic,
+ KEYBOARD_TIMER_INTERVAL
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto Done;
+ }
+
+ //
+ // Report a Progress Code for an attempt to detect the precense of the keyboard device in the system
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
+ BiosKeyboardPrivate->DevicePath
+ );
+
+ //
+ // Reset the keyboard device
+ //
+ Status = BiosKeyboardPrivate->SimpleTextInputEx.Reset (
+ &BiosKeyboardPrivate->SimpleTextInputEx,
+ FALSE
+ );
+
+ if (EFI_ERROR (Status)) {
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
+ goto Done;
+ }
+ //
+ // Do platform specific policy like port swapping and keyboard light default
+ //
+ if (Ps2Policy != NULL) {
+
+ Ps2Policy->Ps2InitHardware (Controller);
+
+ Command = 0;
+ if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_CAPSLOCK) == EFI_KEYBOARD_CAPSLOCK) {
+ Command |= 4;
+ }
+
+ if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_NUMLOCK) == EFI_KEYBOARD_NUMLOCK) {
+ Command |= 2;
+ }
+
+ if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_SCROLLLOCK) == EFI_KEYBOARD_SCROLLLOCK) {
+ Command |= 1;
+ }
+
+ KeyboardWrite (BiosKeyboardPrivate, 0xed);
+ KeyboardWaitForValue (BiosKeyboardPrivate, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT);
+ KeyboardWrite (BiosKeyboardPrivate, Command);
+ //
+ // Call Legacy BIOS Protocol to set whatever is necessary
+ //
+ LegacyBios->UpdateKeyboardLedStatus (LegacyBios, Command);
+ }
+ //
+ // Get Configuration
+ //
+ Regs.H.AH = 0xc0;
+ CarryFlag = BiosKeyboardPrivate->LegacyBios->Int86 (
+ BiosKeyboardPrivate->LegacyBios,
+ 0x15,
+ &Regs
+ );
+
+ if (!CarryFlag) {
+ //
+ // Check bit 6 of Feature Byte 2.
+ // If it is set, then Int 16 Func 09 is supported
+ //
+ if (*(UINT8 *)(UINTN) ((Regs.X.ES << 4) + Regs.X.BX + 0x06) & 0x40) {
+ //
+ // Get Keyboard Functionality
+ //
+ Regs.H.AH = 0x09;
+ CarryFlag = BiosKeyboardPrivate->LegacyBios->Int86 (
+ BiosKeyboardPrivate->LegacyBios,
+ 0x16,
+ &Regs
+ );
+
+ if (!CarryFlag) {
+ //
+ // Check bit 5 of AH.
+ // If it is set, then INT 16 Finc 10-12 are supported.
+ //
+ if ((Regs.H.AL & 0x40) != 0) {
+ //
+ // Set the flag to use INT 16 Func 10-12
+ //
+ BiosKeyboardPrivate->ExtendedKeyboard = TRUE;
+ }
+ }
+ }
+ }
+ //
+ // Install protocol interfaces for the keyboard device.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ &BiosKeyboardPrivate->SimpleTextIn,
+ &gEfiSimpleTextInputExProtocolGuid,
+ &BiosKeyboardPrivate->SimpleTextInputEx,
+ NULL
+ );
+
+Done:
+ if (StatusCode != 0) {
+ //
+ // Report an Error Code for failing to start the keyboard device
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ StatusCode,
+ BiosKeyboardPrivate->DevicePath
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+
+ if (BiosKeyboardPrivate != NULL) {
+ if ((BiosKeyboardPrivate->SimpleTextIn).WaitForKey != NULL) {
+ gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextIn).WaitForKey);
+ }
+
+ if ((BiosKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx != NULL) {
+ gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx);
+ }
+ BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate->NotifyList);
+
+ if (BiosKeyboardPrivate->TimerEvent != NULL) {
+ gBS->CloseEvent (BiosKeyboardPrivate->TimerEvent);
+ }
+
+ FreePool (BiosKeyboardPrivate);
+ }
+
+ if (IsaIo != NULL) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Stop the device handled by this driver.
+
+ @param This The driver binding protocol.
+ @param Controller The controller to release.
+ @param NumberOfChildren The number of handles in ChildHandleBuffer.
+ @param ChildHandleBuffer The array of child handle.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+ @retval Others Fail to uninstall protocols attached on the device.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleTextIn;
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+
+ //
+ // Disable Keyboard
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ (VOID **) &SimpleTextIn,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSimpleTextInputExProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (SimpleTextIn);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ &BiosKeyboardPrivate->SimpleTextIn,
+ &gEfiSimpleTextInputExProtocolGuid,
+ &BiosKeyboardPrivate->SimpleTextInputEx,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Release the IsaIo protocol on the controller handle
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiIsaIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Free other resources
+ //
+ gBS->CloseEvent ((BiosKeyboardPrivate->SimpleTextIn).WaitForKey);
+ gBS->CloseEvent (BiosKeyboardPrivate->TimerEvent);
+ gBS->CloseEvent (BiosKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx);
+ BiosKeyboardFreeNotifyList (&BiosKeyboardPrivate->NotifyList);
+
+ FreePool (BiosKeyboardPrivate);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Read data byte from output buffer of Keyboard Controller without delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+
+ @return The data byte read from output buffer of Keyboard Controller from data port which often is port 60H.
+
+**/
+UINT8
+KeyReadDataRegister (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate
+ )
+{
+ UINT8 Data;
+
+ //
+ // Use IsaIo protocol to perform IO operations
+ //
+ BiosKeyboardPrivate->IsaIo->Io.Read (
+ BiosKeyboardPrivate->IsaIo,
+ EfiIsaIoWidthUint8,
+ BiosKeyboardPrivate->DataRegisterAddress,
+ 1,
+ &Data
+ );
+
+ return Data;
+}
+
+/**
+ Read status byte from status register of Keyboard Controller without delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+
+ @return The status byte read from status register of Keyboard Controller from command port which often is port 64H.
+
+**/
+UINT8
+KeyReadStatusRegister (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate
+ )
+{
+ UINT8 Data;
+
+ //
+ // Use IsaIo protocol to perform IO operations
+ //
+ BiosKeyboardPrivate->IsaIo->Io.Read (
+ BiosKeyboardPrivate->IsaIo,
+ EfiIsaIoWidthUint8,
+ BiosKeyboardPrivate->StatusRegisterAddress,
+ 1,
+ &Data
+ );
+
+ return Data;
+}
+
+/**
+ Write command byte to control register of Keyboard Controller without delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Data Data byte to write.
+
+**/
+VOID
+KeyWriteCommandRegister (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ IN UINT8 Data
+ )
+{
+ //
+ // Use IsaIo protocol to perform IO operations
+ //
+ BiosKeyboardPrivate->IsaIo->Io.Write (
+ BiosKeyboardPrivate->IsaIo,
+ EfiIsaIoWidthUint8,
+ BiosKeyboardPrivate->CommandRegisterAddress,
+ 1,
+ &Data
+ );
+}
+
+/**
+ Write data byte to input buffer or input/output ports of Keyboard Controller without delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Data Data byte to write.
+
+**/
+VOID
+KeyWriteDataRegister (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ IN UINT8 Data
+ )
+{
+ //
+ // Use IsaIo protocol to perform IO operations
+ //
+ BiosKeyboardPrivate->IsaIo->Io.Write (
+ BiosKeyboardPrivate->IsaIo,
+ EfiIsaIoWidthUint8,
+ BiosKeyboardPrivate->DataRegisterAddress,
+ 1,
+ &Data
+ );
+}
+
+/**
+ Read data byte from output buffer of Keyboard Controller with delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Data The pointer for data that being read out.
+
+ @retval EFI_SUCCESS The data byte read out successfully.
+ @retval EFI_TIMEOUT Timeout occurred during reading out data byte.
+
+**/
+EFI_STATUS
+KeyboardRead (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ OUT UINT8 *Data
+ )
+{
+ UINT32 TimeOut;
+ UINT32 RegFilled;
+
+ TimeOut = 0;
+ RegFilled = 0;
+
+ //
+ // wait till output buffer full then perform the read
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_OUTB) != 0) {
+ RegFilled = 1;
+ *Data = KeyReadDataRegister (BiosKeyboardPrivate);
+ break;
+ }
+
+ gBS->Stall (30);
+ }
+
+ if (RegFilled == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write data byte to input buffer or input/output ports of Keyboard Controller with delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Data Data byte to write.
+
+ @retval EFI_SUCCESS The data byte is written successfully.
+ @retval EFI_TIMEOUT Timeout occurred during writing.
+
+**/
+EFI_STATUS
+KeyboardWrite (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ IN UINT8 Data
+ )
+{
+ UINT32 TimeOut;
+ UINT32 RegEmptied;
+
+ TimeOut = 0;
+ RegEmptied = 0;
+
+ //
+ // wait for input buffer empty
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_INPB) == 0) {
+ RegEmptied = 1;
+ break;
+ }
+
+ gBS->Stall (30);
+ }
+
+ if (RegEmptied == 0) {
+ return EFI_TIMEOUT;
+ }
+ //
+ // Write it
+ //
+ KeyWriteDataRegister (BiosKeyboardPrivate, Data);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Write command byte to control register of Keyboard Controller with delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Data Command byte to write.
+
+ @retval EFI_SUCCESS The command byte is written successfully.
+ @retval EFI_TIMEOUT Timeout occurred during writing.
+
+**/
+EFI_STATUS
+KeyboardCommand (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ IN UINT8 Data
+ )
+{
+ UINT32 TimeOut;
+ UINT32 RegEmptied;
+
+ TimeOut = 0;
+ RegEmptied = 0;
+
+ //
+ // Wait For Input Buffer Empty
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_INPB) == 0) {
+ RegEmptied = 1;
+ break;
+ }
+
+ gBS->Stall (30);
+ }
+
+ if (RegEmptied == 0) {
+ return EFI_TIMEOUT;
+ }
+ //
+ // issue the command
+ //
+ KeyWriteCommandRegister (BiosKeyboardPrivate, Data);
+
+ //
+ // Wait For Input Buffer Empty again
+ //
+ RegEmptied = 0;
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_INPB) == 0) {
+ RegEmptied = 1;
+ break;
+ }
+
+ gBS->Stall (30);
+ }
+
+ if (RegEmptied == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Wait for a specific value to be presented in
+ Data register of Keyboard Controller by keyboard and then read it,
+ used in keyboard commands ack
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Value The value to be waited for
+ @param WaitForValueTimeOut The limit of microseconds for timeout
+
+ @retval EFI_SUCCESS The command byte is written successfully.
+ @retval EFI_TIMEOUT Timeout occurred during writing.
+
+**/
+EFI_STATUS
+KeyboardWaitForValue (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ IN UINT8 Value,
+ IN UINTN WaitForValueTimeOut
+ )
+{
+ UINT8 Data;
+ UINT32 TimeOut;
+ UINT32 SumTimeOut;
+ UINT32 GotIt;
+
+ GotIt = 0;
+ TimeOut = 0;
+ SumTimeOut = 0;
+
+ //
+ // Make sure the initial value of 'Data' is different from 'Value'
+ //
+ Data = 0;
+ if (Data == Value) {
+ Data = 1;
+ }
+ //
+ // Read from 8042 (multiple times if needed)
+ // until the expected value appears
+ // use SumTimeOut to control the iteration
+ //
+ while (1) {
+ //
+ // Perform a read
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_OUTB) != 0) {
+ Data = KeyReadDataRegister (BiosKeyboardPrivate);
+ break;
+ }
+
+ gBS->Stall (30);
+ }
+
+ SumTimeOut += TimeOut;
+
+ if (Data == Value) {
+ GotIt = 1;
+ break;
+ }
+
+ if (SumTimeOut >= WaitForValueTimeOut) {
+ break;
+ }
+ }
+ //
+ // Check results
+ //
+ if (GotIt != 0) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_TIMEOUT;
+ }
+
+}
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existance of a keystroke via WaitForEvent () call.
+
+ @param BiosKeyboardPrivate Bioskeyboard driver private structure.
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data availiable.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+ hardware errors.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
+EFI_STATUS
+KeyboardReadKeyStrokeWorker (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ OUT EFI_KEY_DATA *KeyData
+ )
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Use TimerEvent callback funciton to check whether there's any key pressed
+ //
+
+ //
+ // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
+ // Csm will be used to check whether there is a key pending, but the csm will disable all
+ // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
+ // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
+ // e.g. OS loader, other drivers which are driven by timer event will have a bad performance during this period,
+ // e.g. usb keyboard driver.
+ // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
+ // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
+ //
+ gBS->Stall (1000);
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ BiosKeyboardTimerHandler (NULL, BiosKeyboardPrivate);
+ //
+ // If there's no key, just return
+ //
+ Status = CheckQueue (&BiosKeyboardPrivate->Queue);
+ if (EFI_ERROR (Status)) {
+ gBS->RestoreTPL (OldTpl);
+ return EFI_NOT_READY;
+ }
+
+ Status = Dequeue (&BiosKeyboardPrivate->Queue, KeyData);
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_SUCCESS;
+}
+
+//
+// EFI Simple Text In Protocol Functions
+//
+/**
+ Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.
+
+ @param This Pointer of simple text Protocol.
+ @param ExtendedVerification Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
+
+ @retval EFI_SUCCESS The command byte is written successfully.
+ @retval EFI_DEVICE_ERROR Errors occurred during reseting keyboard.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ UINT8 CommandByte;
+ BOOLEAN MouseEnable;
+ EFI_INPUT_KEY Key;
+
+ MouseEnable = FALSE;
+ BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (This);
+
+ //
+ // 1
+ // Report reset progress code
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,
+ BiosKeyboardPrivate->DevicePath
+ );
+
+ //
+ // Report a Progress Code for clearing the keyboard buffer
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER,
+ BiosKeyboardPrivate->DevicePath
+ );
+
+ //
+ // 2
+ // Raise TPL to avoid mouse operation impact
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ //
+ // Exhaust output buffer data
+ //
+ do {
+ Status = BiosKeyboardReadKeyStroke (
+ This,
+ &Key
+ );
+ } while (!EFI_ERROR (Status));
+ //
+ // 3
+ // check for KBC itself firstly for setted-up already or not by reading SYSF (bit2) of status register via 64H
+ // if not skip step 4&5 and jump to step 6 to selftest KBC and report this
+ // else go step 4
+ //
+ if ((KeyReadStatusRegister (BiosKeyboardPrivate) & KBC_STSREG_VIA64_SYSF) != 0) {
+ //
+ // 4
+ // CheckMouseStatus to decide enable it later or not
+ //
+ //
+ // Read the command byte of KBC
+ //
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_CMDBYTE_R
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardRead (
+ BiosKeyboardPrivate,
+ &CommandByte
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ //
+ // Check mouse enabled or not before
+ //
+ if ((CommandByte & KB_CMMBYTE_DISABLE_AUX) != 0) {
+ MouseEnable = FALSE;
+ } else {
+ MouseEnable = TRUE;
+ }
+ //
+ // 5
+ // disable mouse (via KBC) and Keyborad device
+ //
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_AUX_DISABLE
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_KB_DISABLE
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ } else {
+ //
+ // 6
+ // KBC Self Test
+ //
+ //
+ // Report a Progress Code for performing a self test on the keyboard controller
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,
+ BiosKeyboardPrivate->DevicePath
+ );
+
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_KBC_SLFTEST
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_KBCSLFTEST_OK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+ //
+ // 7
+ // Disable Mouse interface, enable Keyboard interface and declare selftest success
+ //
+ // Mouse device will block keyboard interface before it be configured, so we should disable mouse first.
+ //
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_CMDBYTE_W
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // Write 8042 Command Byte, set System Flag
+ // While at the same time:
+ // 1. disable mouse interface,
+ // 2. enable kbd interface,
+ // 3. enable PC/XT kbd translation mode
+ // 4. enable mouse and kbd interrupts
+ //
+ //Command Byte bits:
+ // 7: Reserved
+ // 6: PC/XT translation mode
+ // 5: Disable Auxiliary device interface
+ // 4: Disable keyboard interface
+ // 3: Reserved
+ // 2: System Flag
+ // 1: Enable Auxiliary device interrupt
+ // 0: Enable Keyboard interrupt
+ //
+ CommandByte = 0;
+ Status = KeyboardWrite (
+ BiosKeyboardPrivate,
+ (UINT8) ((CommandByte &
+ (~KB_CMMBYTE_DISABLE_KB)) |
+ KB_CMMBYTE_KSCAN2UNI_COV |
+ KB_CMMBYTE_ENABLE_AUXINT |
+ KB_CMMBYTE_ENABLE_KBINT |
+ KB_CMMBYTE_SLFTEST_SUCC |
+ KB_CMMBYTE_DISABLE_AUX)
+ );
+
+ //
+ // For reseting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,
+ // so we only do the real reseting for keyboard when user asks, and normally during booting an OS, it's skipped.
+ // Call CheckKeyboardConnect() to check whether keyboard is connected, if it is not connected,
+ // Real reset will not do.
+ //
+ if (ExtendedVerification && CheckKeyboardConnect (BiosKeyboardPrivate)) {
+ //
+ // 8
+ // Send keyboard reset command then read ACK
+ //
+ Status = KeyboardWrite (
+ BiosKeyboardPrivate,
+ KBC_INPBUF_VIA60_KBRESET
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_ACK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ //
+ // 9
+ // Wait for keyboard return test OK.
+ //
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_BATTEST_OK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ //
+ // 10
+ // set keyboard scan code set = 02 (standard configuration)
+ //
+ Status = KeyboardWrite (
+ BiosKeyboardPrivate,
+ KBC_INPBUF_VIA60_KBSCODE
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_ACK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardWrite (
+ BiosKeyboardPrivate,
+ KBC_INPBUF_VIA60_SCODESET2
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_ACK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ //
+ // 11
+ // enable keyboard itself (not via KBC) by writing CMD F4 via 60H
+ //
+ Status = KeyboardWrite (
+ BiosKeyboardPrivate,
+ KBC_INPBUF_VIA60_KBEN
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_ACK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ //
+ // 12
+ // Additional validation, do it as follow:
+ // 1). check for status register of PARE && TIM via 64H
+ // 2). perform KB checking by writing ABh via 64H
+ //
+ if ((KeyReadStatusRegister (BiosKeyboardPrivate) & (KBC_STSREG_VIA64_PARE | KBC_STSREG_VIA64_TIM)) != 0) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_KB_CKECK
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_KBCHECK_OK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ }
+ //
+ // 13
+ // Done for validating keyboard. Enable keyboard (via KBC)
+ // and recover the command byte to proper value
+ //
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_KB_ENABLE
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ //
+ // 14
+ // conditionally enable mouse (via KBC)
+ //
+ if (MouseEnable) {
+ Status = KeyboardCommand (
+ BiosKeyboardPrivate,
+ KBC_CMDREG_VIA64_AUX_ENABLE
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+
+ }
+ }
+
+Exit:
+ //
+ // 15
+ // resume priority of task level
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+
+}
+
+/**
+ Read out the scan code of the key that has just been stroked.
+
+ @param This Pointer of simple text Protocol.
+ @param Key Pointer for store the key that read out.
+
+ @retval EFI_SUCCESS The key is read out successfully.
+ @retval other The key reading failed.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+{
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_STATUS Status;
+ EFI_KEY_DATA KeyData;
+
+ BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (This);
+
+ Status = KeyboardReadKeyStrokeWorker (BiosKeyboardPrivate, &KeyData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Waiting on the keyboard event, if there's any key pressed by the user, signal the event
+
+ @param Event The event that be siganlled when any key has been stroked.
+ @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
+
+**/
+VOID
+EFIAPI
+BiosKeyboardWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
+ // Csm will be used to check whether there is a key pending, but the csm will disable all
+ // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
+ // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
+ // e.g. UI setup or Shell, other drivers which are driven by timer event will have a bad performance during this period,
+ // e.g. usb keyboard driver.
+ // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
+ // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
+ //
+ gBS->Stall (1000);
+ //
+ // Use TimerEvent callback funciton to check whether there's any key pressed
+ //
+ BiosKeyboardTimerHandler (NULL, BIOS_KEYBOARD_DEV_FROM_THIS (Context));
+
+ if (!EFI_ERROR (BiosKeyboardCheckForKey (Context))) {
+ gBS->SignalEvent (Event);
+ }
+}
+
+/**
+ Check key buffer to get the key stroke status.
+
+ @param This Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL.
+
+ @retval EFI_SUCCESS A key is being pressed now.
+ @retval Other No key is now pressed.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardCheckForKey (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
+ )
+{
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+
+ BiosKeyboardPrivate = BIOS_KEYBOARD_DEV_FROM_THIS (This);
+
+ return CheckQueue (&BiosKeyboardPrivate->Queue);
+}
+//
+// Private worker functions
+//
+#define TABLE_END 0x0
+
+typedef struct _CONVERT_TABLE_ENTRY {
+ UINT16 ScanCode;
+ UINT16 EfiScanCode;
+} CONVERT_TABLE_ENTRY;
+
+CONVERT_TABLE_ENTRY mConvertTable[] = {
+ {
+ 0x47,
+ SCAN_HOME
+ },
+ {
+ 0x48,
+ SCAN_UP
+ },
+ {
+ 0x49,
+ SCAN_PAGE_UP
+ },
+ {
+ 0x4b,
+ SCAN_LEFT
+ },
+ {
+ 0x4d,
+ SCAN_RIGHT
+ },
+ {
+ 0x4f,
+ SCAN_END
+ },
+ {
+ 0x50,
+ SCAN_DOWN
+ },
+ {
+ 0x51,
+ SCAN_PAGE_DOWN
+ },
+ {
+ 0x52,
+ SCAN_INSERT
+ },
+ {
+ 0x53,
+ SCAN_DELETE
+ },
+ //
+ // Function Keys are only valid if KeyChar == 0x00
+ // This function does not require KeyChar to be 0x00
+ //
+ {
+ 0x3b,
+ SCAN_F1
+ },
+ {
+ 0x3c,
+ SCAN_F2
+ },
+ {
+ 0x3d,
+ SCAN_F3
+ },
+ {
+ 0x3e,
+ SCAN_F4
+ },
+ {
+ 0x3f,
+ SCAN_F5
+ },
+ {
+ 0x40,
+ SCAN_F6
+ },
+ {
+ 0x41,
+ SCAN_F7
+ },
+ {
+ 0x42,
+ SCAN_F8
+ },
+ {
+ 0x43,
+ SCAN_F9
+ },
+ {
+ 0x44,
+ SCAN_F10
+ },
+ {
+ 0x85,
+ SCAN_F11
+ },
+ {
+ 0x86,
+ SCAN_F12
+ },
+ //
+ // Convert ALT + Fn keys
+ //
+ {
+ 0x68,
+ SCAN_F1
+ },
+ {
+ 0x69,
+ SCAN_F2
+ },
+ {
+ 0x6a,
+ SCAN_F3
+ },
+ {
+ 0x6b,
+ SCAN_F4
+ },
+ {
+ 0x6c,
+ SCAN_F5
+ },
+ {
+ 0x6d,
+ SCAN_F6
+ },
+ {
+ 0x6e,
+ SCAN_F7
+ },
+ {
+ 0x6f,
+ SCAN_F8
+ },
+ {
+ 0x70,
+ SCAN_F9
+ },
+ {
+ 0x71,
+ SCAN_F10
+ },
+ {
+ TABLE_END,
+ SCAN_NULL
+ },
+};
+
+/**
+ Convert unicode combined with scan code of key to the counterpart of EFIScancode of it.
+
+ @param KeyChar Unicode of key.
+ @param ScanCode Scan code of key.
+
+ @return The value of EFI Scancode for the key.
+ @retval SCAN_NULL No corresponding value in the EFI convert table is found for the key.
+
+**/
+UINT16
+ConvertToEFIScanCode (
+ IN CHAR16 KeyChar,
+ IN UINT16 ScanCode
+ )
+{
+ UINT16 EfiScanCode;
+ UINT16 Index;
+
+ if (KeyChar == CHAR_ESC) {
+ EfiScanCode = SCAN_ESC;
+ } else if (KeyChar == 0x00 || KeyChar == 0xe0) {
+ //
+ // Movement & Function Keys
+ //
+ for (Index = 0; (Index < sizeof (mConvertTable) / sizeof (CONVERT_TABLE_ENTRY)) && (mConvertTable[Index].ScanCode != TABLE_END); Index += 1) {
+ if (ScanCode == mConvertTable[Index].ScanCode) {
+ return mConvertTable[Index].EfiScanCode;
+ }
+ }
+ //
+ // Reach Table end, return default value
+ //
+ return SCAN_NULL;
+ } else {
+ return SCAN_NULL;
+ }
+
+ return EfiScanCode;
+}
+
+/**
+ Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command
+ If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device
+ should not be in system.
+
+ @param BiosKeyboardPrivate Keyboard Private Data Struture
+
+ @retval TRUE Keyboard in System.
+ @retval FALSE Keyboard not in System.
+
+**/
+BOOLEAN
+CheckKeyboardConnect (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ //
+ // enable keyboard itself and wait for its ack
+ // If can't receive ack, Keyboard should not be connected.
+ //
+ Status = KeyboardWrite (
+ BiosKeyboardPrivate,
+ KBC_INPBUF_VIA60_KBEN
+ );
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = KeyboardWaitForValue (
+ BiosKeyboardPrivate,
+ KBC_CMDECHO_ACK,
+ KEYBOARD_WAITFORVALUE_TIMEOUT
+ );
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Timer event handler: read a series of key stroke from 8042
+ and put them into memory key buffer.
+ It is registered as running under TPL_NOTIFY
+
+ @param Event The timer event
+ @param Context A BIOS_KEYBOARD_DEV pointer
+
+**/
+VOID
+EFIAPI
+BiosKeyboardTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_TPL OldTpl;
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_IA32_REGISTER_SET Regs;
+ UINT8 KbFlag1; // 0040h:0017h - KEYBOARD - STATUS FLAGS 1
+ UINT8 KbFlag2; // 0040h:0018h - KEYBOARD - STATUS FLAGS 2
+ EFI_KEY_DATA KeyData;
+ LIST_ENTRY *Link;
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+
+ BiosKeyboardPrivate = Context;
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // if there is no key present, just return
+ //
+ if (BiosKeyboardPrivate->ExtendedKeyboard) {
+ Regs.H.AH = 0x11;
+ } else {
+ Regs.H.AH = 0x01;
+ }
+
+ BiosKeyboardPrivate->LegacyBios->Int86 (
+ BiosKeyboardPrivate->LegacyBios,
+ 0x16,
+ &Regs
+ );
+ if (Regs.X.Flags.ZF != 0) {
+ gBS->RestoreTPL (OldTpl);
+ return;
+ }
+
+ //
+ // Read the key
+ //
+ if (BiosKeyboardPrivate->ExtendedKeyboard) {
+ Regs.H.AH = 0x10;
+ } else {
+ Regs.H.AH = 0x00;
+ }
+
+ BiosKeyboardPrivate->LegacyBios->Int86 (
+ BiosKeyboardPrivate->LegacyBios,
+ 0x16,
+ &Regs
+ );
+
+ KeyData.Key.ScanCode = (UINT16) Regs.H.AH;
+ KeyData.Key.UnicodeChar = (UINT16) Regs.H.AL;
+ KeyData.KeyState.KeyShiftState = EFI_SHIFT_STATE_VALID;
+ KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
+ //
+ // Leagcy Bios use Int 9 which is IRQ1 interrupt handler to get keystroke scancode to KB buffer in BDA (BIOS DATE AREA), then
+ // 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
+ // 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
+ // 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
+ // 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
+ // 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
+ // to wrong ASCII code. We can increase the Thunk frequence to let Int 9 response in time, but this way will much hurt other dirvers
+ // performance, like USB.
+ //
+ // 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
+ // 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
+ // 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
+ // CTRL and ALT.
+ //
+ // 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
+ // 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,
+ // which will let persist to press SHIFT has same effection as only press one time.
+ //
+ //0040h:0017h - KEYBOARD - STATUS FLAGS 1
+ // 7 INSert active
+ // 6 Caps Lock active
+ // 5 Num Lock active
+ // 4 Scroll Lock active
+ // 3 either Alt pressed
+ // 2 either Ctrl pressed
+ // 1 Left Shift pressed
+ // 0 Right Shift pressed
+
+
+ //
+ // Clear the CTRL and ALT BDA flag
+ //
+ KbFlag1 = *((UINT8 *) (UINTN) 0x417); // read the STATUS FLAGS 1
+ KbFlag2 = *((UINT8 *) (UINTN) 0x418); // read STATUS FLAGS 2
+
+ //
+ // Record toggle state
+ //
+ if ((KbFlag1 & KB_CAPS_LOCK_BIT) == KB_CAPS_LOCK_BIT) {
+ KeyData.KeyState.KeyToggleState |= EFI_CAPS_LOCK_ACTIVE;
+ }
+ if ((KbFlag1 & KB_NUM_LOCK_BIT) == KB_NUM_LOCK_BIT) {
+ KeyData.KeyState.KeyToggleState |= EFI_NUM_LOCK_ACTIVE;
+ }
+ if ((KbFlag1 & KB_SCROLL_LOCK_BIT) == KB_SCROLL_LOCK_BIT) {
+ KeyData.KeyState.KeyToggleState |= EFI_SCROLL_LOCK_ACTIVE;
+ }
+ //
+ // Record shift state
+ // BUGBUG: Need add Menu key and Left/Right Logo key state in the future
+ //
+ if ((KbFlag1 & KB_ALT_PRESSED) == KB_ALT_PRESSED) {
+ KeyData.KeyState.KeyShiftState |= ((KbFlag2 & KB_LEFT_ALT_PRESSED) == KB_LEFT_ALT_PRESSED) ? EFI_LEFT_ALT_PRESSED : EFI_RIGHT_ALT_PRESSED;
+ }
+ if ((KbFlag1 & KB_CTRL_PRESSED) == KB_CTRL_PRESSED) {
+ KeyData.KeyState.KeyShiftState |= ((KbFlag2 & KB_LEFT_CTRL_PRESSED) == KB_LEFT_CTRL_PRESSED) ? EFI_LEFT_CONTROL_PRESSED : EFI_RIGHT_CONTROL_PRESSED;
+ }
+ if ((KbFlag1 & KB_LEFT_SHIFT_PRESSED) == KB_LEFT_SHIFT_PRESSED) {
+ KeyData.KeyState.KeyShiftState |= EFI_LEFT_SHIFT_PRESSED;
+ }
+ if ((KbFlag1 & KB_RIGHT_SHIFT_PRESSED) == KB_RIGHT_SHIFT_PRESSED) {
+ KeyData.KeyState.KeyShiftState |= EFI_RIGHT_SHIFT_PRESSED;
+ }
+
+ //
+ // Clear left alt and left ctrl BDA flag
+ //
+ KbFlag2 &= ~(KB_LEFT_ALT_PRESSED | KB_LEFT_CTRL_PRESSED);
+ *((UINT8 *) (UINTN) 0x418) = KbFlag2;
+ KbFlag1 &= ~0x0C;
+ *((UINT8 *) (UINTN) 0x417) = KbFlag1;
+
+
+ //
+ // Output EFI input key and shift/toggle state
+ //
+ if (KeyData.Key.UnicodeChar == CHAR_NULL || KeyData.Key.UnicodeChar == CHAR_SCANCODE || KeyData.Key.UnicodeChar == CHAR_ESC) {
+ KeyData.Key.ScanCode = ConvertToEFIScanCode (KeyData.Key.UnicodeChar, KeyData.Key.ScanCode);
+ KeyData.Key.UnicodeChar = CHAR_NULL;
+ } else {
+ KeyData.Key.ScanCode = SCAN_NULL;
+ }
+
+ //
+ // CSM16 has converted the Ctrl+[a-z] to [1-26], converted it back.
+ //
+ if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
+ if (KeyData.Key.UnicodeChar >= 1 && KeyData.Key.UnicodeChar <= 26) {
+ if (((KeyData.KeyState.KeyShiftState & (EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED)) != 0) ==
+ ((KeyData.KeyState.KeyToggleState & EFI_CAPS_LOCK_ACTIVE) != 0)
+ ) {
+ KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar + L'a' - 1);
+ } else {
+ KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar + L'A' - 1);
+ }
+ }
+ }
+
+ //
+ // Need not return associated shift state if a class of printable characters that
+ // are normally adjusted by shift modifiers.
+ // e.g. Shift Key + 'f' key = 'F'; Shift Key + 'F' key = 'f'.
+ //
+ if ((KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') ||
+ (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z')
+ ) {
+ KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
+ }
+
+ //
+ // Invoke notification functions if exist
+ //
+ for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ CurrentNotify->KeyNotificationFn (&KeyData);
+ }
+ }
+
+ //
+ // Convert the Ctrl+[a-z] to Ctrl+[1-26]
+ //
+ if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
+ if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
+ KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'a' + 1);
+ } else if (KeyData.Key.UnicodeChar >= L'A' && KeyData.Key.UnicodeChar <= L'Z') {
+ KeyData.Key.UnicodeChar = (UINT16) (KeyData.Key.UnicodeChar - L'A' + 1);
+ }
+ }
+ Enqueue (&BiosKeyboardPrivate->Queue, &KeyData);
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return ;
+}
+
+/**
+ Free keyboard notify list.
+
+ @param ListHead The list head
+
+ @retval EFI_SUCCESS Free the notify list successfully
+ @retval EFI_INVALID_PARAMETER ListHead is invalid.
+
+**/
+EFI_STATUS
+BiosKeyboardFreeNotifyList (
+ IN OUT LIST_ENTRY *ListHead
+ )
+{
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
+
+ if (ListHead == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ while (!IsListEmpty (ListHead)) {
+ NotifyNode = CR (
+ ListHead->ForwardLink,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ RemoveEntryList (ListHead->ForwardLink);
+ gBS->FreePool (NotifyNode);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check if key is registered.
+
+ @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was registered.
+ @param InputData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval TRUE Key be pressed matches a registered key.
+ @retval FLASE Match failed.
+
+**/
+BOOLEAN
+IsKeyRegistered (
+ IN EFI_KEY_DATA *RegsiteredData,
+ IN EFI_KEY_DATA *InputData
+ )
+{
+ ASSERT (RegsiteredData != NULL && InputData != NULL);
+
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
+ return FALSE;
+ }
+
+ //
+ // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
+ //
+ if (RegsiteredData->KeyState.KeyShiftState != 0 &&
+ RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
+ return FALSE;
+ }
+ if (RegsiteredData->KeyState.KeyToggleState != 0 &&
+ RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
+ return FALSE;
+ }
+
+ return TRUE;
+
+}
+
+/**
+ Waiting on the keyboard event, if there's any key pressed by the user, signal the event
+
+ @param Event The event that be siganlled when any key has been stroked.
+ @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+
+**/
+VOID
+EFIAPI
+BiosKeyboardWaitForKeyEx (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+
+ BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (Context);
+ BiosKeyboardWaitForKey (Event, &BiosKeyboardPrivate->SimpleTextIn);
+
+}
+
+/**
+ Reset the input device and optionaly run diagnostics
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);
+
+ Status = BiosKeyboardPrivate->SimpleTextIn.Reset (
+ &BiosKeyboardPrivate->SimpleTextIn,
+ ExtendedVerification
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_SUCCESS;
+
+}
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existance of a keystroke via WaitForEvent () call.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data availiable.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+ hardware errors.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ )
+{
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);
+
+ return KeyboardReadKeyStrokeWorker (BiosKeyboardPrivate, KeyData);
+
+}
+
+/**
+ Set certain state for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ @retval EFI_SUCCESS The device state was set successfully.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and could
+ not have the setting adjusted.
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ )
+{
+ EFI_STATUS Status;
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_TPL OldTpl;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT8 Command;
+
+ if (KeyToggleState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
+ return EFI_UNSUPPORTED;
+ }
+
+ BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);
+ //
+ // See if the Legacy BIOS Protocol is available
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ (VOID **) &LegacyBios
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ Command = 0;
+ if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
+ Command |= 4;
+ }
+ if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
+ Command |= 2;
+ }
+ if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
+ Command |= 1;
+ }
+
+ Status = KeyboardWrite (BiosKeyboardPrivate, 0xed);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ Status = KeyboardWaitForValue (BiosKeyboardPrivate, 0xfa, KEYBOARD_WAITFORVALUE_TIMEOUT);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ Status = KeyboardWrite (BiosKeyboardPrivate, Command);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Call Legacy BIOS Protocol to set whatever is necessary
+ //
+ LegacyBios->UpdateKeyboardLedStatus (LegacyBios, Command);
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+
+}
+
+/**
+ Register a notification function for a particular keystroke for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ information data for the key that was pressed.
+ @param KeyNotificationFunction Points to the function to be called when the key
+ sequence is typed specified by KeyData.
+ @param NotifyHandle Points to the unique handle assigned to the registered notification.
+
+
+ @retval EFI_SUCCESS The notification function was registered successfully.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
+ @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+ )
+{
+ EFI_STATUS Status;
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_TPL OldTpl;
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;
+ LIST_ENTRY *Link;
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+
+ if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
+ //
+ for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
+ *NotifyHandle = CurrentNotify->NotifyHandle;
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ }
+ }
+
+ //
+ // Allocate resource to save the notification function
+ //
+
+ NewNotify = (BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY));
+ if (NewNotify == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ NewNotify->Signature = BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;
+ NewNotify->NotifyHandle = (EFI_HANDLE) NewNotify;
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
+ InsertTailList (&BiosKeyboardPrivate->NotifyList, &NewNotify->NotifyEntry);
+
+ *NotifyHandle = NewNotify->NotifyHandle;
+ Status = EFI_SUCCESS;
+
+Exit:
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Remove a registered notification function from a particular keystroke.
+
+ @param This Protocol instance pointer.
+ @param NotificationHandle The handle of the notification function being unregistered.
+
+ @retval EFI_SUCCESS The notification function was unregistered successfully.
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+ )
+{
+ EFI_STATUS Status;
+ BIOS_KEYBOARD_DEV *BiosKeyboardPrivate;
+ EFI_TPL OldTpl;
+ LIST_ENTRY *Link;
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+
+ //
+ // Check incoming notification handle
+ //
+ if (NotificationHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BiosKeyboardPrivate = TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS (This);
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ for (Link = BiosKeyboardPrivate->NotifyList.ForwardLink; Link != &BiosKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (CurrentNotify->NotifyHandle == NotificationHandle) {
+ //
+ // Remove the notification function from NotifyList and free resources
+ //
+ RemoveEntryList (&CurrentNotify->NotifyEntry);
+
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ }
+
+ //
+ // Can not find the specified Notification Handle
+ //
+ Status = EFI_INVALID_PARAMETER;
+
+Exit:
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ The user Entry Point for module BiosKeyboard. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeBiosKeyboard(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gBiosKeyboardDriverBinding,
+ ImageHandle,
+ &gBiosKeyboardComponentName,
+ &gBiosKeyboardComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h
new file mode 100644
index 0000000..c9f86a1
--- /dev/null
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/BiosKeyboard.h
@@ -0,0 +1,744 @@
+/** @file
+
+Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the BSD License which accompanies this distribution. The
+full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _BIOS_KEYBOARD_H_
+#define _BIOS_KEYBOARD_H_
+
+
+#include <FrameworkDxe.h>
+
+#include <Guid/StatusCodeDataTypeId.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextInEx.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/IsaIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/Ps2Policy.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+
+//
+// Driver Binding Externs
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gBiosKeyboardDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gBiosKeyboardComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gBiosKeyboardComponentName2;
+
+
+#include <IndustryStandard/Pci.h>
+
+//
+// BISO Keyboard Defines
+//
+#define CHAR_SCANCODE 0xe0
+#define CHAR_ESC 0x1b
+
+#define KEYBOARD_8042_DATA_REGISTER 0x60
+#define KEYBOARD_8042_STATUS_REGISTER 0x64
+#define KEYBOARD_8042_COMMAND_REGISTER 0x64
+
+#define KEYBOARD_TIMEOUT 65536 // 0.07s
+#define KEYBOARD_WAITFORVALUE_TIMEOUT 1000000 // 1s
+#define KEYBOARD_BAT_TIMEOUT 4000000 // 4s
+#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
+// KEYBOARD COMMAND BYTE -- read by writing command KBC_CMDREG_VIA64_CMDBYTE_R to 64H, then read from 60H
+// write by wrting command KBC_CMDREG_VIA64_CMDBYTE_W to 64H, then write to 60H
+// 7: Reserved
+// 6: PC/XT translation mode convert
+// 5: Disable Auxiliary device interface
+// 4: Disable keyboard interface
+// 3: Reserved
+// 2: System Flag: selftest successful
+// 1: Enable Auxiliary device interrupt
+// 0: Enable Keyboard interrupt )
+//
+#define KB_CMMBYTE_KSCAN2UNI_COV (0x1 << 6)
+#define KB_CMMBYTE_DISABLE_AUX (0x1 << 5)
+#define KB_CMMBYTE_DISABLE_KB (0x1 << 4)
+#define KB_CMMBYTE_SLFTEST_SUCC (0x1 << 2)
+#define KB_CMMBYTE_ENABLE_AUXINT (0x1 << 1)
+#define KB_CMMBYTE_ENABLE_KBINT (0x1 << 0)
+
+//
+// KEYBOARD CONTROLLER STATUS REGISTER - read from 64h
+// 7: Parity error
+// 6: General time out
+// 5: Output buffer holds data for AUX
+// 4: Keyboard is not locked
+// 3: Command written via 64h / Data written via 60h
+// 2: KBC self-test successful / Power-on reset
+// 1: Input buffer holds CPU data / empty
+// 0: Output buffer holds keyboard data / empty
+//
+#define KBC_STSREG_VIA64_PARE (0x1 << 7)
+#define KBC_STSREG_VIA64_TIM (0x1 << 6)
+#define KBC_STSREG_VIA64_AUXB (0x1 << 5)
+#define KBC_STSREG_VIA64_KEYL (0x1 << 4)
+#define KBC_STSREG_VIA64_C_D (0x1 << 3)
+#define KBC_STSREG_VIA64_SYSF (0x1 << 2)
+#define KBC_STSREG_VIA64_INPB (0x1 << 1)
+#define KBC_STSREG_VIA64_OUTB (0x1 << 0)
+
+//
+// COMMANDs of KEYBOARD CONTROLLER COMMAND REGISTER - write to 64h
+//
+#define KBC_CMDREG_VIA64_CMDBYTE_R 0x20
+#define KBC_CMDREG_VIA64_CMDBYTE_W 0x60
+#define KBC_CMDREG_VIA64_AUX_DISABLE 0xA7
+#define KBC_CMDREG_VIA64_AUX_ENABLE 0xA8
+#define KBC_CMDREG_VIA64_KBC_SLFTEST 0xAA
+#define KBC_CMDREG_VIA64_KB_CKECK 0xAB
+#define KBC_CMDREG_VIA64_KB_DISABLE 0xAD
+#define KBC_CMDREG_VIA64_KB_ENABLE 0xAE
+#define KBC_CMDREG_VIA64_INTP_LOW_R 0xC0
+#define KBC_CMDREG_VIA64_INTP_HIGH_R 0xC2
+#define KBC_CMDREG_VIA64_OUTP_R 0xD0
+#define KBC_CMDREG_VIA64_OUTP_W 0xD1
+#define KBC_CMDREG_VIA64_OUTB_KB_W 0xD2
+#define KBC_CMDREG_VIA64_OUTB_AUX_W 0xD3
+#define KBC_CMDREG_VIA64_AUX_W 0xD4
+
+//
+// echos of KEYBOARD CONTROLLER COMMAND - read from 60h
+//
+#define KBC_CMDECHO_KBCSLFTEST_OK 0x55
+#define KBC_CMDECHO_KBCHECK_OK 0x00
+#define KBC_CMDECHO_ACK 0xFA
+#define KBC_CMDECHO_BATTEST_OK 0xAA
+#define KBC_CMDECHO_BATTEST_FAILE 0xFC
+
+//
+// OUTPUT PORT COMMANDs - write port by writing KBC_CMDREG_VIA64_OUTP_W via 64H, then write the command to 60H
+// drive data and clock of KB to high for at least 500us for BAT needs
+//
+#define KBC_OUTPORT_DCHIGH_BAT 0xC0
+//
+// scan code set type
+//
+#define KBC_INPBUF_VIA60_SCODESET1 0x01
+#define KBC_INPBUF_VIA60_SCODESET2 0x02
+#define KBC_INPBUF_VIA60_SCODESET3 0x03
+
+//
+// COMMANDs written to INPUT BUFFER - write to 60h
+//
+#define KBC_INPBUF_VIA60_KBECHO 0xEE
+#define KBC_INPBUF_VIA60_KBSCODE 0xF0
+#define KBC_INPBUF_VIA60_KBTYPE 0xF2
+#define KBC_INPBUF_VIA60_KBDELAY 0xF3
+#define KBC_INPBUF_VIA60_KBEN 0xF4
+#define KBC_INPBUF_VIA60_KBSTDDIS 0xF5
+#define KBC_INPBUF_VIA60_KBSTDEN 0xF6
+#define KBC_INPBUF_VIA60_KBRESEND 0xFE
+#define KBC_INPBUF_VIA60_KBRESET 0xFF
+
+//
+// 0040h:0017h - KEYBOARD - STATUS FLAGS 1
+// 7 INSert active
+// 6 Caps Lock active
+// 5 Num Lock active
+// 4 Scroll Lock active
+// 3 either Alt pressed
+// 2 either Ctrl pressed
+// 1 Left Shift pressed
+// 0 Right Shift pressed
+//
+// 0040h:0018h - KEYBOARD - STATUS FLAGS 2
+// 7: insert key is depressed
+// 6: caps-lock key is depressed (does not work well)
+// 5: num-lock key is depressed (does not work well)
+// 4: scroll lock key is depressed (does not work well)
+// 3: suspend key has been toggled (does not work well)
+// 2: system key is pressed and held (does not work well)
+// 1: left ALT key is pressed
+// 0: left CTRL key is pressed
+//
+#define KB_INSERT_BIT (0x1 << 7)
+#define KB_CAPS_LOCK_BIT (0x1 << 6)
+#define KB_NUM_LOCK_BIT (0x1 << 5)
+#define KB_SCROLL_LOCK_BIT (0x1 << 4)
+#define KB_ALT_PRESSED (0x1 << 3)
+#define KB_CTRL_PRESSED (0x1 << 2)
+#define KB_LEFT_SHIFT_PRESSED (0x1 << 1)
+#define KB_RIGHT_SHIFT_PRESSED (0x1 << 0)
+
+#define KB_SUSPEND_PRESSED (0x1 << 3)
+#define KB_SYSREQ_PRESSED (0x1 << 2)
+#define KB_LEFT_ALT_PRESSED (0x1 << 1)
+#define KB_LEFT_CTRL_PRESSED (0x1 << 0)
+
+//
+// BIOS Keyboard Device Structure
+//
+#define BIOS_KEYBOARD_DEV_SIGNATURE SIGNATURE_32 ('B', 'K', 'B', 'D')
+#define BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('c', 'b', 'k', 'h')
+
+typedef struct _BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY {
+ UINTN Signature;
+ EFI_HANDLE NotifyHandle;
+ EFI_KEY_DATA KeyData;
+ EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
+ LIST_ENTRY NotifyEntry;
+} BIOS_KEYBOARD_CONSOLE_IN_EX_NOTIFY;
+
+#define QUEUE_MAX_COUNT 32
+typedef struct {
+ UINTN Front;
+ UINTN Rear;
+ EFI_KEY_DATA Buffer[QUEUE_MAX_COUNT];
+} SIMPLE_QUEUE;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_ISA_IO_PROTOCOL *IsaIo;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextIn;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInputEx;
+ UINT16 DataRegisterAddress;
+ UINT16 StatusRegisterAddress;
+ UINT16 CommandRegisterAddress;
+ BOOLEAN ExtendedKeyboard;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Buffer storing EFI_KEY_DATA
+ //
+ SIMPLE_QUEUE Queue;
+
+ //
+ // Notification Function List
+ //
+ LIST_ENTRY NotifyList;
+ EFI_EVENT TimerEvent;
+
+} BIOS_KEYBOARD_DEV;
+
+#define BIOS_KEYBOARD_DEV_FROM_THIS(a) CR (a, BIOS_KEYBOARD_DEV, SimpleTextIn, BIOS_KEYBOARD_DEV_SIGNATURE)
+#define TEXT_INPUT_EX_BIOS_KEYBOARD_DEV_FROM_THIS(a) \
+ CR (a, \
+ BIOS_KEYBOARD_DEV, \
+ SimpleTextInputEx, \
+ BIOS_KEYBOARD_DEV_SIGNATURE \
+ )
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gBiosKeyboardDriverBinding;
+
+//
+// Driver Binding Protocol functions
+//
+
+/**
+ Check whether the driver supports this device.
+
+ @param This The Udriver binding protocol.
+ @param Controller The controller handle to check.
+ @param RemainingDevicePath The remaining device path.
+
+ @retval EFI_SUCCESS The driver supports this controller.
+ @retval other This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Starts the device with this driver.
+
+ @param This The driver binding instance.
+ @param Controller Handle of device to bind driver to.
+ @param RemainingDevicePath Optional parameter use to pick a specific child
+ device to start.
+
+ @retval EFI_SUCCESS The controller is controlled by the driver.
+ @retval Other This controller cannot be started.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop the device handled by this driver.
+
+ @param This The driver binding protocol.
+ @param Controller The controller to release.
+ @param NumberOfChildren The number of handles in ChildHandleBuffer.
+ @param ChildHandleBuffer The array of child handle.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+ @retval Others Fail to uninstall protocols attached on the device.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+//
+// Simple Text Input Protocol functions
+//
+/**
+ Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.
+
+ @param This Pointer of simple text Protocol.
+ @param ExtendedVerification Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
+
+ @retval EFI_SUCCESS The command byte is written successfully.
+ @retval EFI_DEVICE_ERROR Errors occurred during reseting keyboard.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Read out the scan code of the key that has just been stroked.
+
+ @param This Pointer of simple text Protocol.
+ @param Key Pointer for store the key that read out.
+
+ @retval EFI_SUCCESS The key is read out successfully.
+ @retval other The key reading failed.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+//
+// Private worker functions
+//
+/**
+ Waiting on the keyboard event, if there's any key pressed by the user, signal the event
+
+ @param Event The event that be siganlled when any key has been stroked.
+ @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
+
+**/
+VOID
+EFIAPI
+BiosKeyboardWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Check key buffer to get the key stroke status.
+
+ @param This Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL.
+
+ @retval EFI_SUCCESS A key is being pressed now.
+ @retval Other No key is now pressed.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardCheckForKey (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
+ );
+
+/**
+ Convert unicode combined with scan code of key to the counterpart of EFIScancode of it.
+
+ @param KeyChar Unicode of key.
+ @param ScanCode Scan code of key.
+
+ @return The value of EFI Scancode for the key.
+ @retval SCAN_NULL No corresponding value in the EFI convert table is found for the key.
+
+**/
+UINT16
+ConvertToEFIScanCode (
+ IN CHAR16 KeyChar,
+ IN UINT16 ScanCode
+ );
+
+/**
+ Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command
+ If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device
+ should not be in system.
+
+ @param BiosKeyboardPrivate Keyboard Private Data Struture
+
+ @retval TRUE Keyboard in System.
+ @retval FALSE Keyboard not in System.
+
+**/
+BOOLEAN
+CheckKeyboardConnect (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate
+ );
+
+/**
+ Timer event handler: read a series of key stroke from 8042
+ and put them into memory key buffer.
+ It is registered as running under TPL_NOTIFY
+
+ @param Event The timer event
+ @param Context A BIOS_KEYBOARD_DEV pointer
+
+**/
+VOID
+EFIAPI
+BiosKeyboardTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Reset the input device and optionaly run diagnostics
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existance of a keystroke via WaitForEvent () call.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data availiable.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+ hardware errors.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ );
+
+/**
+ Set certain state for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ @retval EFI_SUCCESS The device state was set successfully.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and could
+ not have the setting adjusted.
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ );
+
+/**
+ Register a notification function for a particular keystroke for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ information data for the key that was pressed.
+ @param KeyNotificationFunction Points to the function to be called when the key
+ sequence is typed specified by KeyData.
+ @param NotifyHandle Points to the unique handle assigned to the registered notification.
+
+
+ @retval EFI_SUCCESS The notification function was registered successfully.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necesssary data structures.
+ @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+ );
+
+/**
+ Remove a registered notification function from a particular keystroke.
+
+ @param This Protocol instance pointer.
+ @param NotificationHandle The handle of the notification function being unregistered.
+
+ @retval EFI_SUCCESS The notification function was unregistered successfully.
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+ );
+
+/**
+ Wait for a specific value to be presented in
+ Data register of Keyboard Controller by keyboard and then read it,
+ used in keyboard commands ack
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Value The value to be waited for
+ @param WaitForValueTimeOut The limit of microseconds for timeout
+
+ @retval EFI_SUCCESS The command byte is written successfully.
+ @retval EFI_TIMEOUT Timeout occurred during writing.
+
+**/
+EFI_STATUS
+KeyboardWaitForValue (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ IN UINT8 Value,
+ IN UINTN WaitForValueTimeOut
+ );
+
+/**
+ Write data byte to input buffer or input/output ports of Keyboard Controller with delay and waiting for buffer-empty state.
+
+ @param BiosKeyboardPrivate Keyboard instance pointer.
+ @param Data Data byte to write.
+
+ @retval EFI_SUCCESS The data byte is written successfully.
+ @retval EFI_TIMEOUT Timeout occurred during writing.
+
+**/
+EFI_STATUS
+KeyboardWrite (
+ IN BIOS_KEYBOARD_DEV *BiosKeyboardPrivate,
+ IN UINT8 Data
+ );
+
+/**
+ Free keyboard notify list.
+
+ @param ListHead The list head
+
+ @retval EFI_SUCCESS Free the notify list successfully
+ @retval EFI_INVALID_PARAMETER ListHead is invalid.
+
+**/
+EFI_STATUS
+BiosKeyboardFreeNotifyList (
+ IN OUT LIST_ENTRY *ListHead
+ );
+
+/**
+ Check if key is registered.
+
+ @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was registered.
+ @param InputData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval TRUE Key be pressed matches a registered key.
+ @retval FLASE Match failed.
+
+**/
+BOOLEAN
+IsKeyRegistered (
+ IN EFI_KEY_DATA *RegsiteredData,
+ IN EFI_KEY_DATA *InputData
+ );
+
+/**
+ Waiting on the keyboard event, if there's any key pressed by the user, signal the event
+
+ @param Event The event that be siganlled when any key has been stroked.
+ @param Context Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+
+**/
+VOID
+EFIAPI
+BiosKeyboardWaitForKeyEx (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+#endif
+
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.c b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.c
new file mode 100644
index 0000000..caeecf7
--- /dev/null
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.c
@@ -0,0 +1,183 @@
+/** @file
+
+Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the BSD License which accompanies this distribution. The
+full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "BiosKeyboard.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gBiosKeyboardComponentName = {
+ BiosKeyboardComponentNameGetDriverName,
+ BiosKeyboardComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gBiosKeyboardComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) BiosKeyboardComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) BiosKeyboardComponentNameGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mBiosKeyboardDriverNameTable[] = {
+ {
+ "eng;en",
+ L"BIOS[INT16] Keyboard Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mBiosKeyboardDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gBiosKeyboardComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.h b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.h
new file mode 100644
index 0000000..a20061b
--- /dev/null
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/ComponentName.h
@@ -0,0 +1,153 @@
+/** @file
+
+Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions
+of the BSD License which accompanies this distribution. The
+full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _BIOS_KEYBOARD_COMPONENT_NAME_H_
+#define _BIOS_KEYBOARD_COMPONENT_NAME_H_
+
+
+extern EFI_COMPONENT_NAME_PROTOCOL gBiosKeyboardComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gBiosKeyboardComponentName2;
+
+//
+// EFI Component Name Functions
+//
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+BiosKeyboardComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+#endif
diff --git a/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf
new file mode 100644
index 0000000..6166ba3
--- /dev/null
+++ b/IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/KeyboardDxe.inf
@@ -0,0 +1,68 @@
+## @file
+# Component description file for BiosKeyboard module.
+#
+# Ps2 Keyboard driver by using Legacy Bios protocol service and IsaIo protocol service.
+# This dirver uses legacy INT16 to get the key stroke status.
+#
+# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions
+# of the BSD License which accompanies this distribution. The
+# full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = KeyboardDxe
+ FILE_GUID = 5479662B-6AE4-49e8-A6BD-6DE4B625811F
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+
+ ENTRY_POINT = InitializeBiosKeyboard
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+# DRIVER_BINDING = gBiosKeyboardDriverBinding
+# COMPONENT_NAME = gBiosKeyboardComponentName
+#
+
+[Sources]
+ ComponentName.c
+ ComponentName.h
+ BiosKeyboard.c
+ BiosKeyboard.h
+
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ ReportStatusCodeLib
+ BaseMemoryLib
+ UefiLib
+ DebugLib
+ BaseLib
+
+[Protocols]
+ gEfiIsaIoProtocolGuid # PROTOCOL TO_START
+ gEfiSimpleTextInProtocolGuid # PROTOCOL BY_START
+ gEfiSimpleTextInputExProtocolGuid # PROTOCOL BY_START
+ gEfiLegacyBiosProtocolGuid # PROTOCOL TO_START
+ gEfiPs2PolicyProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+ gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+