summaryrefslogtreecommitdiff
path: root/Core/EM/usb/efiusbkb.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/usb/efiusbkb.c')
-rw-r--r--Core/EM/usb/efiusbkb.c3036
1 files changed, 3036 insertions, 0 deletions
diff --git a/Core/EM/usb/efiusbkb.c b/Core/EM/usb/efiusbkb.c
new file mode 100644
index 0000000..19802c8
--- /dev/null
+++ b/Core/EM/usb/efiusbkb.c
@@ -0,0 +1,3036 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbkb.c 87 5/28/15 5:01a Wilsonlee $
+//
+// $Revision: 87 $
+//
+// $Date: 5/28/15 5:01a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbkb.c $
+//
+// 87 5/28/15 5:01a Wilsonlee
+// [TAG] EIP218997
+// [Category] Improvement
+// [Description] Break the GetQueue loop if UninstallDevice is failed.
+// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c,
+// efiusbpoint.c, efiusbhid.c
+//
+// 86 4/23/15 11:28p Wilsonlee
+// [TAG] EIP213823
+// [Category] Improvement
+// [Description] The memory type for "mUsbKeyboardRecord" is changed
+// from EfiRuntimeServicesData to EfiBootServicesData.
+// [Files] efiusbkb.c
+//
+// 85 6/05/14 9:04p Wilsonlee
+// [TAG] EIP171786
+// [Category] Improvement
+// [Description] The PS2 scan code of "0x64 Keyboard Non-US \ and |" is
+// 0x56 and "0x67 Keypad =" is 0x59.
+// [Files] efiusbkb.c
+//
+// 84 12/20/13 7:36a Ryanchou
+// [TAG] EIP145616
+// [Category] Improvement
+// [Description] Check if the key has been registered before.
+// [Files] efiusbkb.c
+//
+// 83 11/26/13 4:09a Ryanchou
+// [TAG] EIP142509
+// [Category] Improvement
+// [Description] Added usage 0x87 and 0x89.
+// [Files] efiusbkb.c, efiusbkb.h
+//
+// 82 11/05/13 4:47a Ryanchou
+// [TAG] EIP135636
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] NumLock LED cannot be on/off properly.
+// [RootCause] It is the side effect of EIP #107429 changes, the
+// keyboard does not generate break code when pressing NumLock.
+// [Solution] Remove the EIP #107429 changes.
+// [Files] amiusb.c, usbkbd.c, efiusbkb.c
+//
+// 81 7/15/13 8:33a Rameshr
+// [TAG] EIP124584
+// [Category] Improvement
+// [Description] Tab, Backspace, Enter Key's are considerd as Non
+// printable Key's.
+// [Files] efiusbkb.c
+//
+// 80 3/07/13 9:10a Ryanchou
+// [TAG] EIP114307
+// [Category] Improvement
+// [Description] Verified the record present in the linked list and if
+// it's not present, start from the head node again.
+// [Files] efiusbkb.c
+//
+// 79 2/21/13 10:10a Ryanchou
+//
+// 77 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 76 12/09/12 12:12a Wilsonlee
+// [TAG] EIP107429
+// [Category] Improvement
+// [Description] Process the make code even if there is no break code.
+// [Files] efiusbkb.c, amiusb.c
+//
+// 75 11/26/12 9:57p Wilsonlee
+// [TAG] EIP100370
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The root cause is that a timer event of
+// UsbKeyEvent(KEY_POLLING_INTERVAL(500000)) would be created while the
+// function of SimpleTextInEX->RegisterKeyNotify() being invoked, but if
+// we disconnect the Simple text in controllers through
+// pBS->DisconnectController (HandleBuffer[Index], NULL, NULL), this timer
+// still alive.
+// [RootCause] The registered keys in mUsbKeyboardData queue are not
+// cleaned when the USB keyboard driver is removed, which cause the timer
+// to keep running and the stopping condition in function
+// UsbKbdUnregisterKeyNotify could not be reached.
+// [Solution] Examine the mUsbKeyboardData queue at UninstallUSBKeyboard
+// and remove the registered keys inside if they are not empty.
+// [Files] efiusbkb.c
+//
+// 74 11/15/12 3:47a Ryanchou
+//
+// 72 11/01/12 6:32a Deepthins
+// [TAG] EIP101102
+// [Category] Improvement
+// [Description] Multi Language is supported in USB driver
+// [Files] efiusbkb.c, efiusbkb.h
+//
+// 71 10/24/12 1:24a Wilsonlee
+// [TAG] EIP100370
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The root cause is that a timer event of
+// UsbKeyEvent(KEY_POLLING_INTERVAL(500000)) would be created while the
+// function of SimpleTextInEX->RegisterKeyNotify() being invoked, but if
+// we disconnect the Simple text in controllers through
+// pBS->DisconnectController (HandleBuffer[Index], NULL, NULL), this timer
+// still alive.
+// [RootCause] The registered keys in mUsbKeyboardData queue are not
+// cleaned when the USB keyboard driver is removed, which cause the timer
+// to keep running and the stopping condition in function
+// UsbKbdUnregisterKeyNotify could not be reached.
+// [Solution] Examine the mUsbKeyboardData queue at UninstallUSBKeyboard
+// and remove the registered keys inside if they are not empty.
+// [Files] efiusbkb.c
+//
+// 70 9/24/12 8:37a Ryanchou
+// Correct the KeyToggleState check in UsbKbdSetState.
+//
+// 69 8/29/12 8:36a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 68 8/06/12 11:45p Roberthsu
+// [TAG] EIP91889
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CSInSetState has no function when Bootup NumLock State
+// is set to OFF
+// [RootCause] UsbKbdSetState does not work.
+// [Solution] Store ToggleState in function UsbKbdSetState.
+// [Files] efiusbkb.c
+//
+// 67 5/22/12 10:32a Lavanyap
+// [TAG] EIP88049
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Keyboard LED status is synchronised when it is plugged out
+// and in.
+// [RootCause] Existing LED state is not updated when a keyboard is
+// installed.
+// [Solution] Updated existing LED state when a keyboard is installed.
+// [Files] efiusbkb.c
+//
+// 66 5/03/12 5:56a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 65 5/03/12 4:03a Ryanchou
+// [TAG] EIP85918
+// [Category] Improvement
+// [Description] Change the reset type of Ctrl+Alt+Del to EfiResetWarm.
+// [Files] efiusbkb.c
+//
+// 64 4/24/12 3:37a Roberthsu
+// [TAG] EIP83888
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Can not catch F8 key event on Keyboard
+// [RootCause] OS only call readkeystroke once.If OS get break key
+// readkeystroke will return EFI_NOT_READY.
+// [Solution] UsbKbdReadKeyStroke will serach available key in usb
+// data buffer.Fixed key repeat can not
+// work when efi to legacy or legacy to efi.
+// [Files] efiusbkb.c,usbkbd.c
+//
+// 63 4/24/12 2:14a Deepthins
+// [TAG] EIP85747
+// [Category] Improvement
+// [Description] USB-ReadKeyStrokeEx is returning EFI_SUCCESS with
+// KEY_STATE_EXPOSED for Caps, Num and Scroll Lock Key's.
+// KEY_STATE_EXPOSED only for the ShiftState Key's and not for togglestate
+// key's.
+// [Files] Efiusbkb.c, ps2kbd.c and kbc.h
+//
+// 62 4/10/12 2:38a Rameshr
+// [TAG] EIP87058
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Not able to recognise Pause Key Click using ReadKeyStroke
+// [RootCause] Pause Key detection should be done always and only the
+// pause key action should be controlled by PAUSEKEY_SUPPORT SDL token
+// [Solution] SDL token checking removed for the Pause Key detection
+// [Files] efiusbkb.c
+//
+// 61 3/20/12 10:32p Wilsonlee
+// [TAG] EIP83295
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System will hang at B2 when do S3/S4 long run test or DOS
+// reboot test.
+// [RootCause] It causes the stack problem when we call
+// IsUSBKeyboardBufferEmpty function.
+// [Solution] Change to use pointer as parameter to
+// IsUSBKeyboardBufferEmpty function.
+// [Files] efiusbkb.c, efisubkb.h, usbmass.c, ehci.c
+//
+// 60 3/02/12 3:55a Rameshr
+// [TAG] EIP81563
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Press SHIFT key will result in the ReadKeyStroke return
+// unexpected ScanCode and UnicodeChar
+// [RootCause] When the Partial Key returned, ScanCode and Unicode are
+// not filled correctly.
+// [Solution] Initilized the Scan code and UniCode to NULL Value.
+// [Files] Efiusbkb.c
+//
+// 59 2/21/12 5:24a Rameshr
+// [TAG] EIP82772
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Usb Keyboard works even if the SimpleTextin uninstalled for
+// the UsbKeyboard
+// [RootCause] RegsiterKeyNotify Function event not stopped even after
+// SimpleTextin Uninstalled
+// [Solution] Stopped the KeyPolling Event if no more USB keyboard in
+// the system
+// [Files] efiusbkb.c
+//
+// 58 12/29/11 12:37a Deepthins
+// [TAG] EIP77537
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Multiple USB keyboard are not synchronized properly
+// [RootCause] In USB driver for the new Simpletextin ( USB keyboard)
+// device, the memory allocated for the device is saved in gUsbKbd
+// pointer. The same pointer is used when multiple simple text in device
+// installed.
+// [Solution] USB_KB_DEV structure is divided into 2 structure, one is
+// common for all the Simpletextin and another structure is for specific
+// to the SimpleTextin Device.Based on it, allocate the memory for
+// structure and use it. When the stop function is called, we should free
+// only the structure that is specific for device.
+// [Files] Efiusbkb.c, Efiusbhid.c, efiusbkb.c
+//
+// 57 12/14/11 2:09a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 56 9/23/11 12:32a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h, efiusbhid.c
+//
+// 55 8/25/11 11:49a Davidd
+// [TAG] EIPEIP55336
+// [Description] Removed EFI_DEADLOOP() in ClearUsbKbBuffer function
+// from previous check-in file version 54. It was used during testing and
+// inadvertently left over at the time of check-in.
+// [Files] efiusbkb.c
+//
+// 54 8/16/11 2:29p Davidd
+// [TAG] EIP55336
+// [Category] New Feature
+// [Description] Add optional code to clear keyboard buffer at
+// ReadyToBoot in USB driver
+// [Files] Efiusbkb.c
+// Usbsrc.sdl
+//
+// 53 7/15/11 6:23a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+// 52 5/30/11 2:54a Ryanchou
+// [TAG] EIP60562
+// [Category] Improvement
+// [Description] F11/F12 efi scan code correction.
+// [Files] efiusbkb.c
+//
+// 51 5/03/11 10:47a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 50 3/04/11 1:30p Olegi
+//
+// 49 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 48 10/12/10 4:37a Rameshr
+// [TAG] - EIP 42956
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - KeyNotificationFunction gets control twice for every key
+// press in USB keyboard
+// [RootCause] - KeyNotificationFunction gets called for each Key Press
+// and Key Release
+// [Solution] - Previous check-in has the wrong solution and corrected
+// now.
+// [Files] - EfiUsbKb.c
+//
+// 47 9/13/10 1:56a Rameshr
+// [TAG] - EIP 42956
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - KeyNotificationFunction gets control twice for every key
+// press in USB keyboard
+// [RootCause] - KeyNotificationFunction gets called for each Key Press
+// and Key Release
+// [Solution] - Added code to check only call KeyNotificationFunction on
+// Key Press.
+// [Files] - EfiUsbKb.c
+//
+// 46 7/20/10 4:34a Rameshr
+// Corrected the FreePool call in UnRegisterKeyNotify function
+//
+// 45 5/14/10 10:57a Olegi
+// - Tabs converted to spaces
+// - Added FreePool call in UnregisterKeyNotify function
+//
+// 44 5/10/10 2:31a Rameshr
+// Issue:Usb Keyboard driver doesn't handle the Shift Key properly in
+// RegsiterkeyNotify function
+// Solution: ShiftKeyState and KeyToggleState verified for
+// RegisterKeyNotify callback function.
+// EIP 38213
+//
+// 43 5/10/10 2:04a Rameshr
+// PrintScreen/SysRq key, Menu Key, Left Logo and Right Logo Key support
+// in USB Keyboard driver
+// EIP 38214
+//
+// 42 5/10/10 1:57a Rameshr
+// Issue:UsbKeyboard Driver doesn’t differentiate between Left Shift and
+// Right Shift Key.
+// Solution: modified the driver to differentiate between Left
+// Shift/Alt/Ctrl and Right Shift/Alt/Ctrl Key's.
+// EIP 38256
+//
+// 41 2/24/10 3:52p Olegi
+// Updated PS2ScanCodeIsValid field while returning AMI_KEYCODE from USB
+// keyboard.
+//
+// 40 2/23/10 1:36p Olegi
+// Work around Klockwork issues. EIP34370
+//
+// 39 9/15/09 12:01p Olegi
+// Implemented a circular buffer in KeypressCallback; related (indirectly)
+// to EIP#25841
+//
+// 38 8/13/09 2:59p Rameshr
+// When item "num-lock status" set off, Num-lock will keep open until in
+// DOS.
+// EIP:21757
+//
+// 37 5/07/09 5:20p Olegi
+// Numeric keypad scancode correction.
+//
+// 36 3/30/09 10:33a Pats
+// Issue: EIP 19547 - Pause key support needed in Aptio
+// Solution: Functions UsbParseKey and USBKeyCodeToEFIScanCode modified to
+// pass EFI_KEY vaule of pause key on rather than rejecting it.
+//
+// 35 1/22/09 3:00p Olegi
+// Bugfix for EIP#19039.
+//
+// 34 1/07/09 11:01a Olegi
+// Bugfix for EIP#18267
+//
+// 33 11/17/08 10:20a Rameshraju
+// Problem:SCT failure on RegisterKeyNotify, SetState and
+// UnregisterKeyNotify.
+// Fix : Validated the input parameters for RegisterKeyNotify, SetState
+// and UnregisterKeyNotify.
+// EIP:17578
+//
+// 32 10/08/08 4:34p Olegi
+// Implemented the Register/Unregister key notofocation function in
+// SimpletextinEx protocol.
+//
+// 31 10/03/08 3:32p Olegi
+//
+// 30 9/05/08 4:15p Olegi
+// fpCallbackNotify functions removed.
+//
+// 29 8/07/08 11:52a Olegi
+// Bugfix in UsbKbdReadKeyStrokeEx.
+//
+// 28 6/05/08 3:34p Olegi
+//
+// 27 6/05/08 3:27p Olegi
+// Bugfix in processing '5' key on a keypad: when NumLock is off, it
+// should not produce a character.
+//
+// 26 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 25 12/17/07 5:42p Rameshraju
+// Added the core revision check for the AMI Keycode to build with OLD
+// core.
+//
+// 24 10/25/07 4:47p Olegi
+//
+// 23 10/23/07 4:16p Olegi
+// AmiKeycode protocol implementation.
+//
+// 22 9/18/07 12:18p Olegi
+//
+// 19 7/26/07 4:26p Olegi
+// F11 and F12 keys are not ignored anymore.
+//
+// 18 7/13/07 11:44a Olegi
+// F11 and F12 codes added.
+//
+// 17 4/17/07 8:22a Olegi
+// Bugfix in UninstallUSBKeyboard function.
+//
+// 16 3/20/07 1:29p Olegi
+//
+// 15 12/08/06 3:25p Olegi
+// Bugfix in the sequence of multiple keyboard
+// installation/deinstallation.
+//
+// 13 10/12/06 7:12p Andriyn
+// Support unexpected plug-off USB device
+//
+// 12 7/19/06 3:54p Olegi
+//
+// 11 5/03/06 9:59a Olegi
+//
+// 10 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 9 3/01/06 3:53p Olegi
+// Added USB_LEGACY_PLATFORM_SUPPORT.
+//
+// 8 1/11/06 11:54a Olegi
+// EfiResetShutdown has changed to EfiResetCold.
+//
+// 7 11/22/05 4:06p Andriyn
+// Fix: EFI shell hangs when Ctrl-Al-Del reset the system from USB
+// keyboard
+//
+// 6 6/15/05 4:05p Olegi
+// EfiResetShutdown is replaced with EfiResetWarm on Ctl+Alt+Del.
+//
+// 5 6/01/05 5:10p Olegi
+// Debug message shortened.
+//
+// 4 5/19/05 8:06p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiUsbKb.c
+//
+// Description: USB Keyboard Efi driver implementation
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "efiusbkb.h"
+#include "usbkbd.h"
+
+#include "componentname.h"
+#include "usbbus.h"
+
+#ifndef KEY_STATE_EXPOSED
+#define KEY_STATE_EXPOSED 0x40
+#endif
+
+#define KEY_POLLING_INTERVAL 500000
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern EFI_GUID gEfiHotPlugDeviceGuid;
+extern EFI_EVENT UsbKeyEvent;
+
+EFI_STATUS UsbCheckKeyNotify(UINT8 Key);
+
+USB_KEYBOARD_DATA* gUsbKeyboardData;
+
+#if CLEAR_USB_KB_BUFFER_AT_READYTOBOOT
+EFI_EVENT gClearUsbKbBufferEvent;
+#endif
+
+typedef struct _KEY_WAITING_RECORD{
+ DLINK Link;
+ USB_KB_DEV* UsbKbDev; //(EIP100370+)
+ EFI_KEY_DATA Context;
+ EFI_KEY_NOTIFY_FUNCTION Callback;
+ BOOLEAN CallbackStatus;
+} KEY_WAITING_RECORD;
+
+DLIST mUsbKeyboardData;
+KEY_WAITING_RECORD *mUsbKeyboardRecord;
+BOOLEAN KeyProcessed=TRUE;
+static EFI_GUID gAmiMultiLangSupportGuid = AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID;
+AMI_MULTI_LANG_SUPPORT_PROTOCOL *gMultiLangSupportProtocol;
+
+
+//
+// USB Key Code to Efi key mapping table
+// Format:
+// <efi scan code>, <unicode w/o shift>, <unicode w shift>, <PS2 scan code>
+//
+static
+UINT8 KeyConvertionTable[USB_KEYCODE_MAX_MAKE][4] = {
+ SCAN_NULL, 'a', 'A', 0x1e, // 0x04
+ SCAN_NULL, 'b', 'B', 0x30, // 0x05
+ SCAN_NULL, 'c', 'C', 0x2e, // 0x06
+ SCAN_NULL, 'd', 'D', 0x20, // 0x07
+ SCAN_NULL, 'e', 'E', 0x12, // 0x08
+ SCAN_NULL, 'f', 'F', 0x21, // 0x09
+ SCAN_NULL, 'g', 'G', 0x22, // 0x0A
+ SCAN_NULL, 'h', 'H', 0x23, // 0x0B
+ SCAN_NULL, 'i', 'I', 0x17, // 0x0C
+ SCAN_NULL, 'j', 'J', 0x24, // 0x0D
+ SCAN_NULL, 'k', 'K', 0x25, // 0x0E
+ SCAN_NULL, 'l', 'L', 0x26, // 0x0F
+ SCAN_NULL, 'm', 'M', 0x32, // 0x10
+ SCAN_NULL, 'n', 'N', 0x31, // 0x11
+ SCAN_NULL, 'o', 'O', 0x18, // 0x12
+ SCAN_NULL, 'p', 'P', 0x19, // 0x13
+ SCAN_NULL, 'q', 'Q', 0x10, // 0x14
+ SCAN_NULL, 'r', 'R', 0x13, // 0x15
+ SCAN_NULL, 's', 'S', 0x1f, // 0x16
+ SCAN_NULL, 't', 'T', 0x14, // 0x17
+ SCAN_NULL, 'u', 'U', 0x16, // 0x18
+ SCAN_NULL, 'v', 'V', 0x2f, // 0x19
+ SCAN_NULL, 'w', 'W', 0x11, // 0x1A
+ SCAN_NULL, 'x', 'X', 0x2d, // 0x1B
+ SCAN_NULL, 'y', 'Y', 0x15, // 0x1C
+ SCAN_NULL, 'z', 'Z', 0x2c, // 0x1D
+ SCAN_NULL, '1', '!', 0x02, // 0x1E
+ SCAN_NULL, '2', '@', 0x03, // 0x1F
+ SCAN_NULL, '3', '#', 0x04, // 0x20
+ SCAN_NULL, '4', '$', 0x05, // 0x21
+ SCAN_NULL, '5', '%', 0x06, // 0x22
+ SCAN_NULL, '6', '^', 0x07, // 0x23
+ SCAN_NULL, '7', '&', 0x08, // 0x24
+ SCAN_NULL, '8', '*', 0x09, // 0x25
+ SCAN_NULL, '9', '(', 0x0a, // 0x26
+ SCAN_NULL, '0', ')', 0x0b, // 0x27
+ SCAN_NULL, 0x0d, 0x0d, 0x1c, // 0x28 Enter
+ SCAN_ESC, 0x00, 0x00, 0x01, // 0x29 Esc
+ SCAN_NULL, 0x08, 0x08, 0x0e, // 0x2A Backspace
+ SCAN_NULL, 0x09, 0x09, 0x0f, // 0x2B Tab
+ SCAN_NULL, ' ', ' ', 0x39, // 0x2C Spacebar
+ SCAN_NULL, '-', '_', 0x0c, // 0x2D
+ SCAN_NULL, '=', '+', 0x0d, // 0x2E
+ SCAN_NULL, '[', '{', 0x1a, // 0x2F
+ SCAN_NULL, ']', '}', 0x1b, // 0x30
+ SCAN_NULL, '\\', '|', 0x2b, // 0x31
+ SCAN_NULL, '\\', '|', 0x2b, // 0x32 Keyboard US \ and |
+ SCAN_NULL, ';', ':', 0x27, // 0x33
+ SCAN_NULL, '\'', '"', 0x28, // 0x34
+ SCAN_NULL, '`', '~', 0x29, // 0x35 Keyboard Grave Accent and Tlide
+ SCAN_NULL, ',', '<', 0x33, // 0x36
+ SCAN_NULL, '.', '>', 0x34, // 0x37
+ SCAN_NULL, '/', '?', 0x35, // 0x38
+ SCAN_NULL, 0x00, 0x00, 0x3a, // 0x39 CapsLock
+ SCAN_F1, 0x00, 0x00, 0x3b, // 0x3A
+ SCAN_F2, 0x00, 0x00, 0x3c, // 0x3B
+ SCAN_F3, 0x00, 0x00, 0x3d, // 0x3C
+ SCAN_F4, 0x00, 0x00, 0x3e, // 0x3D
+ SCAN_F5, 0x00, 0x00, 0x3f, // 0x3E
+ SCAN_F6, 0x00, 0x00, 0x40, // 0x3F
+ SCAN_F7, 0x00, 0x00, 0x41, // 0x40
+ SCAN_F8, 0x00, 0x00, 0x42, // 0x41
+ SCAN_F9, 0x00, 0x00, 0x43, // 0x42
+ SCAN_F10, 0x00, 0x00, 0x44, // 0x43
+ //(EIP60562)>
+ SCAN_F11, 0x00, 0x00, 0x57, // 0x44 F11
+ SCAN_F12, 0x00, 0x00, 0x58, // 0x45 F12
+ //<(EIP60562)
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x46 PrintScreen
+ SCAN_NULL, 0x00, 0x00, 0x46, // 0x47 Scroll Lock
+ SCAN_PAUSE, 0x00, 0x00, 0x00, // 0x48 Pause
+ SCAN_INSERT, 0x00, 0x00, 0x52, // 0x49
+ SCAN_HOME, 0x00, 0x00, 0x47, // 0x4A
+ SCAN_PAGE_UP, 0x00, 0x00, 0x49, // 0x4B
+ SCAN_DELETE, 0x00, 0x00, 0x53, // 0x4C
+ SCAN_END, 0x00, 0x00, 0x4f, // 0x4D
+ SCAN_PAGE_DOWN, 0x00, 0x00, 0x51, // 0x4E
+ SCAN_RIGHT, 0x00, 0x00, 0x4d, // 0x4F
+ SCAN_LEFT, 0x00, 0x00, 0x4b, // 0x50
+ SCAN_DOWN, 0x00, 0x00, 0x50, // 0x51
+ SCAN_UP, 0x00, 0x00, 0x48, // 0x52
+ SCAN_NULL, 0x00, 0x00, 0x45, // 0x53 NumLock
+ SCAN_NULL, '/', '/', 0x35, // 0x54
+ SCAN_NULL, '*', '*', 0x37, // 0x55
+ SCAN_NULL, '-', '-', 0x4a, // 0x56
+ SCAN_NULL, '+', '+', 0x4e, // 0x57
+ SCAN_NULL, 0x0d, 0x0d, 0x1c, // 0x58
+ SCAN_END, '1', '1', 0x4f, // 0x59
+ SCAN_DOWN, '2', '2', 0x50, // 0x5A
+ SCAN_PAGE_DOWN, '3', '3', 0x51, // 0x5B
+ SCAN_LEFT, '4', '4', 0x4b, // 0x5C
+ SCAN_NULL, '5', '5', 0x4c, // 0x5D
+ SCAN_RIGHT, '6', '6', 0x4d, // 0x5E
+ SCAN_HOME, '7', '7', 0x47, // 0x5F
+ SCAN_UP, '8', '8', 0x48, // 0x60
+ SCAN_PAGE_UP, '9', '9', 0x49, // 0x61
+ SCAN_INSERT, '0', '0', 0x52, // 0x62
+ SCAN_DELETE, '.', '.', 0x53, // 0x63
+ SCAN_NULL, '\\', '|', 0x56, // 0x64 Keyboard Non-US \ and |
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x65 Keyboard Application
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x66 Keyboard Power
+ SCAN_NULL, '=' , '=', 0x59, // 0x67 Keypad =
+
+ SCAN_F13, 0x00, 0x00, 0x64, // 0x68 F13
+ SCAN_F14, 0x00, 0x00, 0x65, // 0x69 F14
+ SCAN_F15, 0x00, 0x00, 0x66, // 0x6A F15
+ SCAN_F16, 0x00, 0x00, 0x67, // 0x6B F16
+ SCAN_F17, 0x00, 0x00, 0x68, // 0x6C F17
+ SCAN_F18, 0x00, 0x00, 0x69, // 0x6D F18
+ SCAN_F19, 0x00, 0x00, 0x6A, // 0x6E F19
+ SCAN_F20, 0x00, 0x00, 0x6B, // 0x6F F20
+ SCAN_F21, 0x00, 0x00, 0x6C, // 0x70 F21
+ SCAN_F22, 0x00, 0x00, 0x6D, // 0x71 F22
+ SCAN_F23, 0x00, 0x00, 0x6E, // 0x72 F23
+ SCAN_F24, 0x00, 0x00, 0x76, // 0x73 F24
+
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x74
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x75
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x76
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x77
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x78
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x79
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7A
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7B
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7C
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7D
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7E
+ SCAN_MUTE, 0x00, 0x00, 0x00, // 0x7F
+ SCAN_VOLUME_UP, 0x00, 0x00, 0x00, // 0x80
+ SCAN_VOLUME_DOWN, 0x00, 0x00, 0x00, // 0x81
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x82
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x83
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x84
+ SCAN_NULL, '.', 0x00, 0x7E, // 0x85
+ SCAN_NULL, '=', 0x00, 0x00, // 0x86
+ SCAN_NULL, '\\', '_', 0x73, // 0x87 backslash
+ SCAN_NULL, 0x00, 0x00, 0x70, // 0x88
+ SCAN_NULL, 0xA5, '|', 0x7D, // 0x89 Yen Symbol
+ };
+
+KB_MODIFIER KB_Mod[8] = {
+ { MOD_CONTROL_L, 0xe0 }, // 11100000
+ { MOD_CONTROL_R, 0xe4 }, // 11100100
+ { MOD_SHIFT_L, 0xe1 }, // 11100001
+ { MOD_SHIFT_R, 0xe5 }, // 11100101
+ { MOD_ALT_L, 0xe2 }, // 11100010
+ { MOD_ALT_R, 0xe6 }, // 11100110
+ { MOD_WIN_L, 0xe3 }, // 11100011
+ { MOD_WIN_R, 0xe7 }, // 11100111
+};
+
+
+UINT8 UsbToEfiKeyTable[USB_KEYCODE_MAX_MAKE] = {
+ EfiKeyC1, // 'a', 'A', 0x1e, // 0x04
+ EfiKeyB5, // 'b', 'B', 0x30, // 0x05
+ EfiKeyB3, // 'c', 'C', 0x2e, // 0x06
+ EfiKeyC3, // 'd', 'D', 0x20, // 0x07
+ EfiKeyD3, // 'e', 'E', 0x12, // 0x08
+ EfiKeyC4, // 'f', 'F', 0x21, // 0x09
+ EfiKeyC5, // 'g', 'G', 0x22, // 0x0A
+ EfiKeyC6, // 'h', 'H', 0x23, // 0x0B
+ EfiKeyD8, // 'i', 'I', 0x17, // 0x0C
+ EfiKeyC7, // 'j', 'J', 0x24, // 0x0D
+ EfiKeyC8, // 'k', 'K', 0x25, // 0x0E
+ EfiKeyC9, // 'l', 'L', 0x26, // 0x0F
+ EfiKeyB7, // 'm', 'M', 0x32, // 0x10
+ EfiKeyB6, // 'n', 'N', 0x31, // 0x11
+ EfiKeyD9, // 'o', 'O', 0x18, // 0x12
+ EfiKeyD10,// 'p', 'P', 0x19, // 0x13
+ EfiKeyD1, // 'q', 'Q', 0x10, // 0x14
+ EfiKeyD4, // 'r', 'R', 0x13, // 0x15
+ EfiKeyC2, // 's', 'S', 0x1f, // 0x16
+ EfiKeyD5, // 't', 'T', 0x14, // 0x17
+ EfiKeyD7, // 'u', 'U', 0x16, // 0x18
+ EfiKeyB4, // 'v', 'V', 0x2f, // 0x19
+ EfiKeyD2, // 'w', 'W', 0x11, // 0x1A
+ EfiKeyB2, // 'x', 'X', 0x2d, // 0x1B
+ EfiKeyD6, // 'y', 'Y', 0x15, // 0x1C
+ EfiKeyB1, // 'z', 'Z', 0x2c, // 0x1D
+ EfiKeyE1, // '1', '!', 0x02, // 0x1E
+ EfiKeyE2, // '2', '@', 0x03, // 0x1F
+ EfiKeyE3, // '3', '#', 0x04, // 0x20
+ EfiKeyE4, // '4', '$', 0x05, // 0x21
+ EfiKeyE5, // '5', '%', 0x06, // 0x22
+ EfiKeyE6, // '6', '^', 0x07, // 0x23
+ EfiKeyE7, // '7', '&', 0x08, // 0x24
+ EfiKeyE8, // '8', '*', 0x09, // 0x25
+ EfiKeyE9, // '9', '(', 0x0a, // 0x26
+ EfiKeyE10, // '0', ')', 0x0b, // 0x27
+ EfiKeyEnter,// 0x0d, 0x0d, 0x1c, // 0x28 Enter
+ EfiKeyEsc, // 0x00, 0x00, 0x01, // 0x29 Esc
+ EfiKeyBackSpace, // 0x08, 0x08, 0x0e, // 0x2A Backspace
+ EfiKeyTab, // 0x09, 0x09, 0x0f, // 0x2B Tab
+ EfiKeySpaceBar, // ' ', ' ', 0x39, // 0x2C Spacebar
+ EfiKeyE11, // '-', '_', 0x0c, // 0x2D
+ EfiKeyE12, // '=', '+', 0x0d, // 0x2E
+ EfiKeyD11, // '[', '{', 0x1a, // 0x2F
+ EfiKeyD12, // ']', '}', 0x1b, // 0x30
+ EfiKeyD13, // '\\', '|', 0x2b, // 0x31
+ EfiKeyC12, // '\\', '|', 0x2b, // 0x32 Keyboard Non-US # and ~
+ EfiKeyC10, // ';', ':', 0x27, // 0x33
+ EfiKeyC11, // '\'', '"', 0x28, // 0x34
+ EfiKeyE0, // '`', '~', 0x29, // 0x35 Keyboard Grave Accent and Tlide
+ EfiKeyB8, // ',', '<', 0x33, // 0x36
+ EfiKeyB9, // '.', '>', 0x34, // 0x37
+ EfiKeyB10, // '/', '?', 0x35, // 0x38
+ EfiKeyCapsLock, // 0x00, 0x00, 0x00, // 0x39 CapsLock
+ EfiKeyF1, // 0x00, 0x00, 0x3b, // 0x3A
+ EfiKeyF2, // 0x00, 0x00, 0x3c, // 0x3B
+ EfiKeyF3, // 0x00, 0x00, 0x3d, // 0x3C
+ EfiKeyF4, // 0x00, 0x00, 0x3e, // 0x3D
+ EfiKeyF5, // 0x00, 0x00, 0x3f, // 0x3E
+ EfiKeyF6, // 0x00, 0x00, 0x40, // 0x3F
+ EfiKeyF7, // 0x00, 0x00, 0x41, // 0x40
+ EfiKeyF8, // 0x00, 0x00, 0x42, // 0x41
+ EfiKeyF9, // 0x00, 0x00, 0x43, // 0x42
+ EfiKeyF10, // 0x00, 0x00, 0x44, // 0x43
+ EfiKeyF11, // 0x00, 0x00, 0x85, // 0x44 F11
+ EfiKeyF12, // 0x00, 0x00, 0x86, // 0x45 F12
+ EfiKeyPrint, // 0x00, 0x00, 0x00, // 0x46 PrintScreen
+ EfiKeySLck, // 0x00, 0x00, 0x00, // 0x47 Scroll Lock
+ EfiKeyPause, // 0x00, 0x00, 0x00, // 0x48 Pause
+ EfiKeyIns, // 0x00, 0x00, 0x52, // 0x49
+ EfiKeyHome, // 0x00, 0x00, 0x47, // 0x4A
+ EfiKeyPgUp, // 0x00, 0x00, 0x49, // 0x4B
+ EfiKeyDel, // 0x00, 0x00, 0x53, // 0x4C
+ EfiKeyEnd, // 0x00, 0x00, 0x4f, // 0x4D
+ EfiKeyPgDn, // 0x00, 0x00, 0x51, // 0x4E
+ EfiKeyRightArrow, // 0x00, 0x00, 0x4d, // 0x4F
+ EfiKeyLeftArrow, // 0x00, 0x00, 0x4b, // 0x50
+ EfiKeyDownArrow, // 0x00, 0x00, 0x50, // 0x51
+ EfiKeyUpArrow, // 0x00, 0x00, 0x48, // 0x52
+ EfiKeyNLck, // 0x00, 0x00, 0x00, // 0x53 NumLock
+ EfiKeySlash, // '/', '/', 0x35, // 0x54
+ EfiKeyAsterisk, // '*', '*', 0x37, // 0x55
+ EfiKeyMinus, // '-', '-', 0x4a, // 0x56
+ EfiKeyPlus, // '+', '+', 0x4e, // 0x57
+ EfiKeyEnter, // 0x0d, 0x0d, 0x1c, // 0x58
+ EfiKeyOne, // '1', '1', 0x02, // 0x59
+ EfiKeyTwo, // '2', '2', 0x03, // 0x5A
+ EfiKeyThree, // '3', '3', 0x04, // 0x5B
+ EfiKeyFour, // '4', '4', 0x05, // 0x5C
+ EfiKeyFive, // '5', '5', 0x06, // 0x5D
+ EfiKeySix, // '6', '6', 0x07, // 0x5E
+ EfiKeySeven, // '7', '7', 0x08, // 0x5F
+ EfiKeyEight, // '8', '8', 0x09, // 0x60
+ EfiKeyNine, // '9', '9', 0x0a, // 0x61
+ EfiKeyZero, // '0', '0', 0x0b, // 0x62
+ EfiKeyPeriod, // '.', '.', 0x53, // 0x63
+ EfiKeyD13, // '\\', '|', 0x2b, // 0x64 Keyboard Non-US \ and |
+ 0, // 0x00, 0x00, 0x00, // 0x65 Keyboard Application
+ 0, // 0x00, 0x00, 0x00, // 0x66 Keyboard Power
+ 0, // '=' , '=', 0x0d // 0x67 Keypad =
+
+ 0, // 0x00, 0x00, 0x08, // 0x68 F13
+ 0, // 0x00, 0x00, 0x10, // 0x69 F14
+ 0, // 0x00, 0x00, 0x18, // 0x6A F15
+ 0, // 0x00, 0x00, 0x20, // 0x6B F16
+ 0, // 0x00, 0x00, 0x28, // 0x6C F17
+ 0, // 0x00, 0x00, 0x30, // 0x6D F18
+ 0, // 0x00, 0x00, 0x38, // 0x6E F19
+ 0, // 0x00, 0x00, 0x40, // 0x6F F20
+ 0, // 0x00, 0x00, 0x48, // 0x70 F21
+ 0, // 0x00, 0x00, 0x50, // 0x71 F22
+ 0, // 0x00, 0x00, 0x57, // 0x72 F23
+ 0, // 0x00, 0x00, 0x5F, // 0x73 F24
+
+ 0, // 0x00, 0x00, 0x00, // 0x74
+ 0, // 0x00, 0x00, 0x00, // 0x75
+ 0, // 0x00, 0x00, 0x00, // 0x76
+ 0, // 0x00, 0x00, 0x00, // 0x77
+ 0, // 0x00, 0x00, 0x00, // 0x78
+ 0, // 0x00, 0x00, 0x00, // 0x79
+ 0, // 0x00, 0x00, 0x00, // 0x7A
+ 0, // 0x00, 0x00, 0x00, // 0x7B
+ 0, // 0x00, 0x00, 0x00, // 0x7C
+ 0, // 0x00, 0x00, 0x00, // 0x7D
+ 0, // 0x00, 0x00, 0x00, // 0x7E
+ 0, // 0x00, 0x00, 0x00, // 0x7F
+ 0, // 0x00, 0x00, 0x00, // 0x80
+ 0, // 0x00, 0x00, 0x00, // 0x81
+ 0, // 0x00, 0x00, 0x00, // 0x82
+ 0, // 0x00, 0x00, 0x00, // 0x83
+ 0, // 0x00, 0x00, 0x00, // 0x84
+ 0, // '.', 0x00, 0x6D, // 0x85
+ 0, // '=', 0x00, 0x00, // 0x86
+ EfiKeyB0, // 0x00, 0x00, 0x51, // 0x87
+ 0, // '\\', 0x00, 0x13, // 0x88
+ EfiKeyD13, // 0xA5, 0x00, 0x6A, // 0x89 Yen Symbol
+};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdGetControllerName
+//
+// Description: USB EFI keyboard driver driver protocol function that
+// returns the keyboard controller name.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+UsbKbdGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitUSBKeyboard
+//
+// Description: Initialize USB Keyboard device and all private data structures.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS or EFI_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitUSBKeyboard()
+{
+ InitUSBKeyBuffer(&(gUsbKeyboardData->KeyboardBuffer));
+ InitUSBKeyCharBuffer();
+ gUsbData->EfiKeyboardBuffer = &gUsbKeyboardData->KeyboardBuffer;
+
+ gUsbKeyboardData->LeftCtrlOn = 0;
+ gUsbKeyboardData->LeftAltOn = 0;
+ gUsbKeyboardData->LeftShiftOn = 0;
+ gUsbKeyboardData->RightCtrlOn = 0;
+ gUsbKeyboardData->RightAltOn = 0;
+ gUsbKeyboardData->RightShiftOn = 0;
+ gUsbKeyboardData->SysRqOn = 0;
+ gUsbKeyboardData->MenuOn = 0;
+ gUsbKeyboardData->LeftLogoOn = 0;
+ gUsbKeyboardData->RightLogoOn = 0;
+ gUsbKeyboardData->NumLockOn = 0;
+ gUsbKeyboardData->CapsOn = 0;
+ gUsbKeyboardData->ScrLkOn = 0;
+ //(EIP91889-)>
+// gUsbKeyboardData->ToggleState =0;
+// SetKeyLED();
+ //<(EIP91889-)
+ gBS->SetMem(gUsbKeyboardData->LastKeyCodeArray, sizeof(UINT8)*8, 0);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KeypressCallback
+//
+// Description: This routine is called every time the keyboard data is updated
+//
+// Input: HcStruc, DevInfo, fpBuf2 always NULL
+// Buf1 - Pointer to 8 bytes USB data array
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KeypressCallback(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Buf1,
+ UINT8* Buf2)
+
+{
+
+ UINT8 *CurKeyCodeBuffer;
+ UINT8 *OldKeyCodeBuffer;
+ UINT8 CurModifierMap;
+ UINT8 OldModifierMap;
+ UINT8 i;
+ UINT8 j;
+ BOOLEAN Down;
+ BOOLEAN KeyRelease,KeyPress;
+ UINT8 SavedTail;
+ USB_KEY UsbKey;
+ UINT8 NewRepeatKey = 0;
+ UINT8 *fPtr, *fPtrEnd;
+
+ OldKeyCodeBuffer = gUsbKeyboardData->LastKeyCodeArray;
+
+ if(gUsbData->aKBCUsbDataBufferHead == gUsbData->aKBCUsbDataBufferTail) {
+ return EFI_SUCCESS;
+ }
+
+ fPtrEnd = gUsbData->aKBCUsbDataBufferStart +
+ sizeof (gUsbData->aKBCUsbDataBufferStart);
+
+ fPtr = gUsbData->aKBCUsbDataBufferTail;
+ CurKeyCodeBuffer = fPtr;
+ fPtr+=8;
+
+ //
+ // Check for buffer end condition
+ //
+ if(fPtr >= fPtrEnd)
+ fPtr = gUsbData->aKBCUsbDataBufferStart;
+ gUsbData->aKBCUsbDataBufferTail = fPtr;
+
+ //
+ // checks for new key stroke.
+ // if no new key got, return immediately.
+ //
+ for (i = 0; i < 8; i ++) {
+ if(OldKeyCodeBuffer[i] != CurKeyCodeBuffer[i]) {
+ break;
+ }
+ }
+
+ if(i == 8) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Parse the modifier key
+ //
+ CurModifierMap = CurKeyCodeBuffer[0];
+ OldModifierMap = OldKeyCodeBuffer[0];
+
+ //
+ // handle modifier key's pressing or releasing situation.
+ //
+ for (i = 0; i < 8; i ++) {
+ if ((CurModifierMap & KB_Mod[i].Mask) !=
+ (OldModifierMap & KB_Mod[i].Mask)) {
+ //
+ // if current modifier key is up, then
+ // CurModifierMap & KB_Mod[i].Mask = 0;
+ // otherwize it is a non-zero value.
+ // Inserts the pressed modifier key into key buffer.
+ //
+ Down = (UINT8)(CurModifierMap & KB_Mod[i].Mask);
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),KB_Mod[i].Key,Down);
+ }
+ }
+
+ //
+ // handle normal key's releasing situation
+ //
+ KeyRelease = FALSE;
+ for (i = 2; i < 8; i ++) {
+
+ if(!USBKBD_VALID_KEYCODE(OldKeyCodeBuffer[i])) {
+ continue;
+ }
+
+ KeyRelease = TRUE;
+ for (j = 2; j < 8; j ++) {
+
+ if(!USBKBD_VALID_KEYCODE(CurKeyCodeBuffer[j])) {
+ continue;
+ }
+
+ if (OldKeyCodeBuffer[i] == CurKeyCodeBuffer[j]) {
+ KeyRelease = FALSE;
+ break;
+ }
+ }
+
+ if (KeyRelease) {
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),OldKeyCodeBuffer[i],0);
+ //
+ // the original reapeat key is released.
+ //
+ if (OldKeyCodeBuffer[i] == gUsbData->RepeatKey) {
+ gUsbData->RepeatKey = 0;
+ }
+ }
+ }
+ //
+ // handle normal key's pressing situation
+ //
+ KeyPress = FALSE;
+ for (i = 2; i < 8; i ++) {
+ if(!USBKBD_VALID_KEYCODE(CurKeyCodeBuffer[i])) {
+ continue;
+ }
+
+ KeyPress = TRUE;
+ for (j = 2; j < 8; j ++) {
+ if(!USBKBD_VALID_KEYCODE(OldKeyCodeBuffer[j])) {
+ continue;
+ }
+
+ if (CurKeyCodeBuffer[i] == OldKeyCodeBuffer[j]) {
+ KeyPress = FALSE;
+ break;
+ }
+ }
+
+ if(KeyPress) {
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),CurKeyCodeBuffer[i],1);
+ //
+ // NumLock, ScrollLock or CapsLock pressed
+ //
+ if(CurKeyCodeBuffer[i] == 0x53 ||
+ CurKeyCodeBuffer[i] == 0x47 ||
+ CurKeyCodeBuffer[i] == 0x39) {
+ gUsbData->RepeatKey = 0;
+ }
+ else
+ {
+ NewRepeatKey = CurKeyCodeBuffer[i];
+ //
+ // do not repeat the original repeated key
+ //
+ gUsbData->RepeatKey = 0;
+ }
+ }
+ }
+
+ //
+ // Update LastKeycodeArray[] buffer in the
+ // Usb Keyboard Device data structure.
+ //
+ for (i = 0; i < 8; i ++) {
+ gUsbKeyboardData->LastKeyCodeArray[i] = CurKeyCodeBuffer[i];
+ }
+
+ //
+ // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
+ // and judge whether it will invoke reset event.
+ //
+ SavedTail = gUsbKeyboardData->KeyboardBuffer.bTail;
+ i = gUsbKeyboardData->KeyboardBuffer.bHead;
+ KeyProcessed=FALSE;
+ while(i != SavedTail) {
+ RemoveKeyCode(&(gUsbKeyboardData->KeyboardBuffer),&UsbKey);
+ //(EIP84455+)>
+ switch(UsbKey.KeyCode) {
+ case 0xe0:
+ if(UsbKey.Down)
+ gUsbKeyboardData->LeftCtrlOn = 1;
+ break;
+
+ case 0xe4:
+ if(UsbKey.Down)
+ gUsbKeyboardData->RightCtrlOn = 1;
+ break;
+
+ case 0xe2:
+ if(UsbKey.Down)
+ gUsbKeyboardData->LeftAltOn = 1;
+ break;
+ case 0xe6:
+ if(UsbKey.Down)
+ gUsbKeyboardData->RightAltOn = 1;
+ break;
+ //<(EIP84455+)
+ case 0x4c: // Del Key Code
+ case 0x63:
+ if(UsbKey.Down) {
+ if((gUsbKeyboardData->LeftCtrlOn | gUsbKeyboardData->RightCtrlOn) && (gUsbKeyboardData->LeftAltOn | gUsbKeyboardData->RightAltOn)) {
+ gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ //
+ // insert the key back to the buffer.
+ // so the key sequence will not be destroyed.
+ //
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),
+ UsbKey.KeyCode,
+ UsbKey.Down);
+
+ i = gUsbKeyboardData->KeyboardBuffer.bHead;
+
+ }
+ KeyProcessed=TRUE;
+ //
+ // If have new key pressed, update the RepeatKey value
+ //
+ if(NewRepeatKey != 0) {
+ gUsbData->RepeatKey = NewRepeatKey;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KeyrepeatCallback
+//
+// Description: This routine is called every time the key repeat is requested
+//
+// Input: All input pointers are NULL, need them for callback function
+// parameters list
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KeyrepeatCallback(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Buf1,
+ UINT8* Buf2)
+
+{
+ //
+ // Do nothing when there is no repeat key.
+ //
+ if(gUsbData->RepeatKey) {
+ //
+ // Inserts one Repeat key into keyboard buffer,
+ //
+ InsertKeyCode(
+ &(gUsbKeyboardData->KeyboardBuffer),
+ gUsbData->RepeatKey,
+ 1
+ );
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBParseKey
+//
+// Description: Retrieves a key character after parsing the raw data
+// in keyboard buffer.
+//
+// Input: KeyChar - pointer to the key character after key parsing.
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS USBParseKey (
+ UINT8 *KeyChar)
+{
+ USB_KEY UsbKey;
+
+ *KeyChar = 0;
+
+ while (!IsUSBKeyboardBufferEmpty(&(gUsbKeyboardData->KeyboardBuffer))) { //(EIP83295)
+ //
+ // pops one raw data off.
+ //
+ RemoveKeyCode(&(gUsbKeyboardData->KeyboardBuffer),&UsbKey);
+
+ //
+ // Key Release
+ //
+ if (!UsbKey.Down) {
+ switch(UsbKey.KeyCode) {
+ case 0xe0: // fall through
+ gUsbKeyboardData->LeftCtrlOn = 0;
+ break;
+
+ case 0xe4:
+ gUsbKeyboardData->RightCtrlOn = 0;
+ break;
+
+ case 0xe1: // fall through
+ gUsbKeyboardData->LeftShiftOn = 0;
+ break;
+ case 0xe5:
+ gUsbKeyboardData->RightShiftOn = 0;
+ break;
+
+ case 0xe2: // fall through
+ gUsbKeyboardData->LeftAltOn = 0;
+ break;
+ case 0xe6:
+ gUsbKeyboardData->RightAltOn = 0;
+ break;
+
+ case 0xe3: // fall through
+ gUsbKeyboardData->LeftLogoOn = 0;
+ break;
+ case 0xe7:
+ gUsbKeyboardData->RightLogoOn = 0;
+ break;
+
+ case 0x46:
+ gUsbKeyboardData->SysRqOn = 0;
+ break;
+
+ case 0x65:
+ gUsbKeyboardData->MenuOn = 0;
+ break;
+
+ default:
+ break;
+ }
+ continue;
+ }
+
+ //
+ // Analyzes key pressing situation
+ //
+ switch (UsbKey.KeyCode) {
+ case 0xe0: // fall through
+ gUsbKeyboardData->LeftCtrlOn = 1;
+ continue;
+ case 0xe4:
+ gUsbKeyboardData->RightCtrlOn = 1;
+ continue;
+
+ case 0xe1: // fall through
+ gUsbKeyboardData->LeftShiftOn = 1;
+ continue;
+ case 0xe5:
+ gUsbKeyboardData->RightShiftOn = 1;
+ continue;
+
+ case 0xe2: // fall through
+ gUsbKeyboardData->LeftAltOn = 1;
+ continue;
+ case 0xe6:
+ gUsbKeyboardData->RightAltOn = 1;
+ continue;
+
+ case 0xe3: // fall through
+ gUsbKeyboardData->LeftLogoOn = 1;
+ continue;
+ case 0xe7:
+ gUsbKeyboardData->RightLogoOn = 1;
+ continue;
+ //
+ // SysRq Key
+ //
+ case 0x46:
+ gUsbKeyboardData->SysRqOn = 1;
+ continue;
+ //
+ // Menu Key
+ //
+ case 0x65:
+ gUsbKeyboardData->MenuOn = 1;
+ continue;
+
+ case 0x53:
+ gUsbKeyboardData->NumLockOn ^= 1;
+ SetKeyLED();
+ break;
+
+ case 0x39:
+ gUsbKeyboardData->CapsOn ^= 1;
+ SetKeyLED();
+ break;
+
+ case 0x47:
+ gUsbKeyboardData->ScrLkOn ^= 1;
+ SetKeyLED();
+ break;
+
+ //
+ // PrintScreen,ScrollLock,Pause,Application,Power
+ // keys are not valid EFI key
+ //
+ case 0x66:
+ continue;
+
+ default:
+ break;
+ }
+
+ //
+ // When encountered Del Key...
+ //
+ if (UsbKey.KeyCode == 0x4c || UsbKey.KeyCode == 0x63) {
+ if((gUsbKeyboardData->LeftCtrlOn | gUsbKeyboardData->RightCtrlOn) && (gUsbKeyboardData->LeftAltOn | gUsbKeyboardData->RightAltOn)) {
+ gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+ }
+
+ *KeyChar = UsbKey.KeyCode;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_READY;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKeyCodeToEFIScanCode
+//
+// Description: Converts USB Keyboard code to EFI Scan Code
+//
+// Input: KeyChar - Indicates the key code that will be interpreted.
+// Key - A pointer to a buffer that is filled in with
+// the keystroke information for the key that
+// was pressed.
+//
+// Output: EFI_SUCCESS, EFI_NOT_READY
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+USBKeyCodeToEFIScanCode(
+ UINT8 KeyChar,
+ EFI_INPUT_KEY *Key
+)
+{
+ UINT8 Index;
+
+ if (!USBKBD_VALID_KEYCODE(KeyChar)) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // valid USB Key Code starts from 4
+ //
+ Index = (UINT8)(KeyChar - 4);
+
+ if (Index >= USB_KEYCODE_MAX_MAKE){
+ return EFI_NOT_READY;
+ }
+
+ Key->ScanCode = KeyConvertionTable[Index][0];
+
+ if (gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->RightShiftOn) {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][2];
+
+ } else {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][1];
+ }
+
+ if ((gUsbKeyboardData->NumLockOn == 0) && gUsbKeyboardData->LeftShiftOn == 0 && gUsbKeyboardData->RightShiftOn == 0 && (Index == 0x5d-4)) {
+ Key->UnicodeChar = 0;
+ }
+
+ if (gUsbKeyboardData->CapsOn) {
+
+ if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][2];
+
+ } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][1];
+
+ }
+ }
+
+ if (KeyChar >= 0x59 && KeyChar <=0x63 && Key->ScanCode != SCAN_NULL) {
+
+ if (gUsbKeyboardData->NumLockOn && !(gUsbKeyboardData->LeftShiftOn | gUsbKeyboardData->RightShiftOn)) {
+
+ Key->ScanCode = SCAN_NULL;
+
+ } else {
+
+ Key->UnicodeChar = 0x00;
+ }
+ }
+ //
+ // CapsLock, NumLock and ScrLock must be reported as valid keys even though their
+ // ScanCode and UnicodeChar are zeroes
+ //
+// if (KeyChar == 0x53 || KeyChar == 0x39 || KeyChar == 0x47 ) return EFI_SUCCESS;
+
+ if (KeyChar == 0x53 || KeyChar == 0x39 || KeyChar == 0x47 || KeyChar == 0x48 ) {
+ return EFI_SUCCESS;
+ }
+
+ if(Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitUSBKeyBuffer
+//
+// Description: Initialize USB Keyboard Buffer.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitUSBKeyBuffer(USB_KB_BUFFER *KeyboardBuffer)
+{
+ EfiZeroMem(KeyboardBuffer,sizeof(USB_KB_BUFFER));
+
+ KeyboardBuffer->bHead = KeyboardBuffer->bTail;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyboardBufferEmpty
+//
+// Description: Check whether USB Keyboard buffer is empty.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+//
+// Output: TRUE if buffer is empty, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ //(EIP83295)>
+BOOLEAN
+IsUSBKeyboardBufferEmpty(USB_KB_BUFFER *KeyboardBuffer)
+{
+ //
+ // meet FIFO empty condition
+ //
+ return (BOOLEAN)(KeyboardBuffer->bHead == KeyboardBuffer->bTail);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyboardBufferFull
+//
+// Description: Check whether USB Keyboard buffer is full.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+//
+// Output: TRUE if buffer is full, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsUSBKeyboardBufferFull(USB_KB_BUFFER *KeyboardBuffer)
+{
+ return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==
+ KeyboardBuffer->bHead);
+}
+ //<(EIP83295)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InsertKeyCode
+//
+// Description: Inserts a key code into keyboard buffer.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InsertKeyCode(
+ USB_KB_BUFFER *KeyboardBuffer,
+ UINT8 Key,
+ UINT8 Down
+ )
+{
+ USB_KEY UsbKey;
+
+ if(KeyProcessed && Down) {
+ UsbCheckKeyNotify(Key);
+ }
+
+ //
+ // if keyboard buffer is full, throw the
+ // first key out of the keyboard buffer.
+ //
+ if (IsUSBKeyboardBufferFull (KeyboardBuffer)) { //(EIP83295)
+ RemoveKeyCode(KeyboardBuffer,&UsbKey);
+ }
+
+ KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;
+ KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;
+
+ //
+ // adjust the tail pointer of the FIFO keyboard buffer.
+ //
+ KeyboardBuffer->bTail = (UINT8)((KeyboardBuffer->bTail + 1)
+ % (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveKeyCode
+//
+// Description: Removes a key code from the keyboard buffer.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+// UsbKey - pointer to buffer that contains usb key code.
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveKeyCode(
+ USB_KB_BUFFER *KeyboardBuffer,
+ USB_KEY *UsbKey
+)
+{
+ if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) { //(EIP83295)
+ return EFI_DEVICE_ERROR;
+ }
+
+ UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;
+ UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;
+
+ //
+ // adjust the head pointer of the FIFO keyboard buffer.
+ //
+ KeyboardBuffer->bHead = (UINT8)((KeyboardBuffer->bHead + 1) %
+ (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitUSBKeyCharBuffer
+//
+// Description: Initialize USB Keyboard Buffer for Keyboard ASCII data.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitUSBKeyCharBuffer()
+{
+ EfiZeroMem((VOID*)&(gUsbKeyboardData->KeyChar[0]),sizeof(UINT8) * MAX_KEY_ALLOWED + 1 );
+
+ gUsbKeyboardData->bHead = gUsbKeyboardData->bTail;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyCharEmpty
+//
+// Description: Check whether USB Keyboard ASCII data buffer is empty.
+//
+// Input: None
+//
+// Output: TRUE if buffer is empty, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsUSBKeyCharEmpty()
+{
+ //
+ // meet FIFO empty condition
+ //
+ return (BOOLEAN)(gUsbKeyboardData->bHead == gUsbKeyboardData->bTail);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyboardBufferFull
+//
+// Description: Check whether USB Keyboard ASCII data buffer is full.
+//
+// Input: None
+//
+// Output: TRUE if buffer is full, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsUSBKeyCharFull()
+{
+ return (BOOLEAN)(((gUsbKeyboardData->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==
+ gUsbKeyboardData->bHead);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InsertKeyCode
+//
+// Description: Inserts a USB Keyboard ASCII data into keyboard buffer.
+//
+// Input: UINT8 KeyChar - USB Key Data
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InsertKeyChar(
+ UINT8 KeyChar
+ )
+{
+ UINT8 TempKey;
+
+ //
+ // if keyboard buffer is full, throw the
+ // first key out of the keyboard buffer.
+ //
+ if (IsUSBKeyCharFull()) {
+ RemoveKeyChar(&TempKey);
+ }
+
+ gUsbKeyboardData->KeyChar[gUsbKeyboardData->bTail] = KeyChar;
+
+ //
+ // adjust the tail pointer of the FIFO keyboard buffer.
+ //
+ gUsbKeyboardData->bTail = (UINT8)((gUsbKeyboardData->bTail + 1)
+ % (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveKeyCode
+//
+// Description: Removes a USB Keyboard ASCII data from the keyboard buffer.
+//
+// Input: UINT8 KeyChar - USB Keyboard Data
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveKeyChar(
+ UINT8 *KeyChar
+)
+{
+ if (IsUSBKeyCharEmpty()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ *KeyChar = gUsbKeyboardData->KeyChar[gUsbKeyboardData->bHead];
+
+ //
+ // adjust the head pointer of the FIFO keyboard buffer.
+ //
+ gUsbKeyboardData->bHead = (UINT8)((gUsbKeyboardData->bHead + 1) %
+ (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SetKeyLED
+//
+// Description: Sets USB Keyboard LED state.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS
+//
+// Notes: UsbKbd can be NULL; in this case LEDs on all keyboards will
+// be refreshed. This is useful when the new keyboard is connected
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetKeyLED()
+{
+ LED_MAP Led;
+ URP_STRUC Urp; // USB Request Packet
+
+ //
+ // Set each field in Led map.
+ //
+ if (gUsbKeyboardData)
+ {
+ Led.NumLock = (UINT8)gUsbKeyboardData->NumLockOn;
+ Led.CapsLock = (UINT8)gUsbKeyboardData->CapsOn;
+ Led.ScrLock = (UINT8)gUsbKeyboardData->ScrLkOn;
+ Led.Resrvd = 0;
+ Urp.ApiData.KbLedsData.fpLedMap = (UINT32)(UINTN)&Led;
+ }
+ else
+ {
+ Urp.ApiData.KbLedsData.fpLedMap = 0;
+ }
+ //
+ // Lighten up LEDs.
+ //
+ Urp.bFuncNumber = USB_API_LIGHTEN_KEYBOARD_LEDS;
+ Urp.bSubFunc = 0;
+
+ InvokeUsbApi(&Urp);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SupportedUSBKeyboard
+//
+// Description: Verifies if usb keyboard support can be installed on a device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SupportedUSBKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ EFI_USB_INTERFACE_DESCRIPTOR Desc;
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if( EFI_ERROR(Status))
+ return Status;
+
+ Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &Desc );
+ if(EFI_ERROR(Status))
+ return EFI_UNSUPPORTED;
+
+ if ( Desc.InterfaceClass == BASE_CLASS_HID &&
+ Desc.InterfaceSubClass == SUB_CLASS_BOOT_DEVICE &&
+ Desc.InterfaceProtocol == PROTOCOL_KEYBOARD)
+ {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+#if CLEAR_USB_KB_BUFFER_AT_READYTOBOOT
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ClearUsbKbBuffer
+//
+// Description:
+// This function clear USB KB buffers
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+ClearUsbKbBuffer(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ InitUSBKeyBuffer(&(gUsbKeyboardData->KeyboardBuffer));
+ gUsbKeyboardData->CurKeyChar = 0;
+
+ // Clear KB buffers in USB_GLOBAL_DATA
+ EfiZeroMem(gUsbData->aKBCCharacterBufferStart, 128);
+ gUsbData->fpKBCCharacterBufferHead = gUsbData->aKBCCharacterBufferStart;
+ gUsbData->fpKBCCharacterBufferTail = gUsbData->aKBCCharacterBufferStart;
+
+ EfiZeroMem(gUsbData->aKBCScanCodeBufferStart, 16);
+ gUsbData->fpKBCScanCodeBufferPtr = gUsbData->aKBCScanCodeBufferStart;
+
+ EfiZeroMem(gUsbData->aKBCUsbDataBufferStart, 32);
+ gUsbData->aKBCUsbDataBufferHead = gUsbData->aKBCUsbDataBufferStart;
+ gUsbData->aKBCUsbDataBufferTail = gUsbData->aKBCUsbDataBufferStart;
+
+ EfiZeroMem(gUsbData->aKBInputBuffer, 16);
+
+ pBS->CloseEvent(Event);
+
+ return EFI_SUCCESS;
+}
+#endif
+
+
+ //(EIP38434+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallUSBKeyboard
+//
+// Description: Installs SimpleTxtIn protocol on a given handle
+//
+// Input: Controller - controller handle to install protocol on.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallUSBKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ DEV_INFO* Dev_info,
+ EFI_USB_IO_PROTOCOL *UsbIo
+)
+{
+ EFI_STATUS Status;
+ USB_KB_DEV* UsbKbd;
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB: InstallUSBKeyboard: starting...\n");
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->AllocatePool( EfiBootServicesData,
+ sizeof(USB_KB_DEV), &UsbKbd ));
+ EfiZeroMem(UsbKbd, sizeof(USB_KB_DEV));
+
+ UsbKbd->dev_info = Dev_info;
+ //
+ // Initialize UsbKbd
+ //
+ ASSERT_EFI_ERROR(Status);
+
+ UsbKbd->io = UsbIo;
+ UsbKbd->Signature = USB_KB_DEV_SIGNATURE;
+ UsbKbd->SimpleInput.Reset = UsbKbdReset;
+ UsbKbd->SimpleInput.ReadKeyStroke = UsbKbdReadKeyStroke;
+
+#if (CORE_REVISION >= 0x3)
+ UsbKbd->SimpleInputEx.Reset = UsbKbdResetEx;
+ UsbKbd->SimpleInputEx.ReadKeyStrokeEx = UsbKbdReadKeyStrokeEx;
+ UsbKbd->SimpleInputEx.SetState = UsbKbdSetState;
+ UsbKbd->SimpleInputEx.RegisterKeyNotify = UsbKbdRegisterKeyNotify;
+ UsbKbd->SimpleInputEx.UnregisterKeyNotify = UsbKbdUnregisterKeyNotify;
+
+ UsbKbd->KeycodeInput.Reset = UsbKbdResetEx;
+ UsbKbd->KeycodeInput.ReadEfikey = UsbKbdReadEfiKey;
+ UsbKbd->KeycodeInput.SetState = UsbKbdSetState;
+ UsbKbd->KeycodeInput.RegisterKeyNotify = UsbKbdRegisterKeyNotify;
+ UsbKbd->KeycodeInput.UnregisterKeyNotify = UsbKbdUnregisterKeyNotify;
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbKbdWaitForKey,
+ UsbKbd,
+ &UsbKbd->SimpleInputEx.WaitForKeyEx));
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbKbdWaitForKey,
+ UsbKbd,
+ &UsbKbd->KeycodeInput.WaitForKeyEx));
+
+#endif
+
+#if CLEAR_USB_KB_BUFFER_AT_READYTOBOOT
+ // Create event on ready to boot to clear KB buffer
+ VERIFY_EFI_ERROR(
+ Status = pBS->CreateEvent(
+ EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ TPL_NOTIFY,
+ ClearUsbKbBuffer,
+ NULL,
+ &gClearUsbKbBufferEvent));
+#endif
+
+ // Setup the WaitForKey event
+ //
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbKbdWaitForKey,
+ UsbKbd,
+ &UsbKbd->SimpleInput.WaitForKey));
+
+ //
+ // Install protocol interfaces for the USB keyboard device:
+ //
+ // Install simple txt in protocol interface
+ // for the usb keyboard device.
+ // Usb keyboard is a hot plug device, and expected to work immediately
+ // when plugging into system, so a HotPlugDeviceGuid is installed onto
+ // the usb keyboard device handle, to distinguish it from other conventional
+ // console devices.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (&Controller,
+ &gEfiHotPlugDeviceGuid, NULL,
+ &gEfiSimpleTextInProtocolGuid,&UsbKbd->SimpleInput,
+#if (CORE_REVISION >= 0x3)
+ &gEfiSimpleTextInExProtocolGuid,&UsbKbd->SimpleInputEx,
+ &gAmiEfiKeycodeProtocolGuid,&UsbKbd->KeycodeInput,
+#endif
+ NULL
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB: InstallUSBKeyboard: done (%x).\n", Status);
+
+ SetKeyLED();
+
+ return Status;
+}
+ //<(EIP38434+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UninstallUSBKeyboard
+//
+// Description: Uninstalls SimpleTxtIn protocol on a given handle
+//
+// Input: Controller - controller handle.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UninstallUSBKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+)
+{
+ EFI_STATUS Status;
+ USB_KB_DEV* UsbKbd=0;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn;
+ DLINK *ListPtr = NULL; //(EIP100370+)
+ KEY_WAITING_RECORD *UsbKeyIn = NULL; //(EIP100370+)
+
+
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ (VOID **)&SimpleIn,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+
+ UsbKbd = USB_KB_DEV_FROM_THIS(SimpleIn, SimpleInput);
+
+ //(EIP100370+)>
+#if (CORE_REVISION >= 0x3)
+ ListPtr = mUsbKeyboardData.pHead;
+ while (ListPtr != NULL) {
+ UsbKeyIn = OUTTER(ListPtr, Link, KEY_WAITING_RECORD);
+ ListPtr = ListPtr->pNext;
+ if (UsbKbd == UsbKeyIn->UsbKbDev) {
+ DListDelete(&mUsbKeyboardData, &UsbKeyIn->Link);
+ pBS->FreePool(UsbKeyIn);
+ }
+ }
+
+ if (mUsbKeyboardData.Size == 0) {
+ pBS->SetTimer(UsbKeyEvent,
+ TimerCancel,
+ 0);
+ }
+#endif
+ //<(EIP100370+)
+
+ //
+ // Uninstall protocol interfaces for the USB keyboard device
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces ( Controller,
+ &gEfiHotPlugDeviceGuid, NULL,
+ &gEfiSimpleTextInProtocolGuid, &UsbKbd->SimpleInput,
+#if (CORE_REVISION >= 0x3)
+ &gEfiSimpleTextInExProtocolGuid,&UsbKbd->SimpleInputEx,
+ &gAmiEfiKeycodeProtocolGuid,&UsbKbd->KeycodeInput,
+#endif
+ NULL);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //(EIP38434+)>
+// VERIFY_EFI_ERROR(
+// gBS->CloseProtocol (
+// Controller, &gEfiUsbIoProtocolGuid,
+// This->DriverBindingHandle, Controller));
+ //<(EIP38434+)
+ //
+ // Close the WaitForKey event
+ //
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (UsbKbd->SimpleInput.WaitForKey));
+
+#if (CORE_REVISION >= 0x3)
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (UsbKbd->SimpleInputEx.WaitForKeyEx));
+
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (UsbKbd->KeycodeInput.WaitForKeyEx));
+#endif
+
+ VERIFY_EFI_ERROR(
+ gBS->FreePool(UsbKbd));
+
+ return Status;
+}
+
+
+/***********************************************************************/
+/* */
+/* SimpleTextIn Protocol implementation routines */
+/* */
+/***********************************************************************/
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReset
+//
+// Description: Reset USB keyboard
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ EFI_STATUS Status;
+
+ //
+ // Non Exhaustive reset: only reset private data structures.
+ //
+ if(!ExtendedVerification) {
+ InitUSBKeyBuffer(&(gUsbKeyboardData->KeyboardBuffer));
+ InitUSBKeyCharBuffer();
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Exhaustive reset
+ //
+ Status = InitUSBKeyboard();
+ InitUSBKeyCharBuffer();
+ if(EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReadKeyStroke
+//
+// Description: Retrieves the key stroke from the keyboard buffer.
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+)
+{
+ EFI_STATUS Status;
+
+ Status = ReadAndProcessKey(Key, sizeof(EFI_INPUT_KEY));
+ if(Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return Status;
+
+}
+
+#if (CORE_REVISION >= 0x3)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdResetEx
+//
+// Description: Reset USB keyboard
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UsbKbdResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ return UsbKbdReset(0, ExtendedVerification);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReadKeyStrokeEx
+//
+// Description: Retrieves the key stroke from the keyboard buffer.
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UsbKbdReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+)
+{
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return ReadAndProcessKey(KeyData, sizeof(EFI_KEY_DATA));
+}
+
+EFI_STATUS UsbKbdReadEfiKey(
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ Status = ReadAndProcessKey(KeyData, sizeof(AMI_EFI_KEY_DATA));
+ if (Status == EFI_SUCCESS && !(KeyData->KeyState.KeyToggleState & KEY_STATE_EXPOSED)) {
+ KeyData->EfiKeyIsValid = 1;
+ KeyData->PS2ScanCodeIsValid = 1;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UsbKbdSetState
+//
+// Description: Set certain state for the input device.
+//
+// Paremeters: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyToggleState - Pointer to the EFI_KEY_TOGGLE_STATE to
+// set the state for the input device.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ BOOLEAN ChgSL = FALSE;
+ BOOLEAN ChgCL = FALSE;
+ BOOLEAN ChgNL = FALSE;
+
+ if(KeyToggleState == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(*KeyToggleState & TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & (~(TOGGLE_STATE_VALID | KEY_STATE_EXPOSED |
+ SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE)))) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Set the new modifier's state only if the requested state is different from the
+ // current one.
+ //
+ if((UINT8)*KeyToggleState != gUsbKeyboardData->ToggleState){ //(EIP91889)
+ gUsbKeyboardData->ToggleState = (*KeyToggleState); //(EIP91889+)
+ gUsbKeyboardData->ScrLkOn = (*KeyToggleState & SCROLL_LOCK_ACTIVE)? 1 : 0;
+ gUsbKeyboardData->NumLockOn = (*KeyToggleState & NUM_LOCK_ACTIVE)? 1 : 0;
+ gUsbKeyboardData->CapsOn = (*KeyToggleState & CAPS_LOCK_ACTIVE)? 1 : 0;
+
+ SetKeyLED();
+ }
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ValidateKeyRecord
+//
+// Description: Check for Record is present or Not
+//
+// Paremeters: KEY_WAITING_RECORD - *UsbKeyIn
+//
+// Output: FALSE - If Record is deleted from list
+// TRUE - If Record is present in List
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+ValidateKeyRecord (
+ IN KEY_WAITING_RECORD *UsbKeyIn
+)
+{
+ KEY_WAITING_RECORD *TempRecord = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+
+ while ( TempRecord != NULL) {
+ if(TempRecord == UsbKeyIn) {
+ return TRUE;
+ }
+ // go to the next element in the list
+ TempRecord = OUTTER(TempRecord->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckKeyNotify
+//
+// Description: Call the notification function based on the key pressed
+//
+// Paremeters: Key - Key pressed
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UsbCheckKeyNotify(UINT8 KeyChar)
+{
+
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+ KEY_WAITING_RECORD *UsbKeyIn = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+ BOOLEAN KeyScanCodeMatch=FALSE;
+ BOOLEAN KeyUniCodeMatch=FALSE;
+ BOOLEAN ShiftKeyMatch=FALSE;
+ BOOLEAN CtrlKeyMatch=FALSE;
+ BOOLEAN AltKeyMatch=FALSE;
+ BOOLEAN LogoKeyMatch=FALSE;
+ BOOLEAN MenuKeyMatch=FALSE;
+ BOOLEAN SysRqKeyMatch=FALSE;
+ BOOLEAN KeyShiftCodeMatch=FALSE;
+ BOOLEAN KeyToggleKeyMatch=FALSE;
+ BOOLEAN CallBackCalled=FALSE;
+
+ // if the list is empty return the status that was passed in
+ if (UsbKeyIn == NULL)
+ return EFI_SUCCESS;
+
+ EfiZeroMem((VOID*)&Key,sizeof(EFI_INPUT_KEY));
+
+ //
+ // Translate saved ASCII byte into EFI_INPUT_KEY and PS/2 Scan Code
+ //
+ Status = USBKeyCodeToEFIScanCode(KeyChar,&Key);
+
+ // check for a handle that was already identified
+ while ( UsbKeyIn != NULL)
+ {
+ KeyScanCodeMatch=FALSE;
+ KeyUniCodeMatch=FALSE;
+ ShiftKeyMatch=FALSE;
+ CtrlKeyMatch=FALSE;
+ AltKeyMatch=FALSE;
+ LogoKeyMatch=FALSE;
+ MenuKeyMatch=FALSE;
+ SysRqKeyMatch=FALSE;
+ KeyShiftCodeMatch=FALSE;
+ KeyToggleKeyMatch=FALSE;
+
+ //
+ // Check the Scan Code if the Scan code is not 0
+ //
+ if (UsbKeyIn->Context.Key.ScanCode != 0) {
+ if( UsbKeyIn->Context.Key.ScanCode == Key.ScanCode) {
+ KeyScanCodeMatch=TRUE;
+ }
+ } else {
+ KeyScanCodeMatch=TRUE;
+ }
+
+ //
+ // Check the Uncide Code Matching
+ //
+
+ if(UsbKeyIn->Context.Key.UnicodeChar == Key.UnicodeChar) {
+ KeyUniCodeMatch=TRUE;
+ }
+
+ if(UsbKeyIn->Context.KeyState.KeyShiftState & SHIFT_STATE_VALID){
+
+ //
+ // Check the ShiftKey Matching. Left Shift Key is matched with
+ // Left or Right Shift Key. Same for Right Shift Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) {
+ if(gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->RightShiftOn) {
+ ShiftKeyMatch=TRUE;
+ }
+ } else {
+ ShiftKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Ctrl Matching. Left Ctrl Key is matched with
+ // Left or Right Ctrl Key. Same for Right Ctrl Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_CONTROL_PRESSED | LEFT_CONTROL_PRESSED)) {
+ if(gUsbKeyboardData->LeftCtrlOn || gUsbKeyboardData->RightCtrlOn) {
+ CtrlKeyMatch=TRUE;
+ }
+ } else {
+ CtrlKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Alt Matching. Left Alt Key is matched with
+ // Left or Right Alt Key. Same for Right Alt Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
+ if(gUsbKeyboardData->LeftAltOn || gUsbKeyboardData->RightAltOn) {
+ AltKeyMatch=TRUE;
+ }
+ } else {
+ AltKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Logo Matching. Left Logo Key is matched with
+ // Left or Right Logo Key. Same for Right Logo Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_LOGO_PRESSED | LEFT_LOGO_PRESSED)) {
+ if(gUsbKeyboardData->LeftLogoOn || gUsbKeyboardData->RightLogoOn) {
+ LogoKeyMatch=TRUE;
+ }
+ } else {
+ LogoKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Menu Key Matching
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & MENU_KEY_PRESSED) {
+ if(gUsbKeyboardData->MenuOn) {
+ MenuKeyMatch=TRUE;
+ }
+ } else {
+ MenuKeyMatch=TRUE;
+ }
+
+ //
+ // Check the SysRq Key Matching
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & SYS_REQ_PRESSED) {
+ if(gUsbKeyboardData->SysRqOn) {
+ SysRqKeyMatch=TRUE;
+ }
+ } else {
+ SysRqKeyMatch=TRUE;
+ }
+
+ KeyShiftCodeMatch=ShiftKeyMatch & CtrlKeyMatch & AltKeyMatch
+ & LogoKeyMatch & MenuKeyMatch & SysRqKeyMatch;
+ }else {
+ KeyShiftCodeMatch=TRUE;
+ }
+ //
+ // Check the Key Toggle State
+ //
+ if(UsbKeyIn->Context.KeyState.KeyToggleState & TOGGLE_STATE_VALID){
+ if((UsbKeyIn->Context.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED) ==
+ (TOGGLE_STATE_VALID | gUsbKeyboardData->ScrLkOn | gUsbKeyboardData->NumLockOn | gUsbKeyboardData->CapsOn)) {
+ KeyToggleKeyMatch=TRUE;
+ }
+ } else {
+ KeyToggleKeyMatch=TRUE;
+ }
+
+ //
+ // If everything matched, call the callback function.
+ //
+ if(KeyScanCodeMatch && KeyUniCodeMatch && KeyShiftCodeMatch && KeyToggleKeyMatch && (!UsbKeyIn->CallbackStatus)) {
+
+ //Call the notification function
+ UsbKeyIn->CallbackStatus=TRUE;
+ CallBackCalled=TRUE;
+ UsbKeyIn->Callback(&UsbKeyIn->Context);
+
+ if(ValidateKeyRecord(UsbKeyIn)) {
+
+ // go to the next element in the list
+ UsbKeyIn = OUTTER(UsbKeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ } else {
+
+ // Record deleted. So go to the first element in the list
+ UsbKeyIn = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+ }
+ continue;
+ }
+ // go to the next element in the list
+ UsbKeyIn = OUTTER(UsbKeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+
+ if(CallBackCalled) {
+ UsbKeyIn = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+ while ( UsbKeyIn != NULL) {
+ UsbKeyIn->CallbackStatus=FALSE;
+ // go to the next element in the list
+ UsbKeyIn = OUTTER(UsbKeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdRegisterKeyNotify
+//
+// Description: Installs a callback notification function on a key
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyData - Key value
+// KeyNotificationFunction- Pointer to the Notification Function
+// NotificationHandle - Handle to be unregisterd
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdRegisterKeyNotify (
+ 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;
+ USB_KB_DEV *UsbKbd = 0; //(EIP100370+)
+ DLINK *Link = NULL;
+ KEY_WAITING_RECORD *NotifyLink = NULL;
+
+ if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check if the key has been reistered
+ for (Link = mUsbKeyboardData.pHead; Link != NULL; Link = Link->pNext) {
+ NotifyLink = OUTTER(Link, Link, KEY_WAITING_RECORD);
+ if (MemCmp(&NotifyLink->Context, KeyData, sizeof(EFI_KEY_DATA)) == 0 &&
+ NotifyLink->Callback == KeyNotificationFunction) {
+ *NotifyHandle = (EFI_HANDLE)(&NotifyLink->Link);
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Create database record and add to database
+ //
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof (KEY_WAITING_RECORD),
+ &mUsbKeyboardRecord
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ UsbKbd = USB_KB_DEV_FROM_THIS (This, SimpleInputEx); //(EIP100370+)
+ //
+ // Gather information about the registration request
+ //
+
+ mUsbKeyboardRecord->UsbKbDev = UsbKbd; //(EIP100370+)
+ mUsbKeyboardRecord->Context = *KeyData;
+ mUsbKeyboardRecord->Callback = KeyNotificationFunction;
+ mUsbKeyboardRecord->CallbackStatus = FALSE;
+
+ DListAdd (&mUsbKeyboardData, &(mUsbKeyboardRecord->Link));
+
+ //
+ // Child's handle will be the address linked list link in the record
+ //
+ *NotifyHandle = (EFI_HANDLE) (&mUsbKeyboardRecord->Link);
+
+ if(mUsbKeyboardData.Size == 1) {
+ pBS->SetTimer(UsbKeyEvent,
+ TimerPeriodic,
+ KEY_POLLING_INTERVAL);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdRegisterKeyNotify
+//
+// Description: Uninstalls a callback notification function on a key
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// NotificationHandle - Handle to be unregisterd
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+)
+{
+ DLINK *ListPtr;
+ KEY_WAITING_RECORD *UsbKeyIn;
+ USB_KB_DEV* UsbKbd = USB_KB_DEV_FROM_THIS (This, SimpleInputEx); //(EIP100370+)
+
+ if(NotificationHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ListPtr = mUsbKeyboardData.pHead;
+ //(EIP100370)>
+ while (ListPtr != NULL) {
+ UsbKeyIn = OUTTER(ListPtr, Link, KEY_WAITING_RECORD);
+ if ((&UsbKeyIn->Link) == NotificationHandle &&
+ UsbKeyIn->UsbKbDev == UsbKbd) {
+ DListDelete(&mUsbKeyboardData, ListPtr);
+ pBS->FreePool(UsbKeyIn);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ if (ListPtr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mUsbKeyboardData.Size == 0) {
+ pBS->SetTimer(UsbKeyEvent,
+ TimerCancel,
+ 0);
+ }
+
+ return EFI_SUCCESS;
+ //<(EIP100370)
+}
+
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdWaitForKey
+//
+// Description: Checks if a key is pending, if so - signals the event.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbKbdWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ if(IsUSBKeyCharEmpty()) {
+ if (EFI_ERROR(USBKeyboardCheckForKey())) {
+ return;
+ }
+ }
+ //
+ // If has key pending, signal the event.
+ //
+ gBS->SignalEvent(Event);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReadKeyStroke
+//
+// Description: Checks if a key is pending, if so - signals the event.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+USBKeyboardCheckForKey ()
+{
+ EFI_STATUS Status;
+ UINT8 KeyChar;
+
+ KeypressCallback (NULL, NULL, gUsbData->aKBCScanCodeBufferStart, NULL);
+
+ //
+ // Fetch raw data from the USB keyboard input,
+ // and translate it into ASCII data.
+ //
+ Status = USBParseKey(&KeyChar);
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ InsertKeyChar(KeyChar);
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: StartPollingKey
+//
+// Description: Get the keys from the USB Keyboard buffer and process it
+//
+// Paremeters: IN EFI_EVENT Event event that has been signaled
+// IN VOID *Context
+//
+// Output: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID StartPollingKey(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 KeyChar;
+
+ KeypressCallback (NULL, NULL, gUsbData->aKBCScanCodeBufferStart, NULL);
+
+ //
+ // Fetch raw data from the USB keyboard input,
+ // and translate it into ASCII data.
+ //
+ Status = USBParseKey(&KeyChar);
+
+ if(EFI_ERROR(Status)) {
+ //
+ //If the Key ShiftState has valid key, report as Partial Key
+ //
+ if (gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->LeftCtrlOn || gUsbKeyboardData->LeftAltOn ||
+ gUsbKeyboardData->LeftLogoOn || gUsbKeyboardData->RightShiftOn || gUsbKeyboardData->RightCtrlOn ||
+ gUsbKeyboardData->RightAltOn || gUsbKeyboardData->RightLogoOn || gUsbKeyboardData->SysRqOn || gUsbKeyboardData->MenuOn) {
+
+ //
+ // Check the Partial Key for the RegsiterKeyNotify callback function
+ //
+// gUsbKeyboardData->ToggleState = (gUsbKeyboardData->ScrLkOn | gUsbKeyboardData->NumLockOn << 1 | gUsbKeyboardData->CapsOn << 2); //(EIP91889-)
+ UsbCheckKeyNotify(0);
+ }
+
+ return;
+ }
+
+ InsertKeyChar(KeyChar);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadAndProcessKey
+//
+// Description: It processes the key and sets its states.
+//
+// Paremeters: Key - VOID Pointer
+// KeySize - Size of the structure.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadAndProcessKey(
+ VOID *Key,
+ UINT8 KeySize
+)
+{
+
+ AMI_EFI_KEY_DATA TempKey;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 KeyChar;
+
+ TempKey.Key.UnicodeChar = 0;
+ TempKey.Key.ScanCode = SCAN_NULL;
+ EfiZeroMem(&(TempKey.KeyState),sizeof(EFI_KEY_STATE));
+
+ //
+ // if there is no saved ASCII byte, fetch it
+ // by calling USBKeyboardCheckForKey().
+ //
+ if(IsUSBKeyCharEmpty()) {
+ //(EIP83888+)>
+ do {
+ Status = USBKeyboardCheckForKey();
+ if(!(EFI_ERROR(Status)))
+ break;
+ }while(gUsbData->aKBCUsbDataBufferHead != gUsbData->aKBCUsbDataBufferTail);
+ if(EFI_ERROR(Status)) {
+ if (gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->LeftCtrlOn || gUsbKeyboardData->LeftAltOn ||
+ gUsbKeyboardData->LeftLogoOn || gUsbKeyboardData->RightShiftOn || gUsbKeyboardData->RightCtrlOn ||
+ gUsbKeyboardData->RightAltOn || gUsbKeyboardData->RightLogoOn || gUsbKeyboardData->SysRqOn || gUsbKeyboardData->MenuOn) {
+
+ TempKey.KeyState.KeyToggleState = KEY_STATE_EXPOSED;
+ }
+ else {
+ return Status;
+ }
+ }
+
+ }
+
+ if(!EFI_ERROR(Status)) {
+ RemoveKeyChar(&KeyChar);
+
+ //
+ // Translate saved ASCII byte into EFI_INPUT_KEY and PS/2 Scan Code
+ //
+ Status = USBKeyCodeToEFIScanCode(KeyChar,&(TempKey.Key));
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+ TempKey.EfiKey = UsbToEfiKeyTable[KeyChar-4];
+ TempKey.PS2ScanCode = KeyConvertionTable[KeyChar-4][3];
+ }
+
+
+// gUsbKeyboardData->ToggleState = (gUsbKeyboardData->ScrLkOn | gUsbKeyboardData->NumLockOn << 1 | gUsbKeyboardData->CapsOn << 2); //(EIP91889-)
+
+ TempKey.KeyState.KeyToggleState |= TOGGLE_STATE_VALID;
+ if (gUsbKeyboardData->ScrLkOn) {
+ TempKey.KeyState.KeyToggleState |= SCROLL_LOCK_ACTIVE;
+ }
+ if (gUsbKeyboardData->NumLockOn) {
+ TempKey.KeyState.KeyToggleState |= NUM_LOCK_ACTIVE;
+ }
+ if (gUsbKeyboardData->CapsOn) {
+ TempKey.KeyState.KeyToggleState |= CAPS_LOCK_ACTIVE;
+ }
+
+ TempKey.KeyState.KeyShiftState = SHIFT_STATE_VALID;
+ if (gUsbKeyboardData->LeftShiftOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_SHIFT_PRESSED;
+ }
+ if (gUsbKeyboardData->LeftCtrlOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_CONTROL_PRESSED;
+ }
+ if (gUsbKeyboardData->LeftAltOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_ALT_PRESSED;
+ }
+ if (gUsbKeyboardData->LeftLogoOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_LOGO_PRESSED;
+ }
+
+ if (gUsbKeyboardData->RightShiftOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_SHIFT_PRESSED;
+ }
+ if (gUsbKeyboardData->RightCtrlOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_CONTROL_PRESSED;
+ }
+ if (gUsbKeyboardData->RightAltOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_ALT_PRESSED;
+ }
+ if (gUsbKeyboardData->RightLogoOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_LOGO_PRESSED;
+ }
+ if (gUsbKeyboardData->SysRqOn) {
+ TempKey.KeyState.KeyShiftState |= SYS_REQ_PRESSED;
+ }
+ if (gUsbKeyboardData->MenuOn) {
+ TempKey.KeyState.KeyShiftState |= MENU_KEY_PRESSED;
+ }
+
+ ProcessMultiLanguage(&TempKey);
+
+
+ // Tab, BackSpace and Enter Key are considerd that it's non Printable
+ // Char and returned the ShiftKey status as it is.
+
+ if( TempKey.Key.UnicodeChar != 9 && TempKey.Key.UnicodeChar != 8
+ && TempKey.Key.UnicodeChar != 13 && TempKey.Key.UnicodeChar != 0) {
+ TempKey.KeyState.KeyShiftState &= ~(RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+ }
+
+ pBS->CopyMem(Key, &TempKey, KeySize);
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessMultiLanguage
+//
+// Description: It maps the current key to a Unicode character from
+// the keyboard layout
+//
+// Paremeters: KeyData - Pointer to the AMI_EFI_KEY_DATA .
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ProcessMultiLanguage(
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+
+ if(gMultiLangSupportProtocol == NULL) {
+ Status= pBS->LocateProtocol (
+ &gAmiMultiLangSupportGuid,
+ NULL,
+ &gMultiLangSupportProtocol
+ );
+ if(EFI_ERROR(Status)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ return gMultiLangSupportProtocol->KeyboardLayoutMap(gMultiLangSupportProtocol,KeyData);
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************