summaryrefslogtreecommitdiff
path: root/Core/EM/PS2CTL
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core/EM/PS2CTL
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core/EM/PS2CTL')
-rw-r--r--Core/EM/PS2CTL/Names.c269
-rw-r--r--Core/EM/PS2CTL/PS2Ctl.cif19
-rw-r--r--Core/EM/PS2CTL/PS2Ctl.sdl6
-rw-r--r--Core/EM/PS2CTL/Ps2Ctl.chmbin0 -> 138933 bytes
-rw-r--r--Core/EM/PS2CTL/efismplpp.c256
-rw-r--r--Core/EM/PS2CTL/hotkey.c420
-rw-r--r--Core/EM/PS2CTL/kbc.c1495
-rw-r--r--Core/EM/PS2CTL/kbc.h321
-rw-r--r--Core/EM/PS2CTL/mouse.c1215
-rw-r--r--Core/EM/PS2CTL/ps2ctl.h178
-rw-r--r--Core/EM/PS2CTL/ps2kbd.c2888
-rw-r--r--Core/EM/PS2CTL/ps2main.c655
-rw-r--r--Core/EM/PS2CTL/ps2mouse.h178
13 files changed, 7900 insertions, 0 deletions
diff --git a/Core/EM/PS2CTL/Names.c b/Core/EM/PS2CTL/Names.c
new file mode 100644
index 0000000..0acdad4
--- /dev/null
+++ b/Core/EM/PS2CTL/Names.c
@@ -0,0 +1,269 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/Names.c 7 8/28/09 10:03a Felixp $
+//
+// $Revision: 7 $
+//
+// $Date: 8/28/09 10:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/Names.c $
+//
+// 7 8/28/09 10:03a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 6 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 5 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 4 4/10/07 10:04a Felixp
+// LookupHID routine renamed to LookupPs2Hid to avoid linking issue when
+// linking with FloppyCtrl module
+//
+// 3 3/13/06 2:38a Felixp
+//
+// 2 3/04/05 1:37p Mandal
+//
+// 1 2/01/05 1:11a Felixp
+//
+// 3 1/28/05 1:21p Felixp
+// bug fix in component name
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 2 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 1 9/21/04 5:42p Olegi
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: Names.c
+//
+// Description: Component name producer for PS/2 Controller DXE driver
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "efi.h"
+#include "ps2ctl.h"
+#include <Protocol\ComponentName.h>
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+#endif
+//----------------------------------------------------------------------
+
+EFI_STATUS PS2GetDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+);
+
+EFI_STATUS
+PS2GetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+);
+
+extern EFI_DRIVER_BINDING_PROTOCOL gPS2CtlDriverBinding;
+extern PS2DEV_TABLE supportedDevices[];
+
+//----------------------------------------------------------------------
+
+CHAR16 *gPS2DriverName = L"AMI PS/2 Driver";
+
+//==================================================================================
+// Driver component name instance for PS2Ctl Driver
+//==================================================================================
+EFI_COMPONENT_NAME_PROTOCOL gPS2CtlDriverName = {
+ PS2GetDriverName,
+ PS2GetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PS2GetDriverName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// Parameters:
+// EFI_COMPONENT_NAME_PROTOCOL
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// CHAR8
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that 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.
+// CHAR16
+// DriverName - 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.
+//
+// Output:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PS2GetDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ *DriverName = gPS2DriverName;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PS2GetControllerName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Parameters:
+// EFI_COMPONENT_NAME_PROTOCOL
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// EFI_HANDLE
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// EFI_HANDLE
+// ChildHandle - 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.
+// CHAR8
+// *Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that 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.
+// CHAR16
+// **ControllerName - 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.
+//
+// Output:
+// 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.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PS2GetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+ ACPI_HID_DEVICE_PATH* acpiDP;
+ PS2DEV_TABLE *ps2dev = 0;
+ if(!Language || !ControllerName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+
+ //
+ // Find the last device node in the device path and return "Supported"
+ // for mouse and/or keyboard depending on the SDL switches.
+ //
+ if(!EFI_ERROR(GetPS2_DP(&gPS2CtlDriverBinding, Controller, &acpiDP, EFI_OPEN_PROTOCOL_GET_PROTOCOL)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, &ps2dev)){
+ *ControllerName = ps2dev->name;
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/PS2Ctl.cif b/Core/EM/PS2CTL/PS2Ctl.cif
new file mode 100644
index 0000000..df7d5f7
--- /dev/null
+++ b/Core/EM/PS2CTL/PS2Ctl.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "PS2CTL"
+ category = ModulePart
+ LocalRoot = "Core\EM\PS2CTL\"
+ RefName = "PS2CTL"
+[files]
+"PS2Ctl.sdl"
+"ps2kbd.c"
+"ps2main.c"
+"ps2ctl.h"
+"kbc.h"
+"kbc.c"
+"ps2mouse.h"
+"mouse.c"
+"efismplpp.c"
+"Names.c"
+"hotkey.c"
+"Ps2Ctl.chm"
+<endComponent>
diff --git a/Core/EM/PS2CTL/PS2Ctl.sdl b/Core/EM/PS2CTL/PS2Ctl.sdl
new file mode 100644
index 0000000..b70e3f8
--- /dev/null
+++ b/Core/EM/PS2CTL/PS2Ctl.sdl
@@ -0,0 +1,6 @@
+
+PATH
+ Name = "PS2Ctl_DIR"
+ Help = "PS/2 Controller source directory"
+End
+
diff --git a/Core/EM/PS2CTL/Ps2Ctl.chm b/Core/EM/PS2CTL/Ps2Ctl.chm
new file mode 100644
index 0000000..159b643
--- /dev/null
+++ b/Core/EM/PS2CTL/Ps2Ctl.chm
Binary files differ
diff --git a/Core/EM/PS2CTL/efismplpp.c b/Core/EM/PS2CTL/efismplpp.c
new file mode 100644
index 0000000..36bd2d9
--- /dev/null
+++ b/Core/EM/PS2CTL/efismplpp.c
@@ -0,0 +1,256 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/efismplpp.c 7 11/03/11 5:56a Rajeshms $
+//
+// $Revision: 7 $
+//
+// $Date: 11/03/11 5:56a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/efismplpp.c $
+//
+// 7 11/03/11 5:56a Rajeshms
+// [TAG] EIP73263
+// [Category] Improvement
+// [Description] PS2Ctl Driver Follow the UEFI Driver Model as per the
+// UEFI Spec.
+// [Files] ps2main.c, efismplpp.c
+//
+// 6 8/23/10 4:26a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.h
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 5 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 4 12/16/08 2:06a Iminglin
+// The function value of StopMouse for compliance.
+//
+// 3 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 2 3/04/05 1:37p Mandal
+//
+// 1 2/01/05 1:11a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 3 10/04/04 7:42p Olegi
+//
+// 2 9/21/04 2:29p Andriyn
+//
+// 1 9/14/04 2:56p Andriyn
+//
+// 4 9/14/04 2:46p Andriyn
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: efismplpp.c
+//
+// Description: PS/2 mouse implmentation of simple pointer protocol
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "ps2ctl.h"
+#include <AmiLib.h>
+#include "ps2ctl.h"
+#include "kbc.h"
+#include "ps2mouse.h"
+
+//----------------------------------------------------------------------
+
+
+extern MOUSE gMouse;
+extern EFI_GUID gDevicePathProtocolGuid;
+EFI_GUID gSimplePointerGuid = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StartMouse
+//
+// Description: This routine is called from Driver Binding Start function.
+// It starts the mouse support
+//
+// Parameters:
+// EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this instance of driver
+// binding protocol structure
+// EFI_HANDLE Controller - Handle for this driver
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StartMouse (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *pDummyDevPath;
+ MOUSE* pmouse = 0;
+
+ if (EFI_ERROR(gSysTable->BootServices->OpenProtocol(
+ Controller,
+ &gDevicePathProtocolGuid,
+ &pDummyDevPath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DetectPS2KeyboardAndMouse();
+
+ if ( EFI_ERROR(InitMOUSE( &pmouse ))) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnMouse,
+ pmouse,
+ &pmouse->iSmplPtr.WaitForInput);
+ //
+ // Install protocol interfaces for the pointer device.
+ //
+ Status = gSysTable->BootServices->InstallProtocolInterface (
+ &Controller, &gSimplePointerGuid, EFI_NATIVE_INTERFACE,
+ &pmouse->iSmplPtr);
+
+ if (EFI_ERROR(Status)) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ gSysTable->BootServices->CloseEvent(pmouse->iSmplPtr.WaitForInput);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StopMouse
+//
+// Description: This routine is called from Driver Binding Start function.
+// It stops the mouse support
+//
+// Parameters:
+// EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this instance of driver
+// binding protocol structure
+// EFI_HANDLE Controller - Handle for this driver
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StopMouse (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller )
+{
+ EFI_STATUS Status;
+
+ //
+ // Kill wait event
+ //
+ Status = gSysTable->BootServices->CloseEvent(gMouse.iSmplPtr.WaitForInput);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Uninstall protocol interfaces from the Mouse device.
+ //
+ Status = gSysTable->BootServices->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gSimplePointerGuid, &gMouse.iSmplPtr,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Close protocols that is open during Start
+ //
+ Status = gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pBS->FreePool(gMouse.iSmplPtr.Mode);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/hotkey.c b/Core/EM/PS2CTL/hotkey.c
new file mode 100644
index 0000000..21ef2b9
--- /dev/null
+++ b/Core/EM/PS2CTL/hotkey.c
@@ -0,0 +1,420 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/hotkey.c 9 4/27/11 4:38a Lavanyap $
+//
+// $Revision: 9 $
+//
+// $Date: 4/27/11 4:38a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/hotkey.c $
+//
+// 9 4/27/11 4:38a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 8 12/01/10 6:13a Anandv
+// [TAG] - EIP 45947
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Build Error on disabling INIT_DEFAULT_HOTKEYS SDL Token.
+// [RootCause] - KEY_ASSOCIATION structure variable not declared based on
+// INIT_DEFAULT_HOTKEYS SDL Token.
+// [Solution] - KEY_ASSOCIATION structure variable declared based on
+// INIT_DEFAULT_HOTKEYS SDL Token
+// [Files] - hotkey.c
+//
+// 7 8/23/10 4:31a Rameshr
+// Bug Fix: EIP 40818
+// Symptoms: Pause/Break function key has no function in logo screen
+// FilesModified: HotKey.c
+// Details:Pause key doesn't have valid Ps2 SCAN code. ProcesshotKey
+// function will get 0 as input for Pause key and it tries to execute the
+// invalid function.So getting exception.
+//
+// 6 1/06/10 12:09a Rameshr
+// Sometimes reset fail in BIOS Setup
+// EIP:33327
+// Ctrl+alt+del+Shift key also should reset the system
+//
+// 5 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 4 4/21/08 5:48p Olegi
+// Bugfix in RegisterHotKey routine for multiple hot keys.
+//
+// 3 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 2 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 1 2/01/05 1:11a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 1 9/30/04 8:07a Olegi
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: hotkeys.c
+//
+// Description: PS/2 keyboard hotkeys support routines
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "ps2ctl.h"
+#include "kbc.h"
+#include <Protocol\HotKeys.h>
+
+EFI_GUID gHotKeysGuid = EFI_HOT_KEYS_PROTOCOL_GUID;
+
+HOT_KEYS_PROTOCOL HotKeysProtocol;
+KEY_ASSOCIATION *HotKeys_Table;
+
+extern UINT8 MaxHotKeys;
+extern BOOLEAN InitDefaultHotKeys;
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CopyKey
+//
+// Description: HotKey helper function - Copies key codes from source to
+// target buffers
+//
+// Parameters:
+// KEY_ASSOCIATION *SrcKey - Pointer to source buffer
+// KEY_ASSOCIATION *TrgKey - Pointer to target buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CopyKey (
+ IN KEY_ASSOCIATION *SrcKey,
+ IN KEY_ASSOCIATION *TrgKey
+ )
+{
+ TrgKey->KeyCode = SrcKey->KeyCode;
+ TrgKey->KeyAttrib = SrcKey->KeyAttrib;
+ TrgKey->ReportKey = SrcKey->ReportKey;
+ TrgKey->KeyExtendedFunc = SrcKey->KeyExtendedFunc;
+ TrgKey->FunctionContext = SrcKey->FunctionContext;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RegisterHotKey
+//
+// Description: This is HotKey protocol API implementation function.
+// It registers the "extended" key function.
+//
+// Parameters: KEY_ASSOCIATION *HotKey - Key code to register
+// BOOLEAN ReplaceExisting - a rule that tells whether or
+// not we will replace the existing function; this
+// parameter will not be considered in case the function
+// for a given key is not assigned yet.
+//
+// Output : EFI_SUCCESS if function is successfully registered
+// EFI_OUT_OF_RESOURCES if we already have reached
+// MAX_HOTKEYS registered functions and we are not
+// replacing the existing one
+// EFI_ACCESS_DENIED if requested key has been already
+// assigned, can be returned only when ReplaceExisting
+// is FALSE
+//
+// Modified: HotKeys_Table
+//
+// Referrals: HotKeys_Table
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS RegisterHotKey (
+ IN KEY_ASSOCIATION *HotKey,
+ IN BOOLEAN ReplaceExisting )
+{
+
+ KEY_ASSOCIATION *hk = HotKeys_Table;
+ UINT8 i;
+ UINT8 emptySpot = 0xFF;
+ //
+ // See if the key is already registered, at the same time find the empty
+ // spot in HotKeys_Table
+ //
+ for (i = 0; i < MaxHotKeys; i++, hk++) {
+ if (!hk->KeyCode) { // empty entry found
+ if (emptySpot == 0xff) {
+ emptySpot = i;
+ }
+ continue;
+ }
+ if ((hk->KeyCode == HotKey->KeyCode) && (hk->KeyAttrib == HotKey->KeyAttrib)) {
+ if (ReplaceExisting) {
+ CopyKey(HotKey, hk);
+ return EFI_SUCCESS;
+ }
+ else {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ }
+ //
+ // We are here if the key duplicate is not found
+ //
+ if (emptySpot == 0xFF) {
+ return EFI_OUT_OF_RESOURCES; // no empty space found either
+ }
+
+ CopyKey(HotKey, &HotKeys_Table[emptySpot]); // fill in the new entry
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UnregisterHotKeys
+//
+// Description: This is HotKey protocol API implementation function.
+// It unregisters all "extended" key functions.
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS if functions are successfully unregistered
+// EFI_ACCESS_DENIED if functions are not unregistered
+//
+// Modified: HotKeys_Table
+//
+// Referrals: HotKeys_Table
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UnregisterHotKeys()
+{
+ UINT8 i;
+ KEY_ASSOCIATION ZeroedEntry = {0};
+
+ for (i = 0; i < MaxHotKeys; i++) {
+ CopyKey(&ZeroedEntry, &HotKeys_Table[i]);
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ResetSystem
+//
+// Description: This routine performs a warm boot of the system
+//
+// Parameters: VOID *Context - Pointer to context
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ResetSystem (
+ VOID *Context )
+{
+ gSysTable->RuntimeServices->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InitHotKeys
+//
+// Description: This routine is called from StartKeyboard function,
+// it initializes the PS/2 keyboard hot keys and produces
+// HotKeys protocol.
+//
+// Parameters: EFI_HANDLE Controller - Handle for this driver
+//
+// Output: EFI_STATUS - Status of the operation
+//
+// Modified: HotKeysProtocol
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitHotKeys (
+ EFI_HANDLE Controller )
+{
+ EFI_STATUS Status;
+ KEY_ASSOCIATION hk;
+ //
+ // Publish the hot key registration interface
+ //
+ HotKeysProtocol.RegisterHotKey = RegisterHotKey;
+ HotKeysProtocol.UnregisterHotKeys = UnregisterHotKeys;
+ Status = gSysTable->BootServices->InstallProtocolInterface (
+ &Controller,
+ &gHotKeysGuid,
+ EFI_NATIVE_INTERFACE,
+ &HotKeysProtocol
+ );
+ //
+ // Initialise the hotkeys table list
+ //
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ MaxHotKeys * sizeof(KEY_ASSOCIATION),
+ &HotKeys_Table );
+ pBS->SetMem( HotKeys_Table, MaxHotKeys * sizeof(KEY_ASSOCIATION), 0);
+
+ if ( InitDefaultHotKeys ) {
+ //
+ // Register Ctl+Alt+Del combination for Soft Reset
+ //
+ hk.KeyCode = 0x53;
+
+ hk.ReportKey = TRUE;
+ hk.KeyExtendedFunc = ResetSystem;
+ hk.FunctionContext = NULL;
+
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | LEFT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | RIGHT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | LEFT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | RIGHT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | LEFT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | LEFT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | LEFT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | LEFT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessHotKey
+//
+// Description: This routine searches the HotKey table for the matching
+// key and executes the corresponding "key extension"
+// function.
+//
+// Parameters: UINT8 Code - key make code
+// UINT16 KeyShiftState - Shift/Alt/Ctrl modifiers:
+// RIGHT_SHIFT_PRESSED 0x00000001
+// LEFT_SHIFT_PRESSED 0x00000002
+// RIGHT_CONTROL_PRESSED 0x00000004
+// LEFT_CONTROL_PRESSED 0x00000008
+// RIGHT_ALT_PRESSED 0x00000010
+// LEFT_ALT_PRESSED 0x00000020
+// RIGHT_LOGO_PRESSED 0x00000040
+// LEFT_LOGO_PRESSED 0x00000080
+//
+// Output: EFI_SUCCESS if 1)key is not found or 2)key is found,
+// function executed and key has to be reported back
+// to the caller;
+// EFI_NOT_READY if key is found but is not to be reported
+// back to the caller.
+// Referrals: HotKeys_Table
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ProcessHotKey (
+ UINT8 Code,
+ UINT16 KeyShiftState
+)
+{
+ KEY_ASSOCIATION *hk = HotKeys_Table;
+ UINT8 i;
+
+ //
+ // Validate the Input Data
+ //
+ if(Code == 0 && KeyShiftState == 0) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Find the match in the table
+ //
+ for (i = 0; i < MaxHotKeys; i++) {
+ if ((hk->KeyCode == Code) && (hk->KeyAttrib == (UINT8)KeyShiftState)) {
+ //
+ // Match found - execute the function
+ //
+ hk->KeyExtendedFunc(hk->FunctionContext);
+ return (hk->ReportKey)? EFI_SUCCESS: EFI_NOT_READY;
+ }
+ hk++;
+ }
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/kbc.c b/Core/EM/PS2CTL/kbc.c
new file mode 100644
index 0000000..1712196
--- /dev/null
+++ b/Core/EM/PS2CTL/kbc.c
@@ -0,0 +1,1495 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.c 41 11/07/12 12:24a Srikantakumarp $
+//
+// $Revision: 41 $
+//
+// $Date: 11/07/12 12:24a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.c $
+//
+// 41 11/07/12 12:24a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 40 10/18/12 8:58a Deepthins
+// [TAG] EIP70313
+// [Category] Improvement
+// [Description] Used CheckIssueLEDCmd in function LEDsOnOff instead of
+// OutToKb(Kbd, 0xED)
+// [Files] kbc.c, ps2kbd.c and kbc.h
+//
+// 39 6/05/12 9:30a Lavanyap
+// [TAG] EIP91313
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] Ps2 keyboard does not work with Ps2Ctl label (INT)4.6.5.4
+// [RootCause] Could not process PS2 keyboard data since there were more
+// frequent calls to DISABLE the Keyboard.
+// [Solution] Disabled and enabled the keyboard only before processing
+// the PS2 keyboard data.
+// [Files] kbc.c
+//
+// 38 5/02/12 2:27a Deepthins
+// [TAG] EIP63116
+// [Category] Improvement
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 37 4/30/12 2:21a Rajeshms
+// [TAG] EIP86986
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Can not detect F8 key on PS2 Keyboard while booting to EFI
+// aware OS.
+// [RootCause] Make code of F8 key (0x42) is taken by int09h and EFI
+// aware OS calls only one ReadKeyStroke() for any key catch, Now PS2
+// driver will take Break Code of F8 key(0xC2) and returns EFI_NOT_READY.
+// [Solution] Multiple Read from PS2 keyboard is implemented and read
+// exits if any valid key is detected. Also, the BDA keyboard buffer is
+// checked for any missed key in EFI.
+// [Files] ps2kbd.c, kbc.c, CORE_DXE.sdl
+//
+// 36 2/01/12 1:59a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 35 8/02/11 4:43a Rameshr
+// [TAG] - EIP 58974
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Yellow exclamation mark in Windows when PS2 KB/MS are not
+// present.
+// [RootCause]- ACPI name space variable reports that PS2 device present
+// [Solution] - Updated the SIO device status based on the device present
+// after BDS.
+// [Files] - Kbc.c, Kbc.h , Ps2main.c
+//
+// 34 4/27/11 4:36a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 33 2/05/11 3:57p Artems
+// Fixed bug with ellow exclamation mark in Windows, when PS2 keyboard is
+// absent
+//
+// 32 1/24/11 3:39p Pats
+// [TAG] - EIP 18488
+// [Category] - Enhancement
+// [Severity] - Normal
+// [Symptom] - PS2CTL: Need hooks for port swap, Keybaord mouse detect.
+// [RootCause] - Support may be needed for kbc controller or SIO with
+// different support from AMI KB-5.
+// [Solution] - Removed token control of AutodetectKbdMousePortsPtr.
+// [Files] - kbc.c
+//
+// 31 1/05/11 1:02a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 30 12/10/10 5:28a Rameshr
+// [TAG] - EIP 47011
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - DTM IO Tests fail due to presence of PS/2 devices that are
+// not ready - no PS/2 devices attached during test.
+// [RootCause]- PS2 device _STA method returns that, device is present .
+// [Solution] - Updated the SIO device status based on the device
+// presence.
+// [Files] - Kbc.c , Kbc.h, Mouse.c
+//
+// 29 8/23/10 4:37a Rameshr
+// Bug Fix: EIP 41862
+// Symptoms: If plug PS/2 KB only, Can`t use hot key enter iSCSI OPROM
+// .The CheckIssueLEDCmd routine cause PS2 keyboard not work.
+// FilesModified: Kbc.c
+// Details: Send Data immediately after sending LED command "ED".
+//
+// 28 8/23/10 4:23a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.c
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 27 7/01/10 9:03a Rameshr
+// Issue:If PS/2 KBD isn't present, KBC returns oxFE when send 0xED
+// command, that makes system to hang for 5 to 10 Sec.
+// Solution:If command output is 0xFE (Resent) , tried for 3 times and
+// gets out.
+// EIP 40515
+//
+// 26 8/04/09 4:32p Rameshr
+// Symptom: Boot to Shell and Press Ps2 keyboard Key, Reduces the EFI
+// available memory.
+// RootCause: Progress_code macro allocate the memory for the Data hub and
+// when ever key pressed , Disable/enable keyboard gets called. That sends
+// the progress code.
+// Solution: Removed the Progress code from Disable/Enable keyboard
+// functions.
+//
+// 25 7/01/09 5:29p Olegi
+// Correction: previous file headers changes were done on the older file.
+// Now changes are applied to the latest file.
+//
+// 24 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 23 4/20/09 1:53p Rameshr
+// CCB byte programmed once Keyboard controller is avilable.
+// EIP 19880-CCB byte not programmed
+//
+// 22 4/22/08 4:31p Felixp
+// Additional progress codes added
+//
+// 21 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 20 10/23/07 4:05p Olegi
+// Removed BDA related data storage.
+//
+// 19 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 18 3/19/07 2:22p Pats
+// Removed test for keyboard active. Issues start keyboard command on
+// logic of SDL tokens only.
+//
+// 17 3/13/07 5:35p Pats
+// Fixed problem of Lakeport not seeing setup key.
+//
+// 16 3/13/07 3:01p Pats
+// If keyboard detection is disabled, tests for keyboard active and issues
+// keyboard enable command only if it is not active. This preserves the
+// input key if there is one.
+//
+// 15 3/13/07 11:11a Pats
+// Added line to enable keyboard if keyboard detection is disabled.
+// Required for some platforms.
+//
+// 14 3/01/07 3:20p Pats
+// Fixed problem of mouse not working if keyboard detection disabled.
+//
+// 13 2/28/07 6:05p Pats
+// Made PS2 Keyboard detection removable with SDL token, to speed up boot,
+// and to keep keep Setup key (F2 or Del) from being absorbed.
+//
+// 12 4/12/06 9:14a Srinin
+// Write to Port 80h removed.
+//
+// 11 1/09/06 11:38a Felixp
+//
+// 9 12/22/05 10:23a Srinin
+// KBD Enable/Disable call optimized. Cleaned up the code.
+//
+// 8 10/27/05 1:04p Srinin
+// When command to KBD is given, check for Timeout error added.
+//
+// 7 10/11/05 4:14p Srinin
+// KBD and Mouse init done together. Re-entry problem fixed.
+//
+// 6 8/31/05 6:21p Srinin
+// Comments added to "AutodetectKbdMousePorts"
+//
+// 5 8/31/05 4:45p Srinin
+// When KBD not connected, DetectPS2Keyboard
+// will returns EFI_SUCCESS in order to support hot plug.
+//
+// 4 8/30/05 5:23p Srinin
+// PortSwap logic changed.
+//
+// 3 5/03/05 8:51a Olegi
+// Delay correction in OutToKb function.
+//
+// 2 2/25/05 10:34a Olegi
+// Removed duplicated code.
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 2 9/17/04 7:02p Olegi
+//
+// 1 8/27/04 3:18p Olegi
+// Initial VSS checkin.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: kbc.c
+//
+// Description: PS/2 Controller I/O support fuctions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "ps2ctl.h"
+#include "kbc.h"
+#include "genericSio.h"
+
+
+//----------------------------------------------------------------------
+
+extern BOOLEAN MouseResetRequired;
+extern BOOLEAN DetectPs2KeyboardValue;
+extern BOOLEAN InstallKeyboardMouseAlways;
+extern UINT32 IbFreeTimeoutValue;
+extern UINT32 IbFreeMaxTimeoutValue;
+BOOLEAN MouseEnableState = FALSE;
+BOOLEAN KBDEnableState = TRUE;
+BOOLEAN Ps2KbdDetected = FALSE;
+BOOLEAN Ps2KbdMouseDetected=FALSE;
+extern BOOLEAN Ps2MouseDetected;
+extern BOOLEAN KbdIrqSupport;
+extern UINT8 gKeyboardIrqInstall;
+extern EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+BOOLEAN InsidePS2DataDispatcher = FALSE;
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KBCDummyGetData
+//
+// Description: Reads keyboard data port to clear it
+//
+// Parameters: VOID *Context - Pointer to context
+//
+// Output: UINT8 - Keyboard data port data
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBCDummyGetData (
+ VOID *Context )
+{
+ UINT8 bData;
+ bData = IoRead8(KBC_DATA_PORT);
+ TRACEKBD((-1,"KD %X ", bData));
+ return bData;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: MouseDummyGetData
+//
+// Description: Reads keyboard data port to clear it
+//
+// Parameters: VOID *Context - Pointer to context
+//
+// Output: UINT8 - Keyboard data port data
+//
+// Modified: MouseResetRequired
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+MouseDummyGetData (
+ VOID *Context )
+{
+ UINT8 bData;
+ bData = IoRead8(KBC_DATA_PORT);
+ TRACEKBD((-1,"MD %X ", bData));
+ MouseResetRequired = TRUE; // Since a orphan mouse data is
+ // received, mouse packet will be out
+ // of sync.
+ return bData;
+
+}
+
+
+//----------------------------------------------------------------------
+// The following two fuction pointers are initialized with dummy
+// routines; they will be updated with the real routine pointers
+// in the corresponding device drivers' start functions.
+//----------------------------------------------------------------------
+
+STATEMACHINEPROC DrivePS2KbdMachine = KBCDummyGetData;
+STATEMACHINEPROC DrivePS2MouseMachine = MouseDummyGetData;
+
+extern KEYBOARD gKbd;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KBCBatTest
+//
+// Description: Runs Basic Assurance Test on KBC.
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS KBCBatTest()
+{
+ UINT16 wCounter = 0xFFFF;
+ PROGRESS_CODE(DXE_KEYBOARD_SELF_TEST);
+ //
+ // Empty KBC before BAT
+ //
+ for (; wCounter; wCounter--) {
+ IoRead8(KBC_DATA_PORT);
+ IoDelay();
+ if (!(IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF | KBC_IBF))) {
+ break;
+ }
+ }
+ if (!wCounter) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Perform BAT
+ //
+ if (Read8042(0xAA) != 0x55) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AutodetectKbdMousePorts
+//
+// Description: Auto detection of KB/MS using AMI KB-5. This code will
+// allow the connector swap of Keyboard and PS2 Mouse i.e.
+// keyboard can be connected to PS2 Mouse connector and
+// vice-versa.
+//
+// Parameters: None. AMI KB-5 present in the system, keyboard controller
+// BAT is complete.
+//
+// Output: None
+//
+//
+// Notes: This code should be used only if the motherboard has
+// AMI KB-5 which is also available in IO chipsets having KBC
+// e.g. SMC932, etc.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID AutodetectKbdMousePorts()
+{
+ UINT8 bData, Index;
+
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ WriteKeyboardCommand(0x60); // Lock KBD
+ IoRead8(KBC_DATA_PORT); // Discard any data
+
+ Write8042CommandByte(0x74); // KBD and Aux device disabled
+
+// Check for KBC version
+ IoRead8(KBC_DATA_PORT); // Discard any data
+ WriteKeyboardCommand(0xa1); //
+ if (!ObFullReadTimeout(&bData, 20, TRUE) && bData == 0x35) {
+
+ WriteKeyboardCommand(0x60);
+ WriteKeyboardData(4);
+
+ for (Index = 6; Index; Index--){ // Read max. 6 data
+ if (ObFullReadTimeout(&bData, 10, TRUE)) break;
+ }
+
+ WriteKeyboardCommand(0xa7); // Disable Mouse
+ WriteKeyboardCommand(0xc8); // Select Primary
+
+ WriteKeyboardData(rKeyboardID); // Read KBD ID
+
+ ObFullReadTimeout(&bData, 1000, TRUE); // Read ACK
+
+ if (bData == rKeyboardID) goto PortSwap;
+
+ if (bData == KB_ACK_COM) {
+ ObFullReadTimeout(&bData, 100, TRUE);
+// When Mouse is connected to KBD port, control goes to PortSwap here
+ if (!bData) goto PortSwap;
+ ObFullReadTimeout(&bData, 100, TRUE);
+ }
+ bData = IoRead8(KBC_CMDSTS_PORT);
+// When KBD is connected to the KBD port, control returns here
+ if (!(bData & KBC_TIMEOUT_ERR)) return;
+
+ WriteKeyboardCommand(0xD4); // Secondary Port
+ WriteKeyboardData(rKeyboardID); // Read KBD ID
+ ObFullReadTimeout(&bData, 1000, TRUE);
+ if (bData == rKeyboardID) return;
+ if (bData == KB_ACK_COM) {
+// When Mouse alone is connected to Mouseport, control returns here
+ if (!ObFullRead()) return;
+ bData = ObFullRead();
+ }
+ bData = IoRead8(KBC_CMDSTS_PORT);
+// When KBD alone is connected to Mouse port, no time out error and control
+// goes to portswap.
+ if (bData & KBC_TIMEOUT_ERR) return;
+
+PortSwap:
+ WriteKeyboardCommand(0xC9);
+ return;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AuxDeviceCommand
+//
+// Description: This routine issues AuxDevice command, and returns the
+// from the AUX device
+// the connector swap of Keyboard and PS2 Mouse i.e. keyboard
+// can be connected to PS2 Mouse connector and vice-versa.
+//
+// Parameters: UINT8 bCmd - AUX device command
+//
+// Output: UINT8 Data from AUX device
+//
+// Notes: Only AUX commands that expect the response from AUX device
+// can be executed using this function; otherwise the code will
+// be stuck waiting for OBF
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 AuxDeviceCommand (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return (UINT8)Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xD4);
+
+ return IssueCommand(bCmd);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IssueCommand
+//
+// Description: Helper function to read the data after executing AUX
+// device command.
+//
+// Parameters: UINT8 bCmd - AUX device command
+//
+// Output: UINT8 Data from AUX device
+//
+// Notes: Only AUX commands that expect the response from AUX device
+// can be executed using this function; otherwise the code will
+// be stuck waiting for OBF
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 IssueCommand (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return (UINT8)Status;
+ }
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+ for (;;)
+ {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) {
+ return IoRead8(KBC_DATA_PORT);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Read8042
+//
+// Description: Sends the given command to KBC, reads and returns the
+// acknowledgement byte returned from KBC.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+//
+// Output: UINT8 Acknowledgment byte
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 Read8042 (
+ UINT8 bCmd )
+{
+
+ UINT8 bData = 0xFE;
+ WriteKeyboardCommand(bCmd);
+ ObFullReadTimeout(&bData, 40, FALSE);
+ return bData;
+
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadDevice
+//
+// Description: Sends the given command to KBD, reads and returns the
+// acknowledgement byte returned from KBD.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+// UINT8 *Data - Pointer to data buffer
+// UINT8 Response - Response expected
+//
+// Output: EFI_SUCCESS - Data == Response
+// EFI_DEVICE_ERROR - Data != Response
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadDevice (
+ UINT8 bCmd,
+ UINT8 *Data,
+ UINT8 Response )
+{
+
+ WriteKeyboardData(bCmd);
+ if (ObFullReadTimeout(Data, 40, FALSE)) return EFI_DEVICE_ERROR;
+ if (*Data == Response) return EFI_SUCCESS;
+ return EFI_DEVICE_ERROR;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WriteKeyboardCommand
+//
+// Description: Writes command to KBC.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteKeyboardCommand (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, bCmd);
+ IbFree();
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WriteKeyboardData
+//
+// Description: Writes data to KBC.
+//
+// Parameters: UINT8 bCmd - Data to send to KBC
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteKeyboardData (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Write8042CommandByte
+//
+// Description: Writes CCB to KBC
+//
+// Parameters: UINT8 bCCB - Command byte to send to KBC
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID Write8042CommandByte (
+ UINT8 bCCB )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ WriteKeyboardCommand(0x60); // CMD to send command byte
+ IoWrite8(KBC_DATA_PORT, bCCB); // Write command byte into KBC
+ IbFree(); // Wait until input buffer is free
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullRead
+//
+// Description: Waits for Output Buffer Full and then reads the data port
+//
+// Parameters: None
+//
+// Output: UINT8 KBC Data port data
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 ObFullRead()
+{
+ for (;;) {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) {
+ return IoRead8(KBC_DATA_PORT);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IbFree
+//
+// Description: Waits for Iutput Buffer to be empty
+//
+// Parameters: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID IbFree()
+{
+ for (;;) {
+ if (!(IoRead8(KBC_CMDSTS_PORT) & KBC_IBF)) {
+ break;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IbFreeTimeout
+//
+// Description: Waits a specified timeout for Iutput Buffer to be empty
+//
+// Parameters: UINT32 TimeoutValue
+//
+// Return value: EFI_STATUS (EFI_SUCCESS or EFI_TIMEOUT)
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS IbFreeTimeout( UINT32 TimeoutValue)
+{
+ UINTN i;
+
+ for (i = 0; i < TimeoutValue; i++) {
+ if (!(IoRead8(KBC_CMDSTS_PORT) & KBC_IBF)) {
+ return EFI_SUCCESS;
+ }
+ gSysTable->BootServices->Stall(1000); // 1 ms
+ }
+ return EFI_TIMEOUT;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IoDelay
+//
+// Description: Performs IO delay by executing IO read.
+//
+// Parameters: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID IoDelay()
+{
+ IoRead8(0x61);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullReadTimeout
+//
+// Description: This routine checks for the data availbility in output
+// buffer for a short period of time, if data is available
+// within this time, it reads and returns the data from
+// output buffer.
+//
+// Paremeters: UINT8* data - Pointer to the byte to be updated
+// UINT32 msec - Milliseconds timeout
+// BOOLEAN ONLYOBF - Only waits for OBF if true
+//
+// Output: BOOLEAN - Returns FALSE if data is successfully updated
+// (no timeout), data is updated
+// Returns TRUE if time-out
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+ObFullReadTimeout (
+ UINT8* data,
+ UINT32 msec,
+ BOOLEAN ONLYOBF )
+{
+
+ UINT8 bData;
+ UINT32 loopcount = msec << 1;
+
+
+ for (; loopcount; loopcount--) {
+
+ bData = IoRead8(KBC_CMDSTS_PORT);
+
+ if (ONLYOBF && (bData & KBC_OBF)) {
+ *data = IoRead8(KBC_DATA_PORT);
+ return FALSE;
+ }
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ *data = IoRead8(KBC_DATA_PORT);
+ if (bData & 0x40) {
+ TRACEKBD((-1, "Status Reg K : %x, %x\n", bData, *data));
+ return TRUE;
+ }
+ else return FALSE; // No timeout
+ }
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF | KBC_AUX_OBF)){
+ TRACEKBD((-1, "AUX OBF inside KBD"));
+ return TRUE;
+ }
+
+ gSysTable->BootServices->Stall(500); // 0.5msec
+
+ }
+ TRACEKBD((-1, "KBD data not available"));
+ return TRUE; // Timeout
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OutToKb
+//
+// Description: Send the given command to KDB during runtime.
+//
+// Parameters: KEYBOARD* kbd - Pointer to keyboard buffer
+// UINT8 bCmd - Command to send to keyboard
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+OutToKb (
+ KEYBOARD* kbd,
+ UINT8 bCmd )
+{
+ UINT8 bCounter1, bData;
+ UINT32 Counter;
+ EFI_STATUS Status;
+
+ //
+ // If Keyboard irq is supported, device acknowlegement is prossed by IRQ
+ // Handler. The acknowledgement data is stored in Kbd->CommandResponded
+ //
+ if(KbdIrqSupport && gKeyboardIrqInstall){
+ if(KBDEnableState) {
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+ for (Counter = 1000; Counter > 0; Counter--) {
+ if (kbd->CommandResponded == KB_ACK_COM){
+ kbd->CommandResponded =NULL;
+ return EFI_SUCCESS;
+ }
+ if (kbd->CommandResponded == KB_RSND_COM){
+ kbd->CommandResponded =NULL;
+ break;
+ }
+ gSysTable->BootServices->Stall(1000);
+ }
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+
+ for (bCounter1 = 3; bCounter1 > 0; bCounter1--) {
+ IbFree();
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+
+ for (Counter = 1000; Counter > 0; Counter--) {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) {
+ bData = IoRead8(KBC_DATA_PORT);
+ if (bData == 0xFA) {
+ return EFI_SUCCESS;
+ } else if (bData == 0xFE) {
+ break;
+ } else {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_TIMEOUT_ERR) break;
+ //
+ // Insert the key into the buffer
+ //
+ if (kbd) {
+ HandleKBDData(kbd, bData);
+ if (kbd->KeyIsReady) {
+ ProcessHotKey(kbd->KeyData.PS2ScanCode, kbd->KeyData.KeyState.KeyShiftState);
+ InsertKeyToBuffer(kbd, &kbd->KeyData);
+ kbd->KeyIsReady = FALSE;
+ }
+ }
+ }
+ }
+ gSysTable->BootServices->Stall(1000); // 1msec
+ }
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DisableKeyboard
+//
+// Description: Disables KBD interface and reads the data from KBC
+// data port.
+//
+// Modified: KBDEnableState
+//
+// Referral(s): KBDEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DisableKeyboard()
+{
+ EFI_STATUS Status;
+
+ if (!KBDEnableState) return;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xAD);
+ IbFree();
+ KBDEnableState = FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: EnableKeyboard
+//
+// Description: Enables KBD interface.
+//
+// Paremeters: None
+//
+// Output: Status
+//
+// Modified: KBDEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EnableKeyboard()
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+
+ if (KBDEnableState) {
+ return EFI_SUCCESS;
+ }
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xAE);
+ Status = IbFreeTimeout(IbFreeTimeoutValue);
+ KBDEnableState = TRUE;
+ if (EFI_ERROR(Status)) {
+ KBDEnableState = FALSE;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DisableAuxDevice
+//
+// Description: Disables Aux interface.
+//
+// Paremeters: None
+//
+// Output: None
+//
+// Modified: MouseEnableState
+//
+// Referrals: MouseEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DisableAuxDevice()
+{
+ EFI_STATUS Status;
+ if (!MouseEnableState) return;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xA7);
+ IbFree();
+ MouseEnableState = FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: EnableAuxDevice
+//
+// Description: Enables Aux interface.
+//
+// Paremeters: None
+//
+// Output: None
+//
+// Modified: MouseEnableState
+//
+// Referrals: MouseEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EnableAuxDevice()
+{
+ EFI_STATUS Status;
+ if (MouseEnableState) return;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xA8);
+ IbFree();
+ MouseEnableState = TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPS2KeyboardAndMouse
+//
+// Description: Detects the presence of Keyboard and Mouse in KBC port.
+//
+// Parameters: None. Keyboard interface is disabled.
+//
+// Output: Ps2KbdDetected and Ps2MouseDetected variable set accorinding
+// the device presence
+//
+// Modified: Ps2KbdDetected, Ps2MouseDetected
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPS2KeyboardAndMouse()
+{
+ UINT16 wCount;
+ UINT8 bData;
+ BOOLEAN bAck = FALSE;
+
+ if(Ps2KbdMouseDetected) {
+ //
+ // Ps2Keyboard and Mouse Detected already
+ //
+ return EFI_SUCCESS;
+ }
+
+ Ps2KbdMouseDetected=TRUE;
+
+ DetectPs2Mouse();
+
+
+ if ( DetectPs2KeyboardValue ) {
+
+ PROGRESS_CODE(DXE_KEYBOARD_DETECT);
+ Write8042CommandByte (0x6d);
+ KBCGetData(); // Dummy read
+
+ for (wCount = 0; wCount < 3; wCount++) {
+ // Disable Scanning
+ if (!ReadDevice(KBD_DISABLE_SCANNING, &bData, KB_ACK_COM)) break;
+ if (IoRead8(KBC_CMDSTS_PORT) & 0x40) { // Time out error
+ gSysTable->BootServices->Stall(6000); // 6 msec
+ // After power-up some junk data comes from KBD. If not eaten
+ // other command will fail.
+ KBCGetData();
+ }
+ }
+
+ DisableKeyboard();
+ KBCGetData();
+
+ //
+ // 3 times retry on keyboard reset
+ //
+ for (wCount = 0; wCount < 3; wCount++) {
+ if (!ReadDevice(KBD_RESET, &bData, KB_ACK_COM)) { // ACK received
+ TRACEKBD((-1,"KBD Reset Response %X ", bData));
+ bAck = TRUE;
+ break;
+ } else {
+ KBCGetData(); // Dummy read
+ }
+ }
+
+ if (bAck) { //If not not Keyboard
+ if (ObFullRead() == 0xAA) { // Reset successful
+ Ps2KbdDetected=TRUE;
+ } else if (Read8042(0xAB)) { // On Success returns 0
+ //
+ // 0x01 if Clock line stuck low, 0x02 if clock line stuck high,
+ // 0x03 if data line stuck low, and 0x04 if data line stuck high
+ //
+ Ps2KbdDetected=FALSE;
+ }
+ }
+
+ //
+ // Check for lock key
+ //
+ if (!(IoRead8(KBC_CMDSTS_PORT) & 0x10)) {
+ //
+ // Keyboard is locked, we can report it here
+ //
+ Ps2KbdDetected=FALSE;
+ }
+ } else {
+ Ps2KbdDetected = TRUE;
+ KBDEnableState = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UpdateSioVariableForKeyboardMouse
+//
+// Description: Update the SIO variable in the ACPI name space depend on the
+// Ps2keyboard and Mouse Present state.
+//
+// Parameters: None
+//
+// Output: None
+//
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateSioVariableForKeyboardMouse(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ static EFI_GUID SioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ SIO_DEV_STATUS SioDevStatus;
+ UINT32 SioDevStatusVarAttributes = 0;
+ EFI_STATUS Status;
+
+ //
+ // Get the SIO variable.
+ //
+ Status = pRS->GetVariable( SIO_DEV_STATUS_VAR_NAME,
+ &SioDevStatusVarGuid,
+ &SioDevStatusVarAttributes,
+ &SioDevStatusVarSize,
+ &SioDevStatus.DEV_STATUS);
+
+ //
+ // If variable not found return without updating it.
+ //
+ if(EFI_ERROR(Status)) {
+ SioDevStatus.DEV_STATUS = 0;
+ SioDevStatusVarAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ SioDevStatus.Res3 = 1; // To indicate that PS2 state vas updated
+ }
+
+ //
+ // Set the flag based on the Ps2 keyboard presence state
+ //
+ if(Ps2KbdDetected) {
+ SioDevStatus.Key60_64 = 1;
+ } else {
+ SioDevStatus.Key60_64 = 0;
+ }
+
+
+ //
+ // Set the Mouse flag based on the Mouse Presence state.
+ //
+ if(Ps2MouseDetected) {
+ SioDevStatus.Ps2Mouse = 1;
+ } else {
+ SioDevStatus.Ps2Mouse = 0;
+ }
+
+ //
+ // Set the SIO variable.
+ //
+ Status = pRS->SetVariable( SIO_DEV_STATUS_VAR_NAME,
+ &SioDevStatusVarGuid,
+ SioDevStatusVarAttributes,
+ SioDevStatusVarSize,
+ &SioDevStatus);
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPS2Keyboard
+//
+// Description: Detects the presence of Keyboard in KBC port.
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS if mouse is detected
+// EFI_NOT_FOUND if mouse is not detected
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPS2Keyboard( )
+{
+ if ( InstallKeyboardMouseAlways ) {
+ return EFI_SUCCESS;
+ } else {
+ return Ps2KbdDetected ? EFI_SUCCESS : EFI_NOT_FOUND;
+ }
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2DataDispatcher
+//
+// Description: This fuction checks whether data is available in the PS2
+// controller output buffer. If so, it gives control to the
+// corresponding state machine executor.
+//
+// Parameters: VOID *Context - Pointer to the context for this function
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PS2DataDispatcher (
+ VOID *Context )
+{
+ UINT8 data;
+ KEYBOARD *kbd = &gKbd;
+ UINT8 bIndicators;
+
+ bIndicators = kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+ if(KbdIrqSupport){
+
+ //
+ // if keyboard irq supported check status of SCRL/NUM/CPSL keys
+ // and send the command to Keyboard to update the LED status
+ //
+ UINT8 bIndicators = kbd->KeyData.KeyState.KeyToggleState & 7;
+ if (bIndicators != kbd->Indicators && kbd->LEDCommandState == 0){
+ LEDsOnOff(kbd);
+ }
+ return;
+ }
+
+ if (InsidePS2DataDispatcher) return;
+ InsidePS2DataDispatcher = TRUE;
+
+ for(data = IoRead8(KBC_CMDSTS_PORT); data & KBC_OBF; data = IoRead8(KBC_CMDSTS_PORT)) {
+ if (data & KBC_AUX_OBF) {
+ DrivePS2MouseMachine(Context);
+ }
+ else {
+ //
+ // Removed the DisableKeyboard() as to read multiple data from port60h,
+ // If any valid key is received we break out of the loop.
+ //
+ DrivePS2KbdMachine(Context);
+ if (CheckKeyinBuffer(kbd) ) {
+ break;
+ }
+ }
+ }
+
+ //
+ // Check LED state before issuing ED command
+ //
+ if (bIndicators != kbd->Indicators && kbd->LEDCommandState == 0) {
+ //
+ // Disable the keyboard before issuing ED command
+ //
+ DisableKeyboard();
+ CheckIssueLEDCmd(kbd);
+ }
+
+ //
+ //Process the led command and data
+ //
+ ProcessLEDCommandData(kbd);
+ EnableKeyboard();
+ InsidePS2DataDispatcher = FALSE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckIssueLEDCmd
+//
+// Description: This function check if KBD LED command ED needs to be
+// issued.
+// If 'yes', sends ED command. No data is read.
+//
+// Parameters: KEYBOARD *kbd - Pointer to keyboard buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CheckIssueLEDCmd (
+ KEYBOARD *Kbd )
+{
+
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+
+ if (bIndicators != Kbd->Indicators && Kbd->LEDCommandState == 0) {
+ //
+ // Don't issue LED command when data is pending
+ //
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) return;
+ Kbd->LEDCommandState = ED_COMMAND_ISSUED;
+ WriteKeyboardData(0xED);
+ }
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessKBDResponse
+//
+// Description: If 0xFA is received as data, check for any pending ACK
+// and take necessary action.
+//
+// Parameters: KEYBOARD* kbd - Pointer to keyboard buffer
+// UINT8 bData - Data received from keyboard
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ProcessKBDResponse (
+ KEYBOARD *Kbd,
+ UINT8 Data )
+{
+
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+
+ switch (Data) {
+ case 0xFA:
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ Kbd->LEDCommandState = ED_DATA_ISSUED;
+ Kbd->Indicators = bIndicators;
+ WriteKeyboardData(bIndicators);
+ break;
+ }
+
+ if (Kbd->LEDCommandState == ED_DATA_ISSUED) {
+ Kbd->LEDCommandState = 0;
+ break;
+ }
+
+
+ case 0xFE:
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED || Kbd->LEDCommandState == ED_DATA_ISSUED) {
+// Error occured. Clear out the current indicator bits.
+// Modifiers will have the correct bits that needs to be set.
+// Next Call to CheckIssueLEDCmd will detect the mismatch
+// and start the LED sequence.
+ WriteKeyboardData(0xF4);
+ Kbd->LEDCommandState = 0;
+ bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7;
+ Kbd->KeyData.KeyState.KeyToggleState &=
+ ~(SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE);
+ Kbd->Indicators &= 0xf0;
+ break;
+ }
+
+ case 0xFF:
+ Kbd->LEDCommandState = 0;
+ break;
+ default: break;
+ }
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KBCGetData
+//
+// Description: Reads and returns byte of data from KBC data port. Also
+// used as dummy KBC data process routine.
+//
+// Parameters: VOID *Context - Pointer to the context of this function
+//
+// Output: UINT8 Data read from KBC Data port.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 KBCGetData ()
+{
+ UINT8 Data;
+ Data = IoRead8(KBC_DATA_PORT);
+
+ return Data;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/kbc.h b/Core/EM/PS2CTL/kbc.h
new file mode 100644
index 0000000..44ec5ea
--- /dev/null
+++ b/Core/EM/PS2CTL/kbc.h
@@ -0,0 +1,321 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.h 25 11/07/12 12:25a Srikantakumarp $
+//
+// $Revision: 25 $
+//
+// $Date: 11/07/12 12:25a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.h $
+//
+// 25 11/07/12 12:25a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 23 10/18/12 9:00a Deepthins
+// [TAG] EIP70313
+// [Category] Improvement
+// [Description] Used CheckIssueLEDCmd in function LEDsOnOff instead of
+// OutToKb(Kbd, 0xED)
+// [Files] kbc.c, ps2kbd.c and kbc.h
+//
+// 22 5/02/12 2:28a Deepthins
+// [TAG] EIP63116
+// [Category] Improvement
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 21 4/24/12 2:18a 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
+//
+// 20 2/01/12 1:59a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 19 9/22/11 6: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
+//
+// 18 8/02/11 4:43a Rameshr
+// [TAG] - EIP 58974
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Yellow exclamation mark in Windows when PS2 KB/MS are not
+// present.
+// [RootCause]- ACPI name space variable reports that PS2 device present
+// [Solution] - Updated the SIO device status based on the device present
+// after BDS.
+// [Files] - Kbc.c, Kbc.h , Ps2main.c
+//
+// 17 1/05/11 1:00a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 16 12/10/10 5:30a Rameshr
+// [TAG] - EIP 47011
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - DTM IO Tests fail due to presence of PS/2 devices that are
+// not ready - no PS/2 devices attached during test.
+// [RootCause]- PS2 device _STA method returns that, device is present .
+// [Solution] - Updated the SIO device status based on the device
+// presence.
+// [Files] - Kbc.c , Kbc.h, Mouse.c
+//
+// 15 8/23/10 4:23a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.c
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 14 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 13 4/21/08 5:49p Olegi
+// Removed keyboard modifiers bits definition, they should be taken from
+// SimpleTextInEx.h
+//
+// 12 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 11 9/07/07 4:34p Olegi
+// EFI_KEY code implementation.
+//
+// 10 8/31/07 2:17p Olegi
+// Added SimpleTextInEx definitions.
+//
+// 9 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 8 3/13/06 2:38a Felixp
+//
+// 7 1/09/06 11:38a Felixp
+//
+// 5 12/22/05 10:22a Srinin
+// ProcessKBDData added.
+//
+// 4 10/11/05 4:11p Srinin
+// New function declarations added.
+//
+// 3 8/30/05 1:15p Srinin
+// KEYBOARD struct modified.
+//
+// 2 3/04/05 1:38p Mandal
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 3 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 2 9/17/04 7:02p Olegi
+//
+// 1 8/27/04 3:17p Olegi
+// Initial VSS checkin.
+//
+// 4 8/18/04 6:37p Olegi
+// Header and footer added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: kbc.h
+//
+// Description: Keyboard Controller functions header
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __PS2_KBC_SUPPORT_H__
+#define __PS2_KBC_SUPPORT_H__
+
+#include <Protocol\Cpu.h>
+#include <Protocol\Legacy8259.h>
+//
+// KBC command/status/data IO ports
+//
+#define KBC_CMDSTS_PORT 0x64
+#define KBC_DATA_PORT 0x60
+
+//
+// KBC status bits definition
+//
+#define KBC_OBF 0x01
+#define KBC_IBF 0x02
+#define KBC_SYSFLAG 0x04
+#define KBC_CMD_DATA 0x08
+#define KBC_INHIBIT_SW 0x10
+#define KBC_AUX_OBF 0x20
+#define KBC_TIMEOUT_ERR 0x40
+#define KBC_PARITY_ERR 0x80
+
+//
+// COMMANDS from KEYBOARD to SYSTEM
+//
+#define KB_ACK_COM 0xFA // ACKNOWLEDGE command
+#define KB_RSND_COM 0xFE // RESEND command
+#define KB_OVRN_COM 0xFF // OVERRUN command
+#define KB_DIAG_FAIL_COM 0xFD // DIAGNOSTIC FAILURE command
+
+#define KBD_ENABLE_SCANNING 0xF4
+#define KBD_DISABLE_SCANNING 0xF5
+#define KBD_RESET 0xFF
+
+#define rKeyboardID 0xF2
+#define rMouseID 0xF2
+
+//
+// Keyboard scanner states
+//
+#define KBST_READY 0
+#define KBST_E0 1
+#define KBST_E1 2
+
+#define BUFFER_SIZE 16
+#define SYSTEM_KEYBOARD_IRQ 0x01
+#define SYSTEM_MOUSE_IRQ 0x0C
+#define SLAVE_IRQ 0X02
+// LED inter command state
+#define ED_COMMAND_ISSUED 0x01
+#define ED_DATA_ISSUED 0x02
+
+typedef struct {
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL iSimpleIn;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL iSimpleInEx;
+ AMI_EFIKEYCODE_PROTOCOL iKeycodeInEx;
+ AMI_EFI_KEY_DATA KeyData;
+ BOOLEAN KeyIsReady;
+ UINT8 ScannerState;
+ AMI_EFI_KEY_DATA* pBufHead;
+ AMI_EFI_KEY_DATA* pBufTail;
+ AMI_EFI_KEY_DATA* pBufStart;
+ AMI_EFI_KEY_DATA* pBufEnd;
+ UINT8 Count;
+// UINT16 Modifiers;
+ UINT8 Indicators;
+ UINT8 LEDCommandState;
+ UINT8 CommandResponded;
+} KEYBOARD;
+
+typedef struct {
+ UINT8 KbdBuffer[BUFFER_SIZE];
+ UINT8 KbdIndex;
+} KEYBOARD_IRQ_STORE;
+
+EFI_STATUS KBCBatTest();
+UINT8 Read8042(UINT8 bCmd);
+UINT8 ObFullRead();
+void WriteKeyboardCommand(UINT8 bCmd);
+void WriteKeyboardData(UINT8 bCmd);
+void Write8042CommandByte(UINT8 bCCB);
+void IbFree();
+EFI_STATUS IbFreeTimeout(UINT32 TimeoutValue);
+void IoDelay();
+void AutodetectKbdMousePorts();
+EFI_STATUS ReadDevice(UINT8 bCmd, UINT8 *Data, UINT8 Response);
+BOOLEAN ObFullReadTimeout(UINT8* data, UINT32 msec, BOOLEAN ONLYOBF);
+UINT8 IssueCommand(UINT8 bCmd);
+UINT8 AuxDeviceCommand(UINT8 bCmd);
+EFI_STATUS OutToKb(KEYBOARD* kbd, UINT8 bCmd);
+EFI_STATUS InsertKeyToBuffer (KEYBOARD* kbd, AMI_EFI_KEY_DATA *key);
+EFI_STATUS GetKeyFromBuffer (KEYBOARD* kbd, VOID* key, UINT8 size);
+BOOLEAN CheckKeyinBuffer (KEYBOARD* kbd);
+void ReadAndProcessKey(void *Context);
+void DisableKeyboard();
+EFI_STATUS EnableKeyboard();
+void DisableAuxDevice();
+void EnableAuxDevice();
+void LEDsOnOff(KEYBOARD* kbd);
+void CheckIssueLEDCmd (KEYBOARD *kbd);
+void ProcessKBDResponse (KEYBOARD *kbd, UINT8 bData);
+EFI_STATUS DetectPS2Keyboard();
+EFI_STATUS DetectPS2KeyboardAndMouse();
+void HandleKBDData(void *Context, UINT8 data);
+void ProcessKBDData (KEYBOARD *kbd, UINT8 data);
+BOOLEAN ObFullReadMTimeout(UINT8* data, UINT32 msec);
+EFI_STATUS ReadDeviceM(UINT8 bCmd, UINT8 *Data, UINT8 Response);
+EFI_STATUS InitHotKeys(EFI_HANDLE Controller);
+EFI_STATUS ProcessHotKey(UINT8 code, UINT16 modifiers);
+EFI_STATUS DetectPs2Mouse();
+EFI_STATUS GetMouseData();
+VOID UpdateSioVariableForKeyboardMouse(
+ EFI_EVENT Event,
+ VOID *Context
+);
+EFI_STATUS
+CheckPartialKey (
+ KEYBOARD *Kbd,
+ EFI_KEY_DATA *Key
+);
+VOID InitKeyboardIrq(VOID);
+void ProcessLEDCommandData(KEYBOARD* kbd);
+EFI_STATUS ProcessMultiLanguage(
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+ );
+#endif // __PS2_KBC_SUPPORT_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/mouse.c b/Core/EM/PS2CTL/mouse.c
new file mode 100644
index 0000000..7fdbbfc
--- /dev/null
+++ b/Core/EM/PS2CTL/mouse.c
@@ -0,0 +1,1215 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/mouse.c 24 11/07/12 12:26a Srikantakumarp $
+//
+// $Revision: 24 $
+//
+// $Date: 11/07/12 12:26a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/mouse.c $
+//
+// 24 11/07/12 12:26a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 23 10/18/12 9:49a Deepthins
+// [TAG] EIP95111
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] PS2 mouse is not working in setup.
+// [RootCause] In stream mode data reporting is disabled by default. The
+// mouse will not actually issue any movement data packets until it
+// receives the "Enable Data Reporting" (0xF4) command. So even when the
+// DETECT_PS2_KEYBOARD and DETECT_PS2_MOUSE token is disabled we need to
+// send command 0xf4 to Enable Data Reporting.
+// [Solution] In MouseReset function, Set sampleRate ,Resolution and
+// Enable streaming.
+// [Files] mouse.c and ps2kbd.c
+//
+// 22 5/02/12 2:28a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 21 2/01/12 2:00a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 20 9/19/11 9:38a Lavanyap
+// [TAG] EIP66198
+// [Category] Improvement
+// [Description] Added Mouse Wheel support in PS2 and USB drivers.
+// [Files] usbdef.h, usbms.c, efiusbms.c, ps2mouse.h, mouse.c
+//
+// 19 7/29/11 1:07a Lavanyap
+// [TAG] EIP63310
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] MouseGetState() does not differentiate between driver busy
+// and no state change between GetState calls.
+// [RootCause] MouseGetState() return status codes does not follow UEFI
+// specification.
+// [Solution] MouseGetState() return status codes has been updated as
+// per UEFI specification.
+// [Files] mouse.c
+//
+// 18 4/27/11 4:37a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 17 12/10/10 5:31a Rameshr
+// [TAG] - EIP 47011
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - DTM IO Tests fail due to presence of PS/2 devices that are
+// not ready - no PS/2 devices attached during test.
+// [RootCause]- PS2 device _STA method returns that, device is present .
+// [Solution] - Updated the SIO device status based on the device
+// presence.
+// [Files] - Kbc.c , Kbc.h, Mouse.c
+//
+// 16 8/23/10 4:25a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.h
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 15 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 14 10/08/08 4:55p Olegi
+// Change in GetMouseData that will reset the mouse in case the recieved
+// packet is wrong. The failure was observed in TSE.
+//
+// 13 4/22/08 4:31p Felixp
+// Additional progress codes added
+//
+// 12 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 11 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 10 3/01/07 3:43p Pats
+// Modified for faster boot if keyboard detection disabled.
+//
+// 9 5/05/06 5:23p Ambikas
+//
+// 8 1/09/06 11:38a Felixp
+//
+// 6 12/22/05 10:25a Srinin
+// Cleaned up the code. KBD disable inside GetMousedata removed.
+//
+// 5 10/11/05 4:15p Srinin
+// Mouse is initialized for Streaming mode but kept disabled. Re-entry
+// problem fixed.
+//
+// 4 7/18/05 3:37p Felixp
+//
+// 3 3/04/05 1:36p Mandal
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Mouse.c
+//
+// Description: This is the PS/2 mouse EFI driver source file.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: mouse.c
+//
+// Description: PS/2 mouse I/O support fuctions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include <Efi.h>
+#include <AmiLib.h>
+#include "ps2ctl.h"
+#include "kbc.h"
+#include "ps2mouse.h"
+
+STATEMACHINEPROC DrivePS2MouseMachine;
+BOOLEAN Ps2MouseDetected = FALSE;
+UINT8 MouseData[5] = {0,};
+BOOLEAN InsideGetMouseData = FALSE;
+BOOLEAN MouseResetRequired = FALSE;
+UINT8 ByteCount = NON_WHEEL_REPORT_FORMAT;
+extern BOOLEAN InsideKbdReadKey;
+extern BOOLEAN InsideOnWaitingOnKey;
+extern KEYBOARD gKbd;
+typedef struct _STATE;
+MOUSE gMouse = {0,};
+EFI_CPU_ARCH_PROTOCOL *gCpuArch;
+EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+UINT8 gMouseIrqInstall = FALSE;
+extern UINT8 gKeyboardIrqInstall;
+extern BOOLEAN KBDEnableState;
+UINT8 gCurrentMouseIndex = NULL;
+UINT8 gGetMouseStateStart=FALSE;
+VOID GetMouseDataFromIrq(VOID);
+UINT8 gMouseCommandActive=FALSE;
+BOOLEAN InsideMouseReset;
+extern BOOLEAN MsIrqSupport;
+extern BOOLEAN MouseEnableState;
+extern BOOLEAN DetectPs2MouseValue;
+extern BOOLEAN InstallKeyboardMouseAlways;
+extern BOOLEAN KbdIrqSupport;
+extern BOOLEAN InsideKbdReset;
+extern UINT32 IbFreeMaxTimeoutValue;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullRead
+//
+// Description: Waits for Output Buffer Full and then reads the data port
+//
+// Parameters: None
+//
+// Output: UINT8 KBC Data port data
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 ObFullReadM()
+{
+ for (;;) {
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+ return IoRead8(KBC_DATA_PORT);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullReadMTimeout
+//
+// Description: This routine checks for the data availbility in output
+// buffer for a short period of time, if data is available
+// within this time, it reads and returns the data from
+// output buffer.
+//
+// Paremeters: UINT8* data - Pointer to the byte to be updated
+// UINT32 msec - Milliseconds timeout
+//
+// Output: BOOLEAN - Returns FALSE if data is successfully updated
+// (no timeout), data is updated
+// Returns TRUE if time-out
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN ObFullReadMTimeout (
+ UINT8* data,
+ UINT32 msec )
+{
+
+ UINT8 bData;
+ UINT32 loopcount = msec << 1;
+
+ for (; loopcount; loopcount--) {
+
+ bData = IoRead8(KBC_CMDSTS_PORT);
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+
+ *data = IoRead8(KBC_DATA_PORT);
+ if (bData & 0x40) {
+ *data = IoRead8(KBC_DATA_PORT);
+ TRACEKBD((-1, "Status Reg M : %x, %x\n", bData, *data));
+ return TRUE;
+ }
+ else return FALSE; // No timeout
+
+ }
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF)){
+ TRACEKBD((-1, "KB OBF inside Mouse"));
+ return TRUE;
+ }
+
+ gSysTable->BootServices->Stall(500); // 0.5 msec
+
+ }
+
+ return TRUE; // Timeout
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadDeviceM
+//
+// Description: Sends the given command to KBD, reads and returns the
+// acknowledgement byte returned from KBD.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+// UINT8 *Data - Pointer to data buffer
+// UINT8 Response - Response expected
+//
+// Output: EFI_SUCCESS - Data == Response
+// EFI_DEVICE_ERROR - Data != Response
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadDeviceM (
+ UINT8 bCmd,
+ UINT8 *Data,
+ UINT8 Response )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xD4);
+ IbFree();
+ WriteKeyboardData(bCmd);
+
+ if (ObFullReadMTimeout(Data, 1000)) {
+ return EFI_DEVICE_ERROR;
+ }
+ if (*Data == Response) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MouseInterruptHandler
+//
+// Description: An interrupt handler for PS2 mouse
+//
+//
+// Input: InterruptType Interrupt type
+// SystemContext System context
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MouseInterruptHandler(
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+)
+{
+ EFI_TPL OldTpl=NULL;
+ KEYBOARD *Kbd = &gKbd;
+
+ //
+ // Disable interrupt to prevent interrupt chaining
+ //
+ gCpuArch->DisableInterrupt(gCpuArch);
+
+ //
+ // Post Code verifies the Mouse IRQ generation by sending command 0xD4(Write mouse device)
+ // and data. For the data if the control comes to Mouse IRQ handler, and IRQ method is enabled
+ // and active. Otherwise it will disable the Mouse IRQ
+
+ if (gMouseCommandActive){
+ gMouseIrqInstall = TRUE;
+ //
+ // Throw out the Dummy data that we sent to test the Mouse IRQ generation
+ //
+ IoRead8(KBC_DATA_PORT);
+
+ } else {
+
+ //
+ // Handle the Mouse Data
+ //
+ GetMouseDataFromIrq();
+ }
+
+ EnableAuxDevice();
+
+ //
+ // Send End Of Interrupt command twice as PIC is connected
+ // in cascade mode, once for master and once for corresponding
+ // slave
+ //
+ mLegacy8259->EndOfInterrupt(mLegacy8259, SYSTEM_MOUSE_IRQ);
+ mLegacy8259->EndOfInterrupt(mLegacy8259, SLAVE_IRQ);
+ gCpuArch->EnableInterrupt(gCpuArch);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InitMOUSE
+//
+// Description: Initializes mouse driver
+//
+// Parameters: MOUSE** ppMouse - Pointer to mouse structure
+//
+// Output: EFI_SUCCESS - Mouse initialized
+// EFI_DEVICE_ERROR - Mouse not detected
+// EFI_OUT_OF_RESOURCES - Not enough memory for buffers
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS InitMOUSE (
+ MOUSE** ppMouse )
+{
+ MOUSE* pmouse;
+ EFI_STATUS Status;
+ UINT32 MouseVector = NULL;
+ UINT32 loopcount = 1000;
+
+ pmouse = *ppMouse = &gMouse;
+
+ MemSet( &pmouse->state, sizeof(pmouse->state), 0 );
+ pmouse->saved_flags=0;
+
+ if (EFI_ERROR(DetectPS2mouse(pmouse))) {
+ //
+ // Ps2 Mouse not Present.
+ //
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Ps2 Mouse Present. Install Simple Pointer protocol.
+ //
+ (pmouse->iSmplPtr).Mode = MallocZ(sizeof (EFI_SIMPLE_POINTER_MODE));
+
+ if(!((pmouse->iSmplPtr).Mode)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Check for mouse IRQ support.
+ //
+ if(MsIrqSupport){
+ if (!gMouseIrqInstall){
+ if(mLegacy8259 == NULL){
+ Status = pBS->LocateProtocol(&gEfiLegacy8259ProtocolGuid, NULL, &mLegacy8259);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Find the CPU Arch Protocol
+ //
+ if(gCpuArch == NULL){
+ Status = pBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, &gCpuArch);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ //
+ // Get Mouse vector
+ //
+ Status = mLegacy8259->GetVector(mLegacy8259, SYSTEM_MOUSE_IRQ, (UINT8 *) & MouseVector);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // Register interrupt handler for mouse
+ //
+ Status = gCpuArch->RegisterInterruptHandler(gCpuArch, MouseVector, MouseInterruptHandler);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // To set the interrupt mode operation in legacy mode
+ //
+
+ mLegacy8259->SetMode(mLegacy8259,Efi8259LegacyMode,NULL,NULL);
+ //
+ // Enable Mouse interrupt
+ //
+ Status = mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = mLegacy8259->EnableIrq(mLegacy8259, 0x02, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // To set the interrupt mode operation in protected mode
+ //
+ mLegacy8259->SetMode(mLegacy8259,Efi8259ProtectedMode,NULL,NULL);
+
+ //
+ // Enable PS2 mouse interrupt
+ //
+ Status = mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Enable Master PIC interrupt IRQ2
+ //
+ Status = mLegacy8259->EnableIrq(mLegacy8259, 0x02, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // Enable INT2 bit in command register.
+ //
+ Write8042CommandByte(0x67);
+
+ // Is Mouse IRQ active?
+ gMouseCommandActive = TRUE;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xD4);
+ IbFree();
+ //
+ // Write mouse data
+ //
+ WriteKeyboardData(0xf4);
+
+ for (; loopcount; loopcount--) {
+ if (gMouseIrqInstall) break;
+ gSysTable->BootServices->Stall(500); // 0.5 msec
+ }
+ gMouseCommandActive = FALSE;
+
+ //
+ // If Mouse irq is not installed then disable interrupt
+ //
+ if (!gMouseIrqInstall){
+ //
+ // a dummy read after writing to mouse
+ //
+ IoRead8(0x60);
+ Write8042CommandByte(0x65);
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ);
+
+ }
+ }
+ }
+
+ (pmouse->iSmplPtr).Mode->ResolutionX = 4;
+ (pmouse->iSmplPtr).Mode->ResolutionY = 4;
+ (pmouse->iSmplPtr).Mode->ResolutionZ = 4;
+ (pmouse->iSmplPtr).Mode->RightButton = TRUE;
+ (pmouse->iSmplPtr).Mode->LeftButton = TRUE;
+
+ //
+ // Initialize pointer interface functions
+ //
+ (pmouse->iSmplPtr).Reset = (EFI_SIMPLE_POINTER_RESET)MouseReset;
+ (pmouse->iSmplPtr).GetState= (EFI_SIMPLE_POINTER_GET_STATE)MouseGetState;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPs2Mouse
+//
+// Description:
+// Implements Reset operation of SimplePointer protocol.
+// As part of initialization process, the firmware/device will make a quick
+// but reasonable attempt to verify that the device is functioning. If the
+// ExtendedVerification flag is TRUE the firmware may take an extended amount
+// of time to verify the device is operating on reset. Otherwise the reset
+// operation is to occur as quickly as possible.
+//
+// Parameters: None
+//
+// Output:
+// Returns EFI_SUCCESS if the device was reset, othewise returns
+// EFI_DEVICE_ERROR - device is not functioning correctly and could
+// not be reset.
+//
+// Modified: MouseEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPs2Mouse()
+{
+
+ UINT8 bData = 0, b1, b2, loop;
+ EFI_STATUS Status;
+
+ if ( DetectPs2MouseValue ) {
+
+
+ PROGRESS_CODE(DXE_MOUSE_RESET);
+
+ for (loop = 3; loop; loop--) {
+
+ if ((IoRead8(KBC_CMDSTS_PORT) & KBC_OBF)) {
+ TRACEKBD((-1,"KBD"));
+ //
+ // Consume Data and discard it
+ //
+ KBCGetData();
+ }
+
+ TRACEKBD((-1,"Reseting mouse...\n"));
+
+ Status = ReadDeviceM(0xFF, &bData, 0xFA);
+ TRACEKBD((-1,"%x, %x ", bData, Status));
+ //
+ // ACK received
+ //
+ if (Status == EFI_SUCCESS) {
+
+ if (ObFullReadMTimeout(&b1, 1000)) {
+ continue;
+ }
+ if (ObFullReadMTimeout(&b2, 1000)) {
+ continue;
+ }
+
+ TRACEKBD((-1,"Data %x; %x\n",b1,b2));
+
+ if ( b1 == 0xAA && b2 == 0x00) {
+ TRACEKBD((-1,"Reset Mouse Ok\n"));
+
+ //
+ // Enable wheel report format
+ //
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0xC8, &bData, 0xFA))) {
+ continue; // 200 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 100 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x50, &bData, 0xFA))) {
+ continue; // 80 samples/sec
+ }
+
+ ReadDeviceM(0xF2, &bData, 0xFA); // Read Mouse ID
+ ObFullReadMTimeout(&bData, 1000);
+
+ // If scroll wheel is supported Mouse Response = 3
+ // else Mouse Response = 0
+ if (bData == 3) {
+ ByteCount = WHEEL_REPORT_FORMAT;
+ }
+
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 20 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xE8, &bData, 0xFA))) {
+ continue; // Set resolution
+ }
+ if (EFI_ERROR(ReadDeviceM(0x2, &bData, 0xFA))) {
+ continue; // 4 Count/mm
+ }
+
+ //
+ // Enable streaming
+ //
+ ReadDeviceM(0xF4, &bData, 0xFA);
+
+ MouseEnableState = TRUE;
+ DisableAuxDevice();
+ Ps2MouseDetected = TRUE;
+
+ return EFI_SUCCESS;
+
+ }
+ }
+ }
+
+ //
+ // Ps2 Mouse Not Present. Return with Error.
+ //
+ return EFI_DEVICE_ERROR;
+ } else {
+ //
+ // By default Ps2 mouse is enabled and Present
+ //
+ MouseEnableState = TRUE;
+ Ps2MouseDetected = TRUE;
+ return EFI_SUCCESS;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: MouseReset
+//
+// Description:
+// Implements Reset operation of SimplePointer protocol.
+// As part of initialization process, the firmware/device will make a quick
+// but reasonable attempt to verify that the device is functioning. If the
+// ExtendedVerification flag is TRUE the firmware may take an extended amount
+// of time to verify the device is operating on reset. Otherwise the reset
+// operation is to occur as quickly as possible.
+//
+// Parameters:
+// MOUSE *self - pointer to the mouse structure
+// BOOLEAN extended - Indicates that the driver may perform a more exhaustive
+// verification operation of the device during reset.
+//
+// Output:
+// Returns EFI_SUCCESS if the device was reset, othewise returns
+// EFI_DEVICE_ERROR - device is not functioning correctly and could
+// not be reset.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS MouseReset(
+ MOUSE *self,
+ BOOLEAN extended)
+{
+ UINT8 bData = 0;
+ UINT8 b1;
+ UINT8 b2;
+ UINT8 loop;
+ EFI_STATUS Status;
+
+
+ //
+ // If ExtendedVerification Flag is true then reset the mouse, set
+ // sampleRate and Resolution and Enable streaming.
+ //
+ if(extended) {
+
+ InsideMouseReset = TRUE;
+ Write8042CommandByte(0x74);
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport ) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ);
+ }
+
+ //
+ // Check for mouse IRQ support
+ //
+ if(MsIrqSupport) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->DisableIrq(mLegacy8259, SLAVE_IRQ);
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ);
+ }
+
+ for (loop = 3; loop; loop--) {
+
+ if ((IoRead8(KBC_CMDSTS_PORT) & KBC_OBF)) {
+ TRACEKBD((-1,"KBD"));
+ //
+ // Consume Data and discard it
+ //
+ KBCGetData();
+ }
+
+ TRACEKBD((-1,"Reseting mouse...\n"));
+
+ Status = ReadDeviceM(0xFF, &bData, 0xFA);
+ TRACEKBD((-1,"%x, %x ", bData, Status));
+ //
+ // ACK received
+ //
+ if (Status == EFI_SUCCESS) {
+
+ ByteCount = NON_WHEEL_REPORT_FORMAT;
+
+ if (ObFullReadMTimeout(&b1, 1000)) {
+ continue;
+ }
+ if (ObFullReadMTimeout(&b2, 1000)) {
+ continue;
+ }
+
+ TRACEKBD((-1,"Data %x; %x\n",b1,b2));
+
+ if ( b1 == 0xAA && b2 == 0x00) {
+ TRACEKBD((-1,"Reset Mouse Ok\n"));
+
+ //
+ // Enable wheel report format
+ //
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0xC8, &bData, 0xFA))) {
+ continue; // 200 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 100 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x50, &bData, 0xFA))) {
+ continue; // 80 samples/sec
+ }
+
+ ReadDeviceM(0xF2, &bData, 0xFA); // Read Mouse ID
+ ObFullReadMTimeout(&bData, 1000);
+
+ // If scroll wheel is supported Mouse Response = 3
+ // else Mouse Response = 0
+ if (bData == 3) {
+ ByteCount = WHEEL_REPORT_FORMAT;
+ }
+
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 20 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xE8, &bData, 0xFA))) {
+ continue; // Set resolution
+ }
+ if (EFI_ERROR(ReadDeviceM(0x2, &bData, 0xFA))) {
+ continue; // 4 Count/mm
+ }
+
+
+ //
+ // Enable streaming
+ //
+ ReadDeviceM(0xF4, &bData, 0xFA);
+ break;
+ }
+ }
+ }
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport ) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+ if(MsIrqSupport) {
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ, FALSE);
+ mLegacy8259->EnableIrq(mLegacy8259, SLAVE_IRQ, FALSE);
+ }
+
+ Write8042CommandByte(0x47);
+ InsideMouseReset = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: MouseGetState
+//
+// Description: Retrieves the current state of a pointer device.
+//
+// Parameters:
+// MOUSE *self - Pointer to the mouse structure
+// EFI_SIMPLE_POINTER_STATE *state - Pointer to state machine buffer
+//
+// Output: EFI_SUCCESS - Mouse data ready
+// EFI_NOT_READY - Mouse data not ready
+//
+// Modified: MouseData
+//
+// Referrals: MouseData
+//
+// Notes:
+// The function retrieves the current state of a pointer device. This includes
+// information on the buttons associated with the pointer device and the
+// distance that each of the axes associated with the pointer device has been
+// moved. If the state of the pointer device has not changed since the last
+// call to MouseGetState(), then EFI_NOT_READY is returned. If the state of
+// the pointer device has changed since the last call to MouseGetState(), then
+// the state information is placed in State, and EFI_SUCCESS is returned. If a
+// device error occurs while attempting to retrieve the state information,
+// then EFI_DEVICE_ERROR is returned.
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS MouseGetState(
+ MOUSE *self,
+ EFI_SIMPLE_POINTER_STATE *state)
+{
+
+ StdMouseDataPacket* packet = (StdMouseDataPacket*)MouseData;
+ EFI_STATUS Status;
+
+ // Check if Mouse Data ready
+ if (!MouseData[ByteCount]) {
+ Status = GetMouseData();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ if (MouseData[ByteCount]) {
+
+ MouseData[ByteCount] = 0;
+
+ if( packet->flags & (MOUSE_X_OVF|MOUSE_Y_OVF) ){
+ return EFI_DEVICE_ERROR;
+ } else {
+ state->RelativeMovementX = (packet->flags & MOUSE_X_NEG)? (signed char)packet->x:packet->x;
+ state->RelativeMovementY = -(int)((packet->flags & MOUSE_Y_NEG)? (signed char)packet->y:packet->y);
+ state->LeftButton = (packet->flags & BUTTON_LEFT)?TRUE:FALSE;
+ state->RightButton = (packet->flags & BUTTON_RIGHT)?TRUE:FALSE;
+
+ if (ByteCount == WHEEL_REPORT_FORMAT) {
+ state->RelativeMovementZ = ((signed char)packet->z);
+ } else {
+ state->RelativeMovementZ = 0;
+ }
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_READY;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPS2mouse
+//
+// Description: Detects the presence of mouse in KBC port.
+//
+// Parameters: MOUSE* self - Pointer to the mouse structure
+//
+// Output: EFI_SUCCESS if mouse is detected
+// EFI_NOT_FOUND if mouse is not detected
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPS2mouse (
+ MOUSE* self )
+{
+ if ( InstallKeyboardMouseAlways ) {
+ return EFI_SUCCESS;
+ } else {
+ return Ps2MouseDetected ? EFI_SUCCESS : EFI_NOT_FOUND;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OnWaitingOnMouse
+//
+// Description: Callback for the WaitForInput event;
+// checks whether the mouse state has changed and if so -
+// signals the event.
+//
+// Parameters: EFI_EVENT event - Event to signal
+// MOUSE *self - Pointer to the mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID OnWaitingOnMouse (
+ EFI_EVENT event,
+ MOUSE *self )
+{
+ // Check if Mouse Data ready
+ if (!MouseData[ByteCount]) {
+ GetMouseData();
+ }
+
+ if (MouseData[ByteCount]) gSysTable->BootServices->SignalEvent(event);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetMouseDataFromIrq
+//
+// Description: Enables Mouse and returns data if available
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS - Mouse data returned
+// EFI_NO_RESPONSE - No response from mouse
+//
+// Modified: MouseData, InsideGetMouseData
+//
+// Referrals: MouseData, InsideGetMouseData, MouseResetRequired,
+// InsideKbdReadKey, InsideOnWaitingOnKey, gKbd
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetMouseDataFromIrq(VOID)
+{
+ UINT8 Port64flag = IoRead8(KBC_CMDSTS_PORT);
+
+
+
+ if ((Port64flag & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+ MouseData[gCurrentMouseIndex] = KBCGetData();
+ if (gCurrentMouseIndex ==(ByteCount-1)){
+ DisableAuxDevice();
+ gCurrentMouseIndex = 0;
+ MouseData[ByteCount] = 1;
+ return;
+ }
+ gCurrentMouseIndex++;
+ }
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetMouseData
+//
+// Description: Enables Mouse and returns data if available
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS - Mouse data returned
+// EFI_NO_RESPONSE - No response from mouse
+//
+// Modified: MouseData, InsideGetMouseData
+//
+// Referrals: MouseData, InsideGetMouseData, MouseResetRequired,
+// InsideKbdReadKey, InsideOnWaitingOnKey, gKbd
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetMouseData()
+{
+
+ UINT8 Index;
+ BOOLEAN MouseDataRead;
+ KEYBOARD *kbd = &gKbd;
+ UINT8 KbdData[20], KbdDataIndex=0, Data8;
+ UINTN Delay, DelayPeriod = 100;
+ BOOLEAN MouseDataValid = FALSE;
+
+ //
+ // If mouse irq is supported and installed then return with success
+ //
+ if(MsIrqSupport){
+ if (gMouseIrqInstall){
+ return EFI_SUCCESS;
+ }
+ }
+
+ // Return if we are in the middle of KBD get key
+ if (InsideGetMouseData || InsideKbdReadKey || InsideOnWaitingOnKey || InsideKbdReset || InsideMouseReset) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (MouseData[ByteCount] == 1) return EFI_SUCCESS;
+
+ // Try to complete the LED sequence
+ for (Index = 0; (Index < 40) && kbd->LEDCommandState; Index++ ) {
+ //
+ // if keyboard irq is supported but not installed yet then call
+ // Ps2DataDispatcher to check whether data is available on port or not
+ //
+ if(KbdIrqSupport)
+ if (!gKeyboardIrqInstall)
+ PS2DataDispatcher(NULL);
+ pBS->Stall(500);
+ }
+
+ // LED sequence is still on, restart it
+ if (kbd->LEDCommandState) {
+ if(KbdIrqSupport)
+ if (!gKeyboardIrqInstall){
+ TRACEKBD((-1,"BLS%x ", kbd->LEDCommandState));
+ ProcessKBDResponse(kbd, 0xfe);
+ }
+ }
+
+ InsideGetMouseData = TRUE;
+
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+
+ EnableAuxDevice();
+ if (MouseResetRequired) {
+ DisableKeyboard();
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+ ReadDeviceM(0xF4, &Index, 0xFA);
+ MouseResetRequired = FALSE;
+ }
+
+ MouseData[ByteCount] = 0;
+
+ DelayPeriod = 200; // Delay for the first byte
+ for (Index = 0; Index < ByteCount; Index++) {
+
+ MouseDataRead = FALSE;
+
+ for (Delay = 0; Delay < DelayPeriod; Delay++) {
+
+ Data8 = IoRead8(KBC_CMDSTS_PORT);
+
+ if ((Data8 & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+
+ if ((Data8 & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+ MouseData[Index] = KBCGetData();
+ MouseDataValid = TRUE;
+ MouseDataRead = TRUE;
+ if (Index == (ByteCount-1)) DisableAuxDevice();
+ break;
+ }
+
+ pBS->Stall(100);
+
+ }
+
+ DelayPeriod = 100; // Delay for the Second & Third byte
+
+ if (Index == (ByteCount-1) && MouseDataRead) {
+ MouseData[ByteCount] = 1;
+ } else if (Index == (ByteCount-1) && MouseDataValid) {
+ MouseResetRequired=TRUE;
+ }
+
+ if (MouseDataRead) continue;
+ else break;
+
+ }
+
+ // Reset mouse counters if the mouse sequence is not correct
+ if (MouseData[ByteCount] == 1 && !(MouseData[0] & 8)) {
+
+ for (; Index; Index--) {
+ TRACEKBD((-1,"%X ", MouseData[Index]));
+ }
+ TRACEKBD((-1,"\n"));
+
+ DisableKeyboard();
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+ ReadDeviceM(0xF4, &Index, 0xFA);
+ }
+
+ EnableKeyboard();
+ DisableAuxDevice();
+
+ for (Index =0 ; KbdDataIndex; KbdDataIndex--, Index++) {
+ ProcessKBDData(kbd, KbdData[Index]);
+ }
+
+ InsideGetMouseData = FALSE;
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2ctl.h b/Core/EM/PS2CTL/ps2ctl.h
new file mode 100644
index 0000000..a117f56
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2ctl.h
@@ -0,0 +1,178 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2ctl.h 15 4/27/11 4:35a Lavanyap $
+//
+// $Revision: 15 $
+//
+// $Date: 4/27/11 4:35a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2ctl.h $
+//
+// 15 4/27/11 4:35a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 14 1/24/11 3:41p Pats
+// [TAG] - EIP 18488
+// [Category] - Enhancement
+// [Severity] - Normal
+// [Symptom] - PS2CTL: Need hooks for port swap, Keybaord mouse detect.
+// [RootCause] - Support may be needed for kbc controller or SIO with
+// different support from AMI KB-5.
+// [Solution] - Added definition of AutodetectKbdMousePortsPtr.
+// [Files] - ps2ctl.h
+// NOTE: Implementation of this change requires changes to CORE_DXE.sdl
+// and BdsBoard.c.
+//
+// 13 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 12 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 11 9/07/07 4:34p Olegi
+// EFI_KEY code implementation.
+//
+// 10 8/31/07 2:17p Olegi
+// Added SimpleTextInEx definitions.
+//
+// 9 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 8 4/10/07 10:04a Felixp
+// LookupHID routine renamed to LookupPs2Hid to avoid linking issue when
+// linking with FloppyCtrl module
+//
+// 7 3/13/06 2:38a Felixp
+//
+// 6 1/09/06 11:38a Felixp
+//
+// 4 12/22/05 10:22a Srinin
+//
+// 3 10/11/05 4:11p Srinin
+//
+// 2 3/04/05 1:38p Mandal
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 7 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 6 9/21/04 5:51p Olegi
+//
+// 5 8/27/04 3:17p Olegi
+// Header and footer added.
+//
+// 4 8/18/04 6:37p Olegi
+// Header and footer added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2ctl.h
+//
+// Description: PS/2 Controller DXE driver header
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#ifndef __PS2_MAIN_H__
+#define __PS2_MAIN_H__
+
+#include <Efi.h>
+#include <AmiDxeLib.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimpleTextInEx.h>
+#include <Protocol\AmiKeycode.h>
+#include <Protocol\SimplePointer.h>
+#include <token.h>
+#define TRACEKBD
+
+
+#define PS2_DRIVER_VER 0x10
+#define DEVICETYPE_MOUSE 1
+#define DEVICETYPE_KEYBOARD 2
+extern EFI_SYSTEM_TABLE *gSysTable;
+
+
+EFI_STATUS StartMouse(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+EFI_STATUS StartKeyboard(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+EFI_STATUS StopMouse(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+EFI_STATUS StopKeyboard(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+
+typedef EFI_STATUS (*STARTSTOPPROC)(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+
+typedef struct PS2DEV_TABLE_tag {
+ UINT32 hid;
+ UINT32 uid;
+ UINT8 DeviceType;
+ STARTSTOPPROC start;
+ STARTSTOPPROC stop;
+ CHAR16* name;
+} PS2DEV_TABLE;
+
+typedef void (*STATEMACHINEPROC)(void*);
+void PS2DataDispatcher(void*);
+UINT8 KBCGetData();
+
+BOOLEAN LookupPs2Hid(PS2DEV_TABLE*, UINT32, UINT32, PS2DEV_TABLE**);
+EFI_STATUS GetPS2_DP(EFI_DRIVER_BINDING_PROTOCOL*, EFI_HANDLE, ACPI_HID_DEVICE_PATH**, UINT32);
+
+typedef VOID (*AUTODETECT_KBD_MOUSE_PORTS)();
+typedef EFI_STATUS (*DETECT_KBC_DEVICE)();
+extern AUTODETECT_KBD_MOUSE_PORTS AutodetectKbdMousePortsPtr;
+extern DETECT_KBC_DEVICE DetectKeyboardPtr;
+extern DETECT_KBC_DEVICE DetectMousePtr;
+
+#endif // __PS2_MAIN_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2kbd.c b/Core/EM/PS2CTL/ps2kbd.c
new file mode 100644
index 0000000..c74ba48
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2kbd.c
@@ -0,0 +1,2888 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2kbd.c 63 11/01/12 6:42a Deepthins $
+//
+// $Revision: 63 $
+//
+// $Date: 11/01/12 6:42a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2kbd.c $
+//
+// 63 11/01/12 6:42a Deepthins
+// [TAG] EIP101100
+// [Category] Improvement
+// [Description] Multi Language is supported in Ps2ctl driver
+// [Files] CORE_DXE.sdl, kbc.h, ps2kbd.c and Tokens.c
+//
+// 62 10/18/12 9:51a Deepthins
+// [TAG] EIP95111
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] PS2 mouse is not working in setup.
+// [RootCause] In stream mode data reporting is disabled by default. The
+// mouse will not actually issue any movement data packets until it
+// receives the "Enable Data Reporting" (0xF4) command. So even when the
+// DETECT_PS2_KEYBOARD and DETECT_PS2_MOUSE token is disabled we need to
+// send command 0xf4 to Enable Data Reporting.
+//
+// [Solution] In MouseReset function, Set sampleRate ,Resolution and
+// Enable streaming.
+// [Files] mouse.c and ps2kbd.c
+//
+// 61 10/18/12 9:03a Deepthins
+// [TAG] EIP70313
+// [Category] Improvement
+// [Description] Used CheckIssueLEDCmd in function LEDsOnOff instead of
+// OutToKb(Kbd, 0xED)
+// [Files] kbc.c, ps2kbd.c and kbc.h
+//
+// 60 7/13/12 7:21a Rajeshms
+// [TAG] EIP57005
+// [Category] Improvement
+// [Description] Need to clear Struck Keys in StartKeyboard() &
+// KbdReset() for some kinds of Notebook KBC. Implemented this feature
+// based on CLEAR_PENDING_KEYS_IN_PS2 token.
+// [Files] Ps2Kbd.c, CORE_DXE.sdl
+//
+// 59 7/09/12 3:13a Rajeshms
+// [TAG] EIP94186
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] side effect after adding the solution of can not catch F8
+// key event on Keyboard - PS2 KB generic implement (EIP6986)
+// [RootCause] BDA is Checked even when CSM is not launched. So even
+// though keys are not pressed Junk Keys are reproted
+// [Solution] Checked whether CSm is launched based of Presence of
+// Legacy BIOS Protocol.
+// [Files] Ps2Kbd.c
+//
+// 58 5/31/12 7:56a Srilathasc
+// [TAG] EIP89947
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ps2Keyboard doesn't work after reconnect -r command from
+// Shell
+// [RootCause] The keyboard driver's stop function does not uninstall
+// AMIEFIKEYCODE Protocol.
+// [Solution] AMIEFIKEYCODE Protocol uninstalled in stop function.
+// [Files] ps2kbd.c
+//
+// 57 5/24/12 6:49a Nimishsv
+// [TAG] EIP90180
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ps2driver doesn't return the proper ShiftState if the valid
+// Unicode char's are pressed.
+// [RootCause] Shift State was not cleared for printable characters
+// [Solution] Shift state is cleared for printable characters
+// [Files] ps2kbd.c
+//
+// 56 5/02/12 2:29a Deepthins
+// [TAG] EIP63116
+// [Category] Improvement
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 55 4/30/12 2:22a Rajeshms
+// [TAG] EIP86986
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Can not detect F8 key on PS2 Keyboard while booting to EFI
+// aware OS.
+// [RootCause] Make code of F8 key (0x42) is taken by int09h and EFI
+// aware OS calls only one ReadKeyStroke() for any key catch, Now PS2
+// driver will take Break Code of F8 key(0xC2) and returns EFI_NOT_READY.
+// [Solution] Multiple Read from PS2 keyboard is implemented and read
+// exits if any valid key is detected. Also, the BDA keyboard buffer is
+// checked for any missed key in EFI.
+// [Files] ps2kbd.c, kbc.c, CORE_DXE.sdl
+//
+// 54 4/24/12 2:19a 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
+//
+// 53 4/23/12 8:52a Jittenkumarp
+// [TAG] EIP84902
+// [Category] Bug Fix
+// [Symptom] Enter key is not working in PS2 key board
+// [RootCause] Filling wrong EFI KEY value in
+// ScancodeToEfi_table.Therefor Enter key is interpreted wrongly as
+// EfiKeyC12.
+// [Solution] Replaced EfiKeyC12 value with EfiKeyEnter value to
+// Interpreted Enter key properly.
+//
+// [Files] ps2kbd.c
+//
+// 52 4/10/12 2:35a Rameshr
+// [TAG] EIP87058
+// [Category] Bug Fix
+// [Severity] Minor
+// [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] Ps2kbd.c
+//
+// 51 2/01/12 2:01a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 50 9/22/11 7:39a 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
+//
+// 49 6/21/11 12:24p Davidd
+// [TAG] EIP55334
+// [Category] New Feature
+// [Description] Add optional code to clear keyboard buffer at
+// ReadyToBoot in PS2KB driver
+// [Files] core_dxe.sdl
+// ps2kbd.c
+//
+// 48 4/27/11 4:34a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 47 1/05/11 12:58a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 46 8/23/10 4:21a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.c
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 45 8/19/10 8:08a Fredericko
+// [TAG] EIP40711
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] Keyboard sometimes does not work in DOS if KBD is being
+// pressed hapazardly during post.
+// [RootCause] After reprogramming of Interrupt Controller base; if
+// keyboard is being pressed hapardzadly, KBD IRQ could be missed and KBD
+// might not work in DOS.
+// [Solution] Follow proper procedures to Reset KBD controller after
+// reprogramming the base of the Interrrupt controller
+// [Files] Thunk.c in CSM
+//
+// 44 7/20/10 4:31a Rameshr
+// Corrected the FreePool call in UnRegisterKeyNotify function
+//
+// 43 5/14/10 11:07a Olegi
+// Added FreePool call in UnRegisterKeyNotify function.
+//
+// 42 5/10/10 1:50a Rameshr
+// Issue:Shift Key issues in RegsiterkeyNotify function
+// Solution: ShiftKeyState and KeyToggleState verified for
+// RegisterKeyNotify callback function.
+// EIP 38211
+//
+// 41 5/10/10 1:41a Rameshr
+// PrintKey/SysRq key, Menu Key, Left Logo and Right Logo Key support
+// added in Ps2 Keyboard driver
+// EIP 38212
+//
+// 40 3/15/10 2:40p Krishnakumarg
+// Pressing DEL key continously intermittently or sticking does not enter
+// setup. EIP: 34615
+//
+// 39 1/29/10 2:11p Krishnakumarg
+// When user press "Ctrl+Break" key, the Scr Lk LED will turn on - #EIP
+// 34317
+//
+// 38 8/13/09 3:02p Rameshr
+// When item "num-lock status" set off, Num-lock will keep open until in
+// DOS.
+// EIP:21757
+//
+// 37 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 36 6/26/09 4:03p Rameshr
+// Symptom: Shift Key Status get set when DELL key pressed more
+// frequently.
+// Reason: DELL key scan code E0 taken by Reset Function and Int9. This
+// has been handled by modifiying Reset function and using BDA.
+// EIP:22611
+//
+// 35 3/30/09 10:28a Pats
+// Issue: EIP 19547 - Pause key support needed in Aptio
+// Solution: Function HandleKBDData modified to pass EFI_KEY vaule of
+// pause key on rather than rejecting it.
+//
+// 34 1/23/09 9:54a Rameshr
+// Symptom:SCT failure in ReadKeystrokeEx function.
+// Solution: Validated the Input parameters Keydata for the
+// ReadKeystrokeEx Function.
+// Eip: 19039
+//
+// 33 11/17/08 10:04a 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:56p Olegi
+// Implemented the Register/Unregister key notofocation function in
+// SimpletextinEx protocol.
+//
+// 31 8/15/08 10:57a Olegi
+// Correction in KbdReset function.
+//
+// 30 8/13/08 9:54a Olegi
+// Change in KbdReset function, EIP#8330.
+//
+// 29 6/05/08 4:26p Olegi
+// Added support for extended keys (EIP#13630)
+//
+// 28 6/05/08 3:19p Olegi
+// Bugfix in processing the '5' key on a keypad when NumLock is off:
+// nothing should be reported.
+//
+// 27 5/09/08 10:11a Olegi
+// ProcessByte function modified
+//
+// 26 4/22/08 4:31p Felixp
+// Additional progress codes added
+//
+// 25 4/21/08 5:49p Olegi
+//
+// 24 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 23 10/25/07 4:48p Olegi
+//
+// 22 10/24/07 6:00p Olegi
+//
+// 21 10/23/07 4:04p Olegi
+// Lock keys maintenance modifications.
+//
+// 20 9/18/07 11:51a Olegi
+//
+// 19 9/18/07 11:47a Olegi
+//
+// 18 9/17/07 3:56p Olegi
+//
+// 17 9/10/07 1:14p Olegi
+//
+// 16 9/07/07 4:34p Olegi
+// EFI_KEY code implementation.
+//
+// 15 8/31/07 2:44p Olegi
+// Added SimpleTextInEx definitions.
+//
+// 14 6/22/07 2:14p Pats
+// Fixed problem of right Ctrl and Alt keys "sticking" and causing reset
+// when Ctrl-Alt-Del pressed sequentially rather than all at once.
+//
+// 13 4/19/07 1:00p Felixp
+// File reformatted to comply with AMI coding standards
+//
+// 11 4/17/07 10:34a Pats
+// Modified to comply with coding standard. No code changes.
+//
+// 10 5/05/06 5:23p Ambikas
+//
+// 9 3/13/06 2:38a Felixp
+//
+// 8 1/09/06 11:38a Felixp
+//
+// 6 12/22/05 10:21a Srinin
+// Optimized KBD Enable/Disable call
+//
+// 5 10/27/05 1:04p Srinin
+// In KbdReset, KBD driver buffer is cleared.
+//
+// 4 10/11/05 4:09p Srinin
+// KBD reset function implemented and other minor changes done.
+//
+// 3 8/30/05 1:08p Srinin
+// KeyBoard buffer and handling of keys which send 4 scan codes modified.
+//
+// 2 3/04/05 3:55p Olegi
+// Shift states corrected for non-letter keys.
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 12/16/04 2:28p Olegi
+// Fix: Caps-Lock made irrelevant to the upper row of keys.
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 10 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2kbd.c
+//
+// Description: PS/2 keyboard support routines
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "ps2ctl.h"
+#include "kbc.h"
+
+
+#define E0_STATUS_IN_BDA BIT1
+#define E1_STATUS_IN_BDA BIT0
+#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+#include <Protocol/LegacyBios.h>
+UINT16 BdaSeg = 0x400;
+UINT16 *BdaKbdHead = (UINT16 *)0x41A;
+UINT16 *BdaKbdTail = (UINT16 *)0x41C;
+EFI_LEGACY_BIOS_PROTOCOL *gLegacy=NULL;
+BOOLEAN gLegacyBiosProtocolFound = FALSE;
+#endif
+#endif
+
+/*
+Table 2. PS/2 Scan Codes Supported in Windows 2000/Windows XP and Windows Me
+
+HID usage/ key name Set 1Make Set 1Break Set 2Make Set 2Break
+ Scan Next Track E0 19 E0 99 E0 4D E0 F0 4D
+ Scan Previous Track E0 10 E0 90 E0 15 E0 F0 15
+ Stop E0 24 E0 A4 E0 3B E0 F0 3B
+ Play/ Pause E0 22 E0 A2 E0 34 E0 F0 34
+ Mute E0 20 E0 A0 E0 23 E0 F0 23
+ Volume Increment E0 30 E0 B0 E0 32 E0 F0 32
+ Volume Decrement E0 2E E0 AE E0 21 E0 F0 21
+ AL Email Reader E0 6C E0 EC E0 48 E0 F0 48
+ AC Search E0 65 E0 E5 E0 10 E0 F0 10
+ AC Home E0 32 E0 B2 E0 3A E0 F0 3A
+ AC Back E0 6A E0 EA E0 38 E0 F0 38
+ AC Forward E0 69 E0 E9 E0 30 E0 F0 30
+ AC Stop E0 68 E0 E8 E0 28 E0 F0 28
+ AC Refresh E0 67 E0 E7 E0 20 E0 F0 20
+ AC Bookmarks E0 66 E0 E6 E0 18 E0 F0 18
+ AL Calculator* E0 21 E0 A1 E0 2B E0 F0 2B
+ AL Local Browser* E0 6B E0 EB E0 40 E0 F0 40
+ AL Consumer Control Configuration*
+ E0 6D E0 ED E0 50 E0 F0 50
+*/
+static UINT8 E0EnhancedKeys[] = {0x20,0x30,0x2E}; // only mute, volume-up, down
+BOOLEAN IsEnhancedKey( UINT8 data)
+{
+ UINTN i;
+
+ data &= 0x7F; // reset MSB
+ for ( i = 0; i < sizeof(E0EnhancedKeys); i++) {
+ if ( data == E0EnhancedKeys[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+
+extern BOOLEAN InsideGetMouseData;
+extern BOOLEAN KBDEnableState;
+extern UINT8 LedsAtStartup;
+extern BOOLEAN InsideMouseReset;
+BOOLEAN InsideKbdReadKey = FALSE;
+BOOLEAN InsideOnWaitingOnKey = FALSE;
+BOOLEAN InsideKbdReset = FALSE;
+extern BOOLEAN InsidePS2DataDispatcher;
+static EFI_GUID gAmiMultiLangSupportGuid = AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID;
+AMI_MULTI_LANG_SUPPORT_PROTOCOL *gPs2MultiLangSupportProtocol=NULL;
+
+EFI_STATUS KbdReset(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ BOOLEAN ExtendedVerification);
+
+EFI_STATUS KbdReadKey(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ EFI_INPUT_KEY *key);
+
+EFI_STATUS KbdResetEx(
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ BOOLEAN ExtendedVerification );
+
+EFI_STATUS KbdReadKeyEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+);
+
+EFI_STATUS KbdReadEfiKeyEx (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+);
+
+EFI_STATUS SetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+);
+
+EFI_STATUS RegisterKeyNotify(
+ 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 UnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+);
+
+void OnWaitingOnKey(EFI_EVENT Event, void *Context);
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+VOID Ps2KbdReset ( VOID );
+VOID ClearOBF ( VOID );
+#endif
+
+
+typedef struct _KEY_WAITING_RECORD{
+ DLINK Link;
+ EFI_KEY_DATA Context;
+ EFI_KEY_NOTIFY_FUNCTION Callback;
+} KEY_WAITING_RECORD;
+
+DLIST mPs2KeyboardData;
+KEY_WAITING_RECORD *mPs2KeyboardRecord;
+EFI_EVENT Ps2KeyEvent;
+#define KEY_POLLING_INTERVAL 500000
+VOID StartPollingKey(EFI_EVENT Event, VOID *Context);
+
+
+extern STATEMACHINEPROC DrivePS2KbdMachine;
+void ReadAndProcessKey(void*);
+void ProcessByte(KEYBOARD *Kbd, UINT8 data, BOOLEAN fourth_byte);
+void ResetStateMachine(KEYBOARD *Kbd);
+void LEDsOnOff(KEYBOARD* Kbd);
+
+static UINT8 E0SeqA[4] = {0x2A, 0xAA, 0x46, 0xB6};
+static UINT8 E0SeqB[11] = {0xD3, 0xD0, 0xCF, 0xC7, 0xD2, 0xCB, 0xD1, 0xC9, 0xCD, 0xC8, 0xB5};
+static UINT8 E1Seq[5] = {0x1D, 0x45, 0xE1, 0x9D, 0xC5};
+
+static UINT8 code_table[59] = { // Lower case keys
+0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8,
+9, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13,
+0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'','`',
+0,'\\','z','x','c','v','b','n','m',',','.','/',0,
+'*', 0, ' ', 0};
+static UINT8 Code_Table[59] = { // Upper case keys
+0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8,
+9, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 13,
+0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
+0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0,
+'*', 0, ' ',0};
+
+static UINT8 ScancodeToEfi_table[59] = { // EFI keys (UEFI Spec 2.1, Ch.28.4, Pg.1325)
+0, EfiKeyEsc, EfiKeyE1, EfiKeyE2, EfiKeyE3,EfiKeyE4, EfiKeyE5, EfiKeyE6,
+EfiKeyE7, EfiKeyE8, EfiKeyE9, EfiKeyE10, EfiKeyE11, EfiKeyE12, EfiKeyBackSpace,
+EfiKeyTab, EfiKeyD1, EfiKeyD2, EfiKeyD3, EfiKeyD4, EfiKeyD5, EfiKeyD6, EfiKeyD7,
+EfiKeyD8, EfiKeyD9, EfiKeyD10, EfiKeyD11, EfiKeyD12, EfiKeyEnter,
+EfiKeyCapsLock, EfiKeyC1, EfiKeyC2, EfiKeyC3, EfiKeyC4, EfiKeyC5, EfiKeyC6, EfiKeyC7,
+EfiKeyC8, EfiKeyC9, EfiKeyC10, EfiKeyC11, EfiKeyE0,
+EfiKeyLShift, EfiKeyD13, EfiKeyB1, EfiKeyB2, EfiKeyB3, EfiKeyB4, EfiKeyB5, EfiKeyB6,
+EfiKeyB7, EfiKeyB8, EfiKeyB9, EfiKeyB10, EfiKeyRshift,
+0, 0, EfiKeySpaceBar, 0};
+
+typedef struct {
+ UINT8 makecode;
+ UINT8 efi_scancode;
+ UINT8 efi_key;
+}EFI_EXTKEY;
+
+static EFI_EXTKEY ScanCode_Table[] = {
+ 0x3B, EFI_SCAN_F1, EfiKeyF1,
+ 0x3C, EFI_SCAN_F2, EfiKeyF2,
+ 0x3D, EFI_SCAN_F3, EfiKeyF3,
+ 0x3E, EFI_SCAN_F4, EfiKeyF4,
+ 0x3F, EFI_SCAN_F5, EfiKeyF5,
+ 0x40, EFI_SCAN_F6, EfiKeyF6,
+ 0x41, EFI_SCAN_F7, EfiKeyF7,
+ 0x42, EFI_SCAN_F8, EfiKeyF8,
+ 0x43, EFI_SCAN_F9, EfiKeyF9,
+ 0x44, EFI_SCAN_F10, EfiKeyF10,
+ 0x57, EFI_SCAN_F11, EfiKeyF11,
+ 0x58, EFI_SCAN_F12, EfiKeyF12,
+ 0x47, EFI_SCAN_HOME, EfiKeyHome,
+ 0x48, EFI_SCAN_UP, EfiKeyUpArrow,
+ 0x49, EFI_SCAN_PGUP, EfiKeyPgUp,
+ 0x4B, EFI_SCAN_LEFT, EfiKeyLeftArrow,
+ 0x4D, EFI_SCAN_RIGHT, EfiKeyRightArrow,
+ 0x4F, EFI_SCAN_END, EfiKeyEnd,
+ 0x50, EFI_SCAN_DN, EfiKeyDownArrow,
+ 0x51, EFI_SCAN_PGDN, EfiKeyPgDn,
+ 0x52, EFI_SCAN_INS, EfiKeyIns,
+ 0x53, EFI_SCAN_DEL, EfiKeyDel,
+ 0xFF, 0xFF, 0xFF // End of table
+};
+
+static UINT8 KeyPad_Table[] = {
+ '7','8','9','-','4','5','6','+','1','2','3','0','.'
+};
+
+static UINT8 KeyPadEfiCode_Table[] = {
+ EfiKeySeven, EfiKeyEight, EfiKeyNine, EfiKeyMinus,
+ EfiKeyFour, EfiKeyFive, EfiKeySix, EfiKeyPlus,
+ EfiKeyOne, EfiKeyTwo, EfiKeyThree,
+ EfiKeyZero, EfiKeyPeriod
+};
+
+KEYBOARD gKbd;
+KEYBOARD_IRQ_STORE gKeyboardIrqBuffer;
+EFI_CPU_ARCH_PROTOCOL *gCpuArch;
+EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+BOOLEAN gKeyboardIrqInstall=FALSE;
+BOOLEAN gKeyboardDriverStart=FALSE;
+
+extern BOOLEAN Ps2MouseDetected;
+extern BOOLEAN KbdIrqSupport;
+extern BOOLEAN KbRdBeforeInstall;
+extern BOOLEAN InsideGetMouseData;
+extern BOOLEAN KBDEnableState;
+
+#if CLEAR_PS2KB_BUFFER_AT_READYTOBOOT
+EFI_EVENT gClearKbBufferEvent;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ClearKbBuffer
+//
+// Description:
+// This function clear PS2 KB buffer
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+ClearKbBuffer(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ KEYBOARD *Kbd = &gKbd;
+ UINT8 *BdaKbHead = (UINT8*)((UINTN) 0x41a);
+ UINT8 *BdaKbTail = (UINT8*)((UINTN) 0x41c);
+ UINT8 *BdaKbBuffer = (UINT8*)((UINTN) 0x41e);
+
+ Kbd->pBufHead = Kbd->pBufStart;
+ Kbd->pBufTail = Kbd->pBufStart;
+
+ pBS->SetMem(Kbd->pBufStart, BUFFER_SIZE * sizeof (AMI_EFI_KEY_DATA), 0);
+
+ // Empty KB Buffer in BDA
+ pBS->SetMem(BdaKbBuffer, 32, 0);
+ *BdaKbTail = *BdaKbHead;
+
+ pBS->CloseEvent(Event);
+
+ return EFI_SUCCESS;
+}
+#endif
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateVariabletoCheckBda
+//
+// Description:
+// This function updates variable Legacy BIOS Protocol found,to check BDA
+// for pending keys in EFI.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+VOID UpdateVariabletoCheckBda(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ //
+ // Update Variable to check BDA if Legacy Bios Protocol Found.
+ //
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &gLegacy);
+ if (!EFI_ERROR(Status)) {
+ gLegacyBiosProtocolFound = TRUE;
+ }
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StartKeyboard
+//
+// Description: This routine is called from Driver Binding Start function,
+// it starts the keyboard
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - A pointer to the
+// EFI_DRIVER_BINDING_PROTOCOL instance
+// EFI_HANDLE Controller - Handle for this controller
+//
+// Output: EFI_STATUS - status of the operation
+//
+// Referrals: gEfiSimpleTextInProtocolGuid
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StartKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller)
+{
+
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *pDummyDevPath;
+ KEYBOARD* Kbd = &gKbd;
+ KEYBOARD_IRQ_STORE* KbIrqBuffer = &gKeyboardIrqBuffer;
+ UINT8 Index=0;
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ EFI_EVENT Event;
+ VOID *pRegistration;
+#endif
+#endif
+
+ if (EFI_ERROR(gSysTable->BootServices->OpenProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ &pDummyDevPath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+ //
+ // Reset the keyboard and Clear Pending Keys as some
+ // NoteBook Kbc needs reset and Clearing the OBF.
+ //
+ Ps2KbdReset();
+ ClearOBF ();
+#endif
+
+ DetectPS2KeyboardAndMouse();
+
+ if (EFI_ERROR(DetectPS2Keyboard())) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Initialize keyboard interface functions
+ //
+ (Kbd->iSimpleIn).Reset = KbdReset;
+ (Kbd->iSimpleIn).ReadKeyStroke = KbdReadKey;
+
+ (Kbd->iSimpleInEx).Reset = KbdResetEx;
+ (Kbd->iSimpleInEx).ReadKeyStrokeEx = KbdReadKeyEx;
+ (Kbd->iSimpleInEx).SetState = SetState;
+ (Kbd->iSimpleInEx).RegisterKeyNotify = RegisterKeyNotify;
+ (Kbd->iSimpleInEx).UnregisterKeyNotify = UnRegisterKeyNotify;
+
+ (Kbd->iKeycodeInEx).Reset = KbdResetEx;
+ (Kbd->iKeycodeInEx).ReadEfikey = KbdReadEfiKeyEx;
+ (Kbd->iKeycodeInEx).SetState = SetState;
+ (Kbd->iKeycodeInEx).RegisterKeyNotify = RegisterKeyNotify;
+ (Kbd->iKeycodeInEx).UnregisterKeyNotify = UnRegisterKeyNotify;
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnKey,
+ Kbd,
+ &Kbd->iSimpleIn.WaitForKey);
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnKey,
+ Kbd,
+ &Kbd->iSimpleInEx.WaitForKeyEx);
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnKey,
+ Kbd,
+ &Kbd->iKeycodeInEx.WaitForKeyEx);
+
+ //
+ // Install protocol interfaces for the keyboard device.
+ //
+ Status = gSysTable->BootServices->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiSimpleTextInProtocolGuid, &Kbd->iSimpleIn,
+ &gEfiSimpleTextInExProtocolGuid, &Kbd->iSimpleInEx,
+ &gAmiEfiKeycodeProtocolGuid, &Kbd->iKeycodeInEx,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleIn.WaitForKey);
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleInEx.WaitForKeyEx);
+ gSysTable->BootServices->CloseEvent(Kbd->iKeycodeInEx.WaitForKeyEx);
+ }
+
+ if (!(EFI_ERROR(Status))) {
+ //
+ // Initialize keyboard device
+ //
+ Kbd->KeyIsReady = FALSE;
+ Kbd->ScannerState = KBST_READY;
+ Kbd->KeyData.KeyState.KeyToggleState = LedsAtStartup;
+ Kbd->KeyData.KeyState.KeyToggleState |= TOGGLE_STATE_VALID;
+ Kbd->KeyData.KeyState.KeyShiftState = SHIFT_STATE_VALID;
+
+ Kbd->pBufStart = MallocZ(BUFFER_SIZE * sizeof (AMI_EFI_KEY_DATA));
+ if(!Kbd->pBufStart) return EFI_OUT_OF_RESOURCES;
+ Kbd->pBufHead = Kbd->pBufStart;
+ Kbd->pBufTail = Kbd->pBufStart;
+ Kbd->pBufEnd = Kbd->pBufStart + BUFFER_SIZE;
+
+ DrivePS2KbdMachine = ReadAndProcessKey;
+
+ //
+ // Set LED's
+ //
+ LEDsOnOff(Kbd);
+
+ InitHotKeys(Controller); // Produce HotKeys protocol
+
+// for (Count = 3; Count; Count--) {
+// if(IssueCommand(0xF4) == 0xFA) break; // Clear the KBD buffer
+// }
+
+ Kbd->LEDCommandState = 0;
+
+#if CLEAR_PS2KB_BUFFER_AT_READYTOBOOT
+ gSysTable->BootServices->CreateEvent(
+ EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ TPL_NOTIFY,
+ ClearKbBuffer,
+ NULL,
+ &gClearKbBufferEvent);
+#endif
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ RegisterProtocolCallback(
+ &gEfiLegacyBiosProtocolGuid, UpdateVariabletoCheckBda,
+ NULL, &Event,&pRegistration
+ );
+
+ //
+ // Check whether Legacy BIOS Protocol Installed.
+ //
+ UpdateVariabletoCheckBda(NULL,NULL);
+
+#endif
+#endif
+ }
+
+ DListInit(&mPs2KeyboardData);
+
+ Status = pBS->CreateEvent(
+ EVT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ StartPollingKey,
+ Kbd,
+ &Ps2KeyEvent
+ );
+
+ //
+ // if before keyboard driver starts data is available in buffer
+ // it will be collected in local buffer in KeyboardInterrupt?Handler
+ // only if KBD_READ_BEFORE_INSTALL = 1, the avalable data in local
+ // buffer is processed.
+ //
+ if(KbRdBeforeInstall){
+ for (Index=0;Index < KbIrqBuffer->KbdIndex; Index++){
+ ProcessKBDData(Kbd, KbIrqBuffer->KbdBuffer[Index]);
+ }
+ }
+ gKeyboardDriverStart = TRUE;
+ //
+ // Re enable keyboard irq as it was previously disabled.
+ // if KBD_READ_BEFORE_INSTALL = 0 then initialize keyboard irq here
+ //
+ if(KbdIrqSupport){
+ if(KbRdBeforeInstall){
+ gKeyboardIrqInstall = TRUE;
+ //
+ // Now enable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+ else {
+ InitKeyboardIrq();
+ }
+ }
+ //
+ // Enable the Keyboard and Keyboard Interrupt. We must initilize this
+ // one for the Keyboard to work on Legacy mode. And also Legacy mode AMIUSB driver
+ // expects Keyboard and Interrupt should be enabled once Port 60/64 is present.
+ //
+ Write8042CommandByte(0x65);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StopKeyboard
+//
+// Description: This routine is called from Driver Binding Stop function.
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - A pointer to the
+// EFI_DRIVER_BINDING_PROTOCOL instance
+// EFI_HANDLE Controller - Handle for this controller
+//
+// Output: EFI_STATUS - status of the operation
+//
+// Referrals: gEfiSimpleTextInProtocolGuid
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StopKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller)
+{
+ KEYBOARD* Kbd = &gKbd;
+ EFI_STATUS Status;
+
+ //
+ // Uninstall protocol interfaces from the keyboard device.
+ //
+ Status = gSysTable->BootServices->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiSimpleTextInProtocolGuid, &Kbd->iSimpleIn,
+ &gEfiSimpleTextInExProtocolGuid, &Kbd->iSimpleInEx,
+ &gAmiEfiKeycodeProtocolGuid, &Kbd->iKeycodeInEx,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Close protocols that is open during Start
+ //
+ Status = gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Kill wait event
+ //
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleIn.WaitForKey);
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleInEx.WaitForKeyEx);
+ gSysTable->BootServices->CloseEvent(Kbd->iKeycodeInEx.WaitForKeyEx);
+ gSysTable->BootServices->CloseEvent(Ps2KeyEvent);
+
+ pBS->FreePool(Kbd->pBufStart);
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KbdReset
+//
+// Description: Resets the input device hardware. This routine is a part
+// of SimpleTextIn protocol implementation.
+//
+// Parameters: EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// *This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// instance.
+// BOOLEAN
+// ExtendedVerification - Indicates that the driver may
+// perform a more exhaustive verification operation of the
+// device during reset.
+//
+// Output: EFI_SUCCESS The device was reset.
+// EFI_DEVICE_ERROR The device is not functioning correctly
+// and could not be reset.
+//
+// Modified: KBDEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS KbdReset(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ BOOLEAN ExtendedVerification )
+{
+ UINT8 bCount, bData, bBCount;
+ KEYBOARD* Kbd = &gKbd;
+ EFI_STATUS Status;
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport && gKeyboardIrqInstall) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ);
+ }
+ InsideKbdReset = TRUE;
+ Kbd->KeyIsReady = FALSE;
+ Kbd->ScannerState = KBST_READY;
+
+ Kbd->pBufHead = Kbd->pBufStart;
+ Kbd->pBufTail = Kbd->pBufStart;
+
+ pBS->SetMem(Kbd->pBufStart, BUFFER_SIZE * sizeof (AMI_EFI_KEY_DATA), 0);
+
+ DisableKeyboard();
+ PROGRESS_CODE(DXE_KEYBOARD_RESET);
+
+ for (bBCount = 0; bBCount < 4; bBCount++) {
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_DISABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_ENABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+ //
+ // Report the Buffer FULL error code if there is failure.
+ //
+ if (EFI_ERROR(Status)) {
+ ERROR_CODE (DXE_KEYBOARD_BUFFER_FULL_ERROR, EFI_ERROR_MAJOR);
+ }
+
+ KBDEnableState = FALSE;
+ Status = EnableKeyboard();
+
+ if (EFI_ERROR(Status)) {
+ //
+ // Report the KBC Controller error code.
+ //
+ ERROR_CODE (DXE_KEYBOARD_CONTROLLER_ERROR, EFI_ERROR_MAJOR);
+ }
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+ //
+ // Clear OBF as some Notebook KBC has some keys even after
+ // disabling and enabling scanning.
+ //
+ ClearOBF ();
+#endif
+
+ if(!gKeyboardIrqInstall){
+ LEDsOnOff(Kbd);
+ }
+
+ Kbd->LEDCommandState = 0;
+ InsideKbdReset = FALSE;
+
+ if(KbdIrqSupport && gKeyboardIrqInstall) {
+
+
+ //
+ // Now enable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS KbdResetEx(
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ BOOLEAN ExtendedVerification )
+{
+ return KbdReset(0, ExtendedVerification);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KbdReadKey
+//
+// Description: Reads the next keystroke from the input device. This
+// routine is a part of SimpleTextIn protocol
+// implementation.
+//
+// Paremeters: EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// instance.
+// EFI_INPUT_KEY
+// InputKey - A pointer to a buffer that is to be filled in
+// with the keystroke information for the key that was
+// pressed.
+//
+// Output: EFI_SUCCESS - The keystroke information was returned.
+// EFI_NOT_READY - There was no keystroke data available.
+// EFI_DEVICE_ERROR - The keystroke information was not
+// returned due to hardware errors.
+//
+// Modified: InsideKbdReadKey
+//
+// Referral(s): InsideGetMouseData, InsideGetMouseData,
+// InsideOnWaitingOnKey
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS KbdReadKey(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ EFI_INPUT_KEY *InputKey )
+{
+ KEYBOARD* Kbd = &gKbd;
+
+ if (InsideGetMouseData || InsideKbdReadKey || InsideOnWaitingOnKey || InsideKbdReset || InsideMouseReset) {
+ return GetKeyFromBuffer (Kbd, (VOID*)InputKey, sizeof(EFI_INPUT_KEY));
+ }
+
+ InsideKbdReadKey = TRUE;
+
+ PS2DataDispatcher(This);
+
+ InsideKbdReadKey = FALSE;
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ if (!CheckKeyinBuffer(Kbd)) {
+ if( *BdaKbdHead != *BdaKbdTail ) {
+ ProcessKBDData (Kbd, *((UINT8 *)(*BdaKbdHead + BdaSeg + 1)));
+ *BdaKbdHead += 2;
+ if(*BdaKbdHead == 0x3E) {
+ *BdaKbdHead = 0x1E;
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+ return GetKeyFromBuffer (Kbd, (VOID*)InputKey, sizeof(EFI_INPUT_KEY));
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KbdReadKeyEx
+//
+// Description: Reads the next keystroke from the input device. This
+// routine is a part of SimpleTextInEx protocol
+// implementation.
+//
+// Paremeters: EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
+// *This - A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
+// instance.
+//
+// Output: EFI_INPUT_KEY
+// *key - A pointer to a buffer that is filled in with the
+// keystroke state data for the key that was pressed.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+KbdReadKeyEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+ KEYBOARD *Kbd = &gKbd;
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (!InsideGetMouseData && !InsideKbdReadKey && !InsideOnWaitingOnKey && !InsideKbdReset && !InsideMouseReset) {
+ InsideKbdReadKey = TRUE;
+ PS2DataDispatcher(This);
+ InsideKbdReadKey = FALSE;
+ }
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ if (!CheckKeyinBuffer(Kbd)) {
+ if( *BdaKbdHead != *BdaKbdTail ) {
+ ProcessKBDData (Kbd, *((UINT8 *)(*BdaKbdHead + BdaSeg + 1)));
+ *BdaKbdHead += 2;
+ if(*BdaKbdHead == 0x3E) {
+ *BdaKbdHead = 0x1E;
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+ Status = GetKeyFromBuffer (Kbd, (VOID*)KeyData, sizeof(EFI_KEY_DATA));
+ if (EFI_ERROR(Status)) {
+
+ pBS->SetMem(KeyData, sizeof (EFI_KEY_DATA), 0);
+ //
+ // Check the partial Key. If found return Success with NULL data
+ // in EFI_INPUT_KEY.
+ //
+ Status=CheckPartialKey(Kbd, (EFI_KEY_DATA*)KeyData);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS KbdReadEfiKeyEx (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+ KEYBOARD *Kbd = &gKbd;
+
+ if (!InsideGetMouseData && !InsideKbdReadKey && !InsideOnWaitingOnKey && !InsideKbdReset && !InsideMouseReset) {
+ InsideKbdReadKey = TRUE;
+ PS2DataDispatcher(This);
+ InsideKbdReadKey = FALSE;
+ }
+
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ //
+ // If there is no key, check whether any key is present BDA Keyboard buffer as
+ // we may miss any key in legacy mode.
+ //
+ if (!CheckKeyinBuffer(Kbd)) {
+ if( *BdaKbdHead != *BdaKbdTail ) {
+ //
+ // Get the scan code from BDA keyboard buffer and process it.
+ //
+ ProcessKBDData (Kbd, *((UINT8 *)(*BdaKbdHead + BdaSeg + 1)));
+ *BdaKbdHead += 2;
+ //
+ // Check whether we have reached end of circular buffer, if reached initialize
+ // header to beginning of the buffer.
+ //
+ if(*BdaKbdHead == 0x3E) {
+ *BdaKbdHead = 0x1E;
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+ Status = GetKeyFromBuffer (Kbd, (VOID*)KeyData, sizeof(AMI_EFI_KEY_DATA));
+ if (EFI_ERROR(Status)) {
+ pBS->SetMem(KeyData, sizeof (AMI_EFI_KEY_DATA), 0);
+ //
+ // Check the partial Key. If found return Success with NULL data
+ // in EFI_INPUT_KEY.
+ //
+ Status=CheckPartialKey(Kbd, (EFI_KEY_DATA*)KeyData);
+ return Status;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetState
+//
+// 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
+SetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ BOOLEAN ChgSL = FALSE;
+ BOOLEAN ChgCL = FALSE;
+ BOOLEAN ChgNL = FALSE;
+
+ KEYBOARD* Kbd = &gKbd;
+
+ 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;
+ }
+
+
+ ChgSL = ((*KeyToggleState & SCROLL_LOCK_ACTIVE)!=0) ^ ((Kbd->KeyData.KeyState.KeyToggleState & SCROLL_LOCK_ACTIVE)!=0);
+ ChgNL = ((*KeyToggleState & NUM_LOCK_ACTIVE)!=0) ^ ((Kbd->KeyData.KeyState.KeyToggleState & NUM_LOCK_ACTIVE)!=0);
+ ChgCL = ((*KeyToggleState & CAPS_LOCK_ACTIVE)!=0) ^ ((Kbd->KeyData.KeyState.KeyToggleState & CAPS_LOCK_ACTIVE)!=0);
+
+ if (ChgSL || ChgCL || ChgNL) {
+ Kbd->KeyData.KeyState.KeyToggleState &= ~(SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE);
+
+ if (*KeyToggleState & SCROLL_LOCK_ACTIVE) Kbd->KeyData.KeyState.KeyToggleState |= SCROLL_LOCK_ACTIVE;
+ if (*KeyToggleState & NUM_LOCK_ACTIVE) Kbd->KeyData.KeyState.KeyToggleState |= NUM_LOCK_ACTIVE;
+ if (*KeyToggleState & CAPS_LOCK_ACTIVE) Kbd->KeyData.KeyState.KeyToggleState |= CAPS_LOCK_ACTIVE;
+
+ LEDsOnOff(Kbd);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: StartPollingKey
+//
+// Description: Get the keys from the keyboard controller
+//
+// 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)
+{
+ if (!InsideGetMouseData && !InsideKbdReadKey && !InsideOnWaitingOnKey && !InsideKbdReset && !InsideMouseReset) {
+ InsideKbdReadKey = TRUE;
+ PS2DataDispatcher(Context);
+ InsideKbdReadKey = FALSE;
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckKeyNotify
+//
+// Description: Call the notification function based on the key pressed
+//
+// Input: Key - Key pressed
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckKeyNotify(AMI_EFI_KEY_DATA *Key)
+{
+
+ KEY_WAITING_RECORD *Ps2KeyIn = OUTTER(mPs2KeyboardData.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;
+
+ // if the list is empty return the status that was passed in
+ if (Ps2KeyIn == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( Ps2KeyIn != 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 (Ps2KeyIn->Context.Key.ScanCode != 0) {
+ if( Ps2KeyIn->Context.Key.ScanCode == Key->Key.ScanCode) {
+ KeyScanCodeMatch=TRUE;
+ }
+ } else {
+ KeyScanCodeMatch=TRUE;
+ }
+
+ //
+ // Check the Uncide Code Matching
+ //
+
+ if(Ps2KeyIn->Context.Key.UnicodeChar == Key->Key.UnicodeChar) {
+ KeyUniCodeMatch=TRUE;
+ }
+
+ if(Ps2KeyIn->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 (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) {
+ 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 (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_CONTROL_PRESSED | LEFT_CONTROL_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_CONTROL_PRESSED | LEFT_CONTROL_PRESSED)) {
+ 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 (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
+ 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 (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_LOGO_PRESSED | LEFT_LOGO_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_LOGO_PRESSED | LEFT_LOGO_PRESSED)) {
+ LogoKeyMatch=TRUE;
+ }
+ } else {
+ LogoKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Menu Key Matching
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & MENU_KEY_PRESSED) {
+ if(Key->KeyState.KeyShiftState & MENU_KEY_PRESSED) {
+ MenuKeyMatch=TRUE;
+ }
+ } else {
+ MenuKeyMatch=TRUE;
+ }
+
+ //
+ // Check the SysRq Key Matching
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & SYS_REQ_PRESSED) {
+ if(Key->KeyState.KeyShiftState & SYS_REQ_PRESSED) {
+ SysRqKeyMatch=TRUE;
+ }
+ } else {
+ SysRqKeyMatch=TRUE;
+ }
+
+ KeyShiftCodeMatch=ShiftKeyMatch & CtrlKeyMatch & AltKeyMatch
+ & LogoKeyMatch & MenuKeyMatch & SysRqKeyMatch;
+ }else {
+ KeyShiftCodeMatch=TRUE;
+ }
+ //
+ // Check the Key Toggle State
+ //
+ if(Ps2KeyIn->Context.KeyState.KeyToggleState & TOGGLE_STATE_VALID){
+ if(Ps2KeyIn->Context.KeyState.KeyToggleState == Key->KeyState.KeyToggleState) {
+ KeyToggleKeyMatch=TRUE;
+ }
+ } else {
+ KeyToggleKeyMatch=TRUE;
+ }
+
+ //
+ // If everything matched, call the callback function.
+ //
+ if(KeyScanCodeMatch & KeyUniCodeMatch & KeyShiftCodeMatch & KeyToggleKeyMatch) {
+ //Call the notification function
+ //
+ Ps2KeyIn->Callback(&Ps2KeyIn->Context);
+ }
+ // go to the next element in the list
+ Ps2KeyIn = OUTTER(Ps2KeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RegisterKeyNotify
+//
+// Description: Register the callback function for the specific 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
+RegisterKeyNotify(
+ 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;
+
+
+ if(KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Create database record and add to database
+ //
+ Status = pBS->AllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (KEY_WAITING_RECORD),
+ &mPs2KeyboardRecord
+ );
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Gather information about the registration request
+ //
+
+ mPs2KeyboardRecord->Context = *KeyData;
+ mPs2KeyboardRecord->Callback = KeyNotificationFunction;
+
+ DListAdd (&mPs2KeyboardData, &(mPs2KeyboardRecord->Link));
+
+ //
+ // Child's handle will be the address linked list link in the record
+ //
+ *NotifyHandle = (EFI_HANDLE) (&mPs2KeyboardRecord->Link);
+
+ if(mPs2KeyboardData.Size == 1) {
+ pBS->SetTimer(Ps2KeyEvent,
+ TimerPeriodic,
+ KEY_POLLING_INTERVAL);
+ }
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UnRegisterKeyNotify
+//
+// Description: Unregister the callback function
+//
+// 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
+UnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+)
+{
+
+ DLINK *ListPtr;
+ KEY_WAITING_RECORD *Ps2KeyIn;
+
+ if(NotificationHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ListPtr = mPs2KeyboardData.pHead;
+ while ( ListPtr != NULL)
+ {
+ Ps2KeyIn = OUTTER(ListPtr, Link, KEY_WAITING_RECORD);
+ if ( (&Ps2KeyIn->Link) == NotificationHandle)
+ {
+ DListDelete(&mPs2KeyboardData, ListPtr);
+ pBS->FreePool(Ps2KeyIn);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ if(ListPtr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(mPs2KeyboardData.Size == 0) {
+ pBS->SetTimer(Ps2KeyEvent,
+ TimerCancel,
+ 0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OnWaitingOnKey
+//
+// Description: Callback for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey
+// event;
+// checks whether the new key is available and if so -
+// signals the event.
+//
+// Input: EFI_EVENT Event - Event to signal
+// void Context - Event specific context (pointer to Kbd
+// device)
+//
+// Output: None
+//
+// Modified: InsideOnWaitingOnKey
+//
+// Referrals: InsideGetMouseData, InsideKbdReadKey,
+// InsideOnWaitingOnKey
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+OnWaitingOnKey (
+ EFI_EVENT Event,
+ VOID *Context )
+{
+
+ if (InsideGetMouseData || InsideKbdReadKey || InsideOnWaitingOnKey || InsideKbdReset || InsideMouseReset) {
+ if (CheckKeyinBuffer((KEYBOARD*)Context)) gSysTable->BootServices->SignalEvent(Event);
+ return;
+ }
+
+ InsideOnWaitingOnKey = TRUE;
+
+ PS2DataDispatcher(Context); // Process new keys if available
+
+ InsideOnWaitingOnKey = FALSE;
+
+ if (CheckKeyinBuffer((KEYBOARD*)Context))
+ {
+ gSysTable->BootServices->SignalEvent(Event);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadAndProcessKey
+//
+// Description: PS2 keyboard keys processor, called from main PS2
+// dispatcher.
+// It gets the key from KBC output buffer and calls
+// HandleKBDData.
+//
+// Paremeters: void *Context - keyboard device pointer
+//
+// Output: None
+//
+// Notes: PS2 output buffer has data, incoming key is processed,
+// Context->KeyIsReady is updated.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ReadAndProcessKey (
+ VOID *Context )
+{
+
+ KEYBOARD *Kbd = &gKbd;
+ UINT8 data;
+
+ data = KBCGetData();
+ ProcessKBDData (Kbd, data);
+ return;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessKBDData
+//
+// Description: If key is ready, processes any hotkey, and inserts key
+// in buffer
+//
+// Parameters:
+// KEYBOARD *Kbd - Pointer to key buffer
+// UINT8 data - Key data
+//
+// Output: None
+//
+// Notes: Incoming key is processed, Context->KeyIsReady is updated
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessKBDData (
+ KEYBOARD *Kbd,
+ UINT8 data
+)
+{
+ EFI_KEY_DATA DummyKey;
+
+ HandleKBDData(Kbd, data);
+ if (Kbd->KeyIsReady) {
+
+ ProcessHotKey(Kbd->KeyData.PS2ScanCode,
+ (UINT16)Kbd->KeyData.KeyState.KeyShiftState);
+ InsertKeyToBuffer(Kbd, &Kbd->KeyData);
+ Kbd->KeyIsReady = FALSE;
+ } else {
+ if (Kbd->KeyData.Key.ScanCode == 0 && Kbd->KeyData.Key.UnicodeChar == 0 && Kbd->ScannerState == KBST_READY ) {
+ //
+ // If the Key ShiftState has valid key, report as Partial Key
+ //
+ if ((Kbd->KeyData.KeyState.KeyShiftState & ~SHIFT_STATE_VALID) != 0) {
+
+ pBS->CopyMem(&DummyKey, &Kbd->KeyData, sizeof(EFI_KEY_DATA));
+ DummyKey.KeyState.KeyToggleState |= KEY_STATE_EXPOSED;
+ CheckKeyNotify((AMI_EFI_KEY_DATA*)&DummyKey);
+ }
+ }
+ }
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: HandleKBDData
+//
+// Description: Processes the input data. If a callback function is
+// associated with the key, then it is executed.
+//
+// Paremeters:
+// KEYBOARD *Kbd - Pointer to key buffer
+// UINT8 data - Key data
+//
+// Output: None
+//
+//
+// Notes: This routine can be called re-entrantly from LEDsOnOff(OutToKb)
+// e.g. when Numlock and Del is pressed continously.
+// Incoming key is processed, Context->KeyIsReady is updated.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+HandleKBDData (
+ KEYBOARD *Kbd,
+ UINT8 data )
+{
+ //
+ // PS2 keyboard could send one, two, four or six bytes in a row.
+ // Kbd->ScannerState is ST_READY if it is the first byte
+ //
+ if (Kbd->ScannerState == KBST_READY)
+ {
+ switch (data) {
+ case 0xE0:
+ Kbd->ScannerState = KBST_E0;
+ break;
+ case 0xE1:
+ Kbd->ScannerState = KBST_E1;
+ break;
+ default:
+ ProcessByte(Kbd, data, FALSE);
+ }
+ return;
+ }
+ else // Multi-byte sequence is being processed
+ {
+ if (Kbd->ScannerState == KBST_E1) // Processing E1 state
+ {
+ if (data != E1Seq[Kbd->Count]) { // Wrong byte in a sequence
+ ResetStateMachine(Kbd);
+ return;
+ }
+ //
+ // E1 sequence data is correct, proceed
+ //
+ if (Kbd->Count == 2) { // The ONLY 2-key sequence starting with E1 is Pause
+ Kbd->KeyData.EfiKey = EfiKeyPause;
+ Kbd->KeyIsReady = TRUE;
+ ResetStateMachine(Kbd);
+ return;
+ }
+ if (Kbd->Count == 4) { // E1 sequence has finished
+ ProcessByte(Kbd, data, FALSE);
+ ResetStateMachine(Kbd);
+ return;
+ }
+ //
+ // E1 sequence is not complete, update the counter and return
+ //
+ Kbd->Count++;
+ return;
+ }
+ else // Kbd->ScannerState == ST_E0 - processing E0 state
+ {
+
+ //
+ // For E0 state the Count values will be:
+ // 0 for 1st and 2nd byte
+ // 2 for 3rd byte (if available)
+ // 1 for 4th byte (if available)
+ // No validity checking will be done for 2nd,3rd and 4th bytes
+ //
+
+ if (Kbd->ScannerState == KBST_E0) {
+ if ( IsEnhancedKey( data)) {
+ ResetStateMachine(Kbd);
+ return;
+ }
+ // Processing E0 state, if data is 2A or AA or MSB bit is
+ // set (break key) ignore it.
+ if (data == 0x2A || data == 0xAA || data & 0x80 && \
+ // except in special case of alt, ctrl, Print key, Left Logo, Right Logo and Menu Key
+ data != 0xb8 && data != 0x9d && data != 0xB7 && \
+ data != 0xDB && data != 0xDC && data != 0xDD) {
+ ResetStateMachine(Kbd);
+ return;
+ }
+ else {
+ ProcessByte(Kbd, data, TRUE);
+ ResetStateMachine(Kbd);
+ return;
+ }
+ }
+ ProcessByte(Kbd, data, FALSE);
+ ResetStateMachine(Kbd);
+ return;
+
+ }
+ }
+}
+
+
+
+void ResetStateMachine(KEYBOARD *Kbd)
+{
+ Kbd->ScannerState = KBST_READY;
+ Kbd->Count = 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IsLetter
+//
+// Description: Returns TRUE if the given make code belongs to the
+// alphabetical symbol, otherwise returns FALSE.
+//
+// Paremeters: UINT8 data - The character to test
+//
+// Output: BOOLEAN - True if character is letter
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsLetter (
+ UINT8 data )
+{
+ if ((data >= 0x10 && data <= 0x19) || // Q...P
+ (data >= 0x1E && data <= 0x26) || // A...L
+ (data >= 0x2C && data <= 0x32)) { // Z...M
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessByte
+//
+// Description: Checks for valid key, updates key modifiers, keyboard
+// queue head and tail as well as Kbd->KeyIsReady field.
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// UINT8 data - byte to process
+// BOOLEAN long_sequence - the indication of whether it is a
+// 4 byte sequence or not; used to differentiate Shift keys
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessByte (
+ KEYBOARD *Kbd,
+ UINT8 Data,
+ BOOLEAN long_sequence )
+{
+ BOOLEAN bUpperCase, bShifted;
+ EFI_EXTKEY *extkey;
+ static BOOLEAN Make_Capslock = FALSE, Make_SCRLOCK = FALSE, Make_NUMLOCK = FALSE;
+ UINT8 *KeyboardTypeBda = (UINT8*)((UINTN) 0x496);
+
+
+ Kbd->KeyData.Key.ScanCode = 0;
+ Kbd->KeyData.Key.UnicodeChar = 0;
+ Kbd->KeyData.PS2ScanCode = Data;
+
+ //
+ // Process ESC key
+ //
+ if (Data == 1) {
+ Kbd->KeyData.Key.ScanCode = EFI_SCAN_ESC;
+ Kbd->KeyData.EfiKey = EfiKeyEsc;
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+
+ //
+ // Get the E0, E1 Status from BDA (40:96). If those bit get set means Int9 processed the E0
+ // E1 data and before processing other Scan code it came out of Legacy mode.
+ // Now EFI driver sees other scan code that's part of the E0 and E1 scan. So we don't want to Process
+ // those data.
+ //
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ if(*KeyboardTypeBda & (E0_STATUS_IN_BDA + E1_STATUS_IN_BDA)) {
+ *KeyboardTypeBda &=~(E0_STATUS_IN_BDA + E1_STATUS_IN_BDA);
+ return;
+ }
+ }
+#endif
+#endif
+
+ //
+ // Process key modifiers: xyzLock (update LEDs) and Ctrl/Alt/Shift
+ //
+ switch (Data) {
+ case 0x38:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_ALT_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_ALT_PRESSED;
+ }
+ return; //break;
+ case 0xB8:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~RIGHT_ALT_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~LEFT_ALT_PRESSED;
+ }
+ return; //break;
+
+ case 0x1D:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_CONTROL_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_CONTROL_PRESSED;
+ }
+ return; //break;
+ case 0x9D:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~RIGHT_CONTROL_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~LEFT_CONTROL_PRESSED;
+ }
+ return; //break;
+
+ case 0x2A: {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_SHIFT_PRESSED; return; //break;
+ }
+ case 0xAA: // could be a part of a long break code
+ if (!long_sequence) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~LEFT_SHIFT_PRESSED;
+ }
+ return; //break;
+
+ case 0x36: Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_SHIFT_PRESSED; return; //break;
+ case 0xB6: Kbd->KeyData.KeyState.KeyShiftState &= ~RIGHT_SHIFT_PRESSED; return; //break;
+
+ case 0x3A:
+ if (!Make_Capslock) {
+ Kbd->KeyData.KeyState.KeyToggleState ^= CAPS_LOCK_ACTIVE;
+ Make_Capslock = TRUE;
+ }
+ Kbd->KeyData.EfiKey = EfiKeyCapsLock;
+ Kbd->KeyIsReady = TRUE;
+ break;
+
+ case 0xBA: Make_Capslock = FALSE; break;
+
+ case 0x46:
+ if (Kbd->ScannerState != KBST_E0){
+ if (!Make_SCRLOCK) {
+ Kbd->KeyData.KeyState.KeyToggleState ^= SCROLL_LOCK_ACTIVE;
+ Make_SCRLOCK = TRUE;
+ }
+ Kbd->KeyData.EfiKey = EfiKeySLck;
+ Kbd->KeyIsReady = TRUE;
+ }
+ break;
+
+ case 0xC6:
+ if (Kbd->ScannerState != KBST_E0){
+ Make_SCRLOCK = FALSE;
+ }
+ break;
+ case 0x45:
+ if (!Make_NUMLOCK) {
+ Kbd->KeyData.KeyState.KeyToggleState ^= NUM_LOCK_ACTIVE;
+ Make_NUMLOCK = TRUE;
+ }
+ Kbd->KeyData.EfiKey = EfiKeyNLck;
+ Kbd->KeyIsReady = TRUE;
+ break;
+
+ case 0xC5: Make_NUMLOCK = FALSE; break;
+ //
+ // Handle the PrintScreen/SysRq make Code
+ //
+ case 0x37:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= SYS_REQ_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the PrintScreen/SysRq breakcode
+ //
+ case 0xB7:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ SYS_REQ_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Left Logo make Code
+ //
+ case 0x5B:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Left Logo breakcode
+ //
+ case 0xDB:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ LEFT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Right Logo make Code
+ //
+ case 0x5C:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Right Logo breakcode
+ //
+ case 0xDC:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ RIGHT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Menu Key make Code
+ //
+ case 0x5D:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= MENU_KEY_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Meny Key breakcode
+ //
+ case 0xDD:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ MENU_KEY_PRESSED;
+ return;
+ }
+ break;
+
+ case 0xFA: ProcessKBDResponse(Kbd, Data); break;
+ case 0xFE: ProcessKBDResponse(Kbd, Data); break;
+ case 0xFF: ProcessKBDResponse(Kbd, Data); break;
+ }
+
+ //
+ // Process main block of keys
+ //
+ if (Data < 0x3A && !(Kbd->ScannerState == KBST_E0 && Data == 0x37)) {// Exceptional case is Printscreen/sys req
+
+ bShifted = Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+
+ if (Kbd->ScannerState == KBST_E0) bShifted = 0; // Check for '/' in Keypad. Otherwise '?' will be sent
+
+
+ if (IsLetter(Data)) { // for not-a-letter Caps-Lock must not work
+ bUpperCase = (Kbd->KeyData.KeyState.KeyToggleState & CAPS_LOCK_ACTIVE)? !bShifted: bShifted;
+ }
+ else {
+ bUpperCase = bShifted;
+ }
+ if (bUpperCase) {
+ Kbd->KeyData.Key.UnicodeChar = Code_Table[Data]; // UPPER CASE TABLE
+ }
+ else {
+ Kbd->KeyData.Key.UnicodeChar = code_table[Data]; // lower case table
+ }
+ Kbd->KeyData.EfiKey = ScancodeToEfi_table[Data];
+ if (Kbd->KeyData.Key.UnicodeChar != 0) {
+ Kbd->KeyIsReady = TRUE;
+ }
+ return;
+ }
+
+// UK Keyboard "|\" (EfiKeyB0)
+// data = 0x56(ScanCode Set1), EfiKeyB0, "|\"
+ if ( Data == 0x56) {
+ bShifted = Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+ if ( Kbd->ScannerState == KBST_E0) bShifted = 0; // Check for '/' in Keypad. Otherwise '?' will be sent
+ bUpperCase = bShifted; // for not-a-letter Caps-Lock must not work
+ if (bUpperCase) {
+ Kbd->KeyData.Key.UnicodeChar = '|'; // UPPER CASE TABLE
+ }
+ else {
+ Kbd->KeyData.Key.UnicodeChar = '\\'; // lower case
+ }
+ Kbd->KeyData.EfiKey = EfiKeyB0;
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+
+ //
+ // Process keypad keys. Exceptional cases: -, + on keypad
+ // Keypad numbers when NUMLOCK only is ON OR Shift only is pressed.
+ if (Kbd->ScannerState != KBST_E0) {
+ if ((Data > 0x46) && (Data < 0x54) && !long_sequence) {
+ if (((Kbd->KeyData.KeyState.KeyToggleState & NUM_LOCK_ACTIVE) // Only NUMLOCK in ON
+ && ((Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) == 0))
+ || (((Kbd->KeyData.KeyState.KeyToggleState & NUM_LOCK_ACTIVE) == 0) // Only shift key is pressed
+ && (Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)))
+ || Data == 0x4a || Data ==0x4e) // check for -, + keys in keypad
+ {
+ Kbd->KeyData.Key.UnicodeChar = KeyPad_Table[Data-0x47];
+ Kbd->KeyData.EfiKey = KeyPadEfiCode_Table[Data-0x47];
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+ }
+ }
+ //
+ // Process F-keys
+ //
+ for (extkey = ScanCode_Table; extkey->makecode != 0xFF; extkey++) {
+ if (Data == extkey->makecode) {
+ Kbd->KeyData.Key.ScanCode = extkey->efi_scancode;
+ Kbd->KeyData.EfiKey = extkey->efi_key;
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LEDsOnOff
+//
+// Description: Turns keyboard LEDs on and off.
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void LEDsOnOff (
+ KEYBOARD* Kbd )
+{
+
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+
+ if (InsidePS2DataDispatcher) return;
+ InsidePS2DataDispatcher = TRUE;
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport){
+ if(gKeyboardIrqInstall && KBDEnableState){
+ if (bIndicators != Kbd->Indicators){
+ //
+ // Turn on/off the lights
+ //
+ Kbd->CommandResponded = NULL;
+ //
+ // Issue Keyboard LED Command 0xED
+ //
+ CheckIssueLEDCmd(Kbd);
+ if(Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ //
+ // LED command "ED" has been issues. Process the Data here itself.
+ //
+ UINT32 Counter;
+ for (Counter = 1000; Counter > 0; Counter--) {
+ //
+ // The Interrupt handler will handle the response
+ // and set the Kbd->LEDCommandState to zero in both
+ // case with or without error. Exit once the response is
+ // handled.
+ //
+ if(Kbd->LEDCommandState == 0) {
+ break;
+ }
+ gSysTable->BootServices->Stall(1000);
+
+ }
+ }
+ }
+ Kbd->LEDCommandState = NULL;
+ InsidePS2DataDispatcher = FALSE;
+ return;
+ }
+ }
+
+
+ if (bIndicators != Kbd->Indicators) {
+ //
+ // Issue Keyboard LED Command 0xED
+ //
+ CheckIssueLEDCmd(Kbd);
+
+ //
+ //Process the led command and data
+ //
+ ProcessLEDCommandData(Kbd);
+ }
+
+ InsidePS2DataDispatcher = FALSE;
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetKeyFromBuffer
+//
+// Description: Gets the next key from the circular buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// EFI_INPUT_KEY *key - Pointer to input key data
+//
+// Output: EFI_SUCCESS - key.ScanCode and key.UnicodeChar updated
+// EFI_NOT_READY - no key in buffer
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetKeyFromBuffer (
+ KEYBOARD *Kbd,
+ VOID *Key,
+ UINT8 KeySize
+)
+{
+ AMI_EFI_KEY_DATA TempKey;
+
+ if (Kbd->pBufHead == Kbd->pBufTail) return EFI_NOT_READY;
+
+ pBS->CopyMem(&TempKey, Kbd->pBufHead, sizeof(AMI_EFI_KEY_DATA));
+
+
+ TempKey.EfiKeyIsValid = 1;
+ TempKey.PS2ScanCodeIsValid = 1;
+
+ ProcessMultiLanguage(&TempKey);
+
+ if (TempKey.Key.UnicodeChar != 0) {
+ TempKey.KeyState.KeyShiftState &= ~(RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+ }
+
+ pBS->CopyMem(Key, &TempKey, KeySize);
+
+ Kbd->pBufHead++;
+ if (Kbd->pBufHead >= Kbd->pBufEnd) Kbd->pBufHead = Kbd->pBufStart; // Point to the beginning
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InsertKeyToBuffer
+//
+// Description: Insert the key into the circular buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// AMI_EFI_INPUT_KEY key - input key data
+//
+// Output: EFI_SUCCESS - Key placed in buffer
+// EFI_WARN_BUFFER_TOO_SMALL - Buffer to small
+//
+// Notes: If buffer is full, the EFI_WARN_BUFFER_TOO_SMALL.
+// Tail points to the new Data.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InsertKeyToBuffer (
+ KEYBOARD *Kbd,
+ AMI_EFI_KEY_DATA *Key
+)
+{
+ AMI_EFI_KEY_DATA *Temp = Kbd->pBufTail;
+
+ CheckKeyNotify(Key);
+ if (Kbd->pBufTail != Kbd->pBufHead) { // Check if space available
+ Temp++;
+ if (Temp >= Kbd->pBufEnd) Temp = Kbd->pBufStart;
+ if (Kbd->pBufHead == Temp) return EFI_WARN_BUFFER_TOO_SMALL; // No more space
+ }
+
+ *Kbd->pBufTail = *Key;
+ Kbd->pBufTail++;
+
+ if (Kbd->pBufTail >= Kbd->pBufEnd) Kbd->pBufTail = Kbd->pBufStart;
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckKeyinBuffer
+//
+// Description: Checks if any key is present in the buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+//
+// Output: BOOLEAN - TRUE if a key is in the buffer, FALSE otherwise.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+CheckKeyinBuffer (
+ KEYBOARD* Kbd
+)
+{
+ if (Kbd->pBufHead == Kbd->pBufTail) return FALSE;
+ return TRUE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckPartialKey
+//
+// Description: Gets the next key from the circular buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// EFI_INPUT_KEY *key - Pointer to input key data
+//
+// Output: EFI_SUCCESS - Partial Key Found
+// EFI_NOT_READY - no key in buffer
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CheckPartialKey (
+ KEYBOARD *Kbd,
+ EFI_KEY_DATA *Key
+)
+{
+
+ if (Kbd->KeyData.Key.ScanCode == 0 && Kbd->KeyData.Key.UnicodeChar == 0) {
+ //
+ // If the Key ShiftState has valid key, report as Partial Key
+ //
+ if ((Kbd->KeyData.KeyState.KeyShiftState & ~SHIFT_STATE_VALID) != 0) {
+
+ pBS->CopyMem(Key, &Kbd->KeyData, sizeof(EFI_KEY_DATA));
+ Key->KeyState.KeyToggleState |= KEY_STATE_EXPOSED;
+ CheckKeyNotify((AMI_EFI_KEY_DATA*)Key);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_READY;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: KeyboardInterruptHandler
+//
+// Description: An interrupt handler for keyboard IRQ.
+//
+//
+// Input: InterruptType Interrupt type
+// SystemContext System context
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID KeyboardInterruptHandler(
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+)
+{
+ KEYBOARD_IRQ_STORE* KbIrqBuffer = &gKeyboardIrqBuffer;
+ KEYBOARD *Kbd = &gKbd;
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+ UINT8 Data = IoRead8(KBC_DATA_PORT);
+
+ gCpuArch->DisableInterrupt(gCpuArch);
+
+ //
+ // Stored received acknowledgement
+ //
+ switch (Data) {
+ case 0xFA:
+ Kbd->CommandResponded = KB_ACK_COM;
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ Kbd->LEDCommandState = ED_DATA_ISSUED;
+ Kbd->Indicators = bIndicators;
+ WriteKeyboardData(bIndicators);
+ break;
+ }
+
+ if (Kbd->LEDCommandState == ED_DATA_ISSUED) {
+ Kbd->LEDCommandState = 0;
+ break;
+ }
+
+ break;
+ case 0xFE:
+ Kbd->CommandResponded = KB_RSND_COM;
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED || Kbd->LEDCommandState == ED_DATA_ISSUED) {
+// Error occured. Clear out the current indicator bits.
+// Modifiers will have the correct bits that needs to be set.
+// Next Call to CheckIssueLEDCmd will detect the mismatch
+// and start the LED sequence.
+ WriteKeyboardData(0xF4);
+ Kbd->LEDCommandState = 0;
+ Kbd->KeyData.KeyState.KeyToggleState &=
+ ~(SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE);
+ Kbd->Indicators &= 0xf0;
+ }
+ break;
+ case 0xFF:
+ Kbd->CommandResponded = KB_RSND_COM;
+ Kbd->LEDCommandState = 0;
+ break;
+ default:
+ //
+ // If key has been pressed before keyboard start then data will be saved in local buffer
+ // else data will be processed
+ //
+ if(!gKeyboardDriverStart){
+ if (KbIrqBuffer->KbdIndex < BUFFER_SIZE){
+ KbIrqBuffer->KbdBuffer[KbIrqBuffer->KbdIndex]=Data;
+ KbIrqBuffer->KbdIndex++;
+ }
+ }
+ else {
+ ProcessKBDData (Kbd, Data);
+ }
+ break;
+ }
+
+ //
+ // End of interrupt command sent
+ //
+ mLegacy8259->EndOfInterrupt(mLegacy8259, SYSTEM_KEYBOARD_IRQ);
+ gCpuArch->EnableInterrupt(gCpuArch);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitKeyboardIrq
+//
+// Description: To initialize keyboard interrupt, register keyboard
+// handler, and enable the keyboard interrupt
+//
+// Input:
+//
+// Paremeters:
+//
+// Output: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID InitKeyboardIrq(VOID)
+{
+
+ EFI_STATUS Status;
+ KEYBOARD_IRQ_STORE* KbIrqBuffer = &gKeyboardIrqBuffer;
+ EFI_GUID gEfiLegacy8259ProtocolGuid = EFI_LEGACY_8259_PROTOCOL_GUID;
+ EFI_GUID gEfiCpuArchProtocolGuid = EFI_CPU_ARCH_PROTOCOL_GUID;
+ UINT32 KeyboardVector = NULL;
+
+ if (!gKeyboardIrqInstall){
+ Status = pBS->LocateProtocol(&gEfiLegacy8259ProtocolGuid, NULL, &mLegacy8259);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ // Find the CPU Arch Protocol
+ Status = pBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, &gCpuArch);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ //
+ // Get keyboard Interrupt vector
+ //
+ Status = mLegacy8259->GetVector(mLegacy8259, SYSTEM_KEYBOARD_IRQ, (UINT8 *) & KeyboardVector);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ //
+ // Register interrupt handler for keyboard
+ //
+ Status = gCpuArch->RegisterInterruptHandler(gCpuArch, KeyboardVector, KeyboardInterruptHandler);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ KbIrqBuffer->KbdIndex=0;
+ gKeyboardIrqInstall = TRUE;
+
+ //
+ // Now enable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+ return;
+}
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+// <AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ClearOBF
+//
+// Description:
+// Clears any pending keys in Ps2 Output Buffer.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: This OBF clear is done since some PS2 KBC has pending keys even
+// after resetting the Keyboard.
+//---------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID
+ClearOBF(
+VOID
+)
+{
+ UINT8 bData;
+ UINT8 Counter=200;
+
+ pBS->Stall(10*1000);
+
+ while( IoRead8(KBC_CMDSTS_PORT) & KBC_OBF )
+ {
+ bData = IoRead8(KBC_DATA_PORT);
+ //
+ // wait 10 ms for KBC OBF output.
+ //
+ pBS->Stall(10*1000);
+ Counter--;
+ //
+ // If still keys are present after 2 sec. exit from the loop.
+ //
+ if(Counter==NULL) {
+ break;
+ }
+ }
+ return;
+}
+
+// <AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Ps2KbdReset
+//
+// Description:
+// Reset the Ps2 Keyboard by sending disabling and Enabling scanning.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID
+Ps2KbdReset(
+VOID
+)
+{
+ EFI_STATUS Status;
+ UINT8 bCount, bData, bBCount;
+
+ //
+ // Disable and enable keyboard to reset.
+ //
+ DisableKeyboard();
+
+ for (bBCount = 0; bBCount < 4; bBCount++) {
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_DISABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_ENABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ EnableKeyboard();
+ return;
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessLEDCommandData
+//
+// Description: Process the LED command and data.
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessLEDCommandData(
+ KEYBOARD* Kbd )
+{
+
+ UINT32 Counter;
+ UINT8 data;
+
+ if(Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ //
+ // LED command "ED" has been issued. Disable the keyboard and
+ // Process the Data here itself.
+ //
+
+ DisableKeyboard();
+
+ for (Counter = 1000; Counter > 0; Counter--) {
+ for(data = IoRead8(KBC_CMDSTS_PORT); data & KBC_OBF; data = IoRead8(KBC_CMDSTS_PORT)) {
+ if (!(data & KBC_AUX_OBF)) {
+ //
+ // Handle the Command or Data Status
+ //
+ DrivePS2KbdMachine(NULL);
+ }
+ }
+
+ //
+ // If the command and data is processed with or without error, exit here.
+ //
+ if(Kbd->LEDCommandState == 0) {
+ return;
+ }
+ gSysTable->BootServices->Stall(1000);
+ }
+ EnableKeyboard();
+ }
+ return;
+}
+
+//<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(gPs2MultiLangSupportProtocol == NULL) {
+ Status= pBS->LocateProtocol (
+ &gAmiMultiLangSupportGuid,
+ NULL,
+ &gPs2MultiLangSupportProtocol
+ );
+ if(EFI_ERROR(Status)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+ Status = gPs2MultiLangSupportProtocol->KeyboardLayoutMap(gPs2MultiLangSupportProtocol,KeyData);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2main.c b/Core/EM/PS2CTL/ps2main.c
new file mode 100644
index 0000000..d760970
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2main.c
@@ -0,0 +1,655 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2main.c 22 11/07/12 12:23a Srikantakumarp $
+//
+// $Revision: 22 $
+//
+// $Date: 11/07/12 12:23a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2main.c $
+//
+// 22 11/07/12 12:23a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 21 2/01/12 2:02a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 20 12/15/11 5:42p Artems
+// Fixed bug in Supported function
+//
+// 19 11/03/11 5:58a Rajeshms
+// [TAG] EIP73263
+// [Category] Improvement
+// [Description] PS2Ctl Driver Follow the UEFI Driver Model as per the
+// UEFI Spec.
+// [Files] ps2main.c, efismplpp.c
+//
+// 18 8/02/11 4:43a Rameshr
+// [TAG] - EIP 58974
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Yellow exclamation mark in Windows when PS2 KB/MS are not
+// present.
+// [RootCause]- ACPI name space variable reports that PS2 device present
+// [Solution] - Updated the SIO device status based on the device present
+// after BDS.
+// [Files] - Kbc.c, Kbc.h , Ps2main.c
+//
+// 17 4/27/11 4:35a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 16 1/24/11 3:45p Pats
+// [TAG] - EIP 18488
+// [Category] - Enhancement
+// [Severity] - Normal
+// [Symptom] - PS2CTL: Need hooks for port swap, Keybaord mouse detect.
+// [RootCause] - Support may be needed for kbc controller or SIO with
+// different support from AMI KB-5.
+// [Solution] - Changes to make AutodetectKbdMousePortsPtr elink
+// controlled instead of token controlled.
+// [Files] - ps2main.c
+// NOTE: Implementation of this change requires changes to CORE_DXE.sdl
+// and BdsBoard.c.
+//
+// 15 1/05/11 12:43a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 14 8/28/09 10:03a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 13 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 12 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 11 4/10/07 10:04a Felixp
+// LookupHID routine renamed to LookupPs2Hid to avoid linking issue when
+// linking with FloppyCtrl module
+//
+// 10 3/19/07 2:28p Pats
+// Removed test for KBC acrive.
+//
+// 9 3/13/07 5:36p Pats
+// Fixed problem in last BAT fix.
+//
+// 8 3/13/07 2:59p Pats
+// Tests for KBC active and skips KBC BAT test if it is. This preserves
+// the input key if there is one.
+//
+// 7 2/28/07 6:05p Pats
+// Made KBC BAT test removable with SDL token, to speed up boot, and to
+// keep keep Setup key (F2 or Del) from being absorbed.
+//
+// 6 3/13/06 2:38a Felixp
+//
+// 5 10/11/05 4:11p Srinin
+// KBD and Mouse Start function is called in TPL_NOTIFY state.
+//
+// 4 6/03/05 5:35p Felixp
+//
+// 2 2/25/05 10:27a Olegi
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 4 1/31/05 3:12p Felixp
+// Driver Binding Installed on a new handle.
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 1/07/05 4:57p Felixp
+// Small bug fix in ComponentName Protocol (GetPS2_DP modified)
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 9 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 8 9/24/04 4:36p Olegi
+//
+// 7 9/21/04 5:53p Olegi
+//
+// 6 8/27/04 3:17p Olegi
+// Header and footer added.
+//
+// 5 8/18/04 6:44p Olegi
+// Logitech mouse PNPID added.
+//
+// 4 8/18/04 6:37p Olegi
+// Header and footer added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2main.c
+//
+// Description: PS/2 Controller DXE driver
+// This driver supports PS/2 keyboard and/or PS/2 mouse depending on the
+// switches in SDL tokens.
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "efi.h"
+#include "ps2ctl.h"
+#include "kbc.h"
+#include <Protocol\ComponentName.h>
+
+//----------------------------------------------------------------------
+
+#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \
+ {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93}
+
+EFI_GUID gBdsAllDriversConnectedProtocolGuid = BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID;
+
+static EFI_GUID gDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#else
+static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+#endif
+EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+UINT8 gDriverStartCounter;
+
+VOID *gAllDriverConnectedNotifyRegistration;
+EFI_EVENT gAllDriverConnectedEvent;
+
+extern BOOLEAN Ps2MouseSupport;
+extern BOOLEAN Ps2KbdSupport;
+extern BOOLEAN KbcBasicAssuranceTest;
+extern EFI_COMPONENT_NAME_PROTOCOL gPS2CtlDriverName;
+extern EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+extern BOOLEAN KbRdBeforeInstall;
+extern BOOLEAN KbdIrqSupport;
+EFI_SYSTEM_TABLE *gSysTable = NULL;
+extern UINT8 gKeyboardIrqInstall;
+extern UINT32 IbFreeTimeoutValue;
+
+
+
+//==================================================================================
+// Function Prototypes for Driver Binding Protocol Interface
+//==================================================================================
+EFI_STATUS PS2CtlSupported(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS PS2CtlStart(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS PS2CtlStop(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *ChildHandleBuffer);
+
+//==================================================================================
+// Driver binding protocol instance for PS2Ctl Driver
+//==================================================================================
+EFI_DRIVER_BINDING_PROTOCOL gPS2CtlDriverBinding = {
+ PS2CtlSupported,
+ PS2CtlStart,
+ PS2CtlStop,
+ PS2_DRIVER_VER, // Driver version
+ NULL, // Image Handle
+ NULL // DriverBindingHandle
+};
+
+//==================================================================================
+// Supported PS2 devices table
+//==================================================================================
+CHAR16 *gPS2ControllerName = L"PS/2 Controller";
+
+PS2DEV_TABLE supportedDevices[] = {
+ {EISA_PNP_ID(0xF03), 0, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"Microsoft PS/2 Mouse"},
+ {EISA_PNP_ID(0xF12), 0, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"Logitech PS/2 Mouse"},
+ {EISA_PNP_ID(0xF13), 0, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"Generic PS/2 Mouse"},
+ {EISA_PNP_ID(0x303), 1, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"IBM Keyboard, PS/2 Mouse Support"},
+ {EISA_PNP_ID(0x303), 0, DEVICETYPE_KEYBOARD, StartKeyboard, StopKeyboard, L"Generic PS/2 Keyboard"},
+ {0} // End of table
+};
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlEntryPoint
+//
+// Description: PS/2 Controller Driver Entry Point
+// This function is a part of DriverBinfing protocol
+//
+// Parameters: EFI_HANDLE ImageHandle - Image handle for this driver
+// image
+// EFI_SYSTEM_TABLE *SystemTable - pointer to the EFI
+// system table
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlEntryPoint(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ gSysTable = SystemTable;
+ gPS2CtlDriverBinding.DriverBindingHandle = NULL;
+ gPS2CtlDriverBinding.ImageHandle = ImageHandle;
+
+ Status = gSysTable->BootServices->InstallMultipleProtocolInterfaces(
+ &gPS2CtlDriverBinding.DriverBindingHandle,
+ &gDriverBindingProtocolGuid, &gPS2CtlDriverBinding,
+ &gComponentNameProtocolGuid, &gPS2CtlDriverName,
+ NULL);
+
+ gDriverStartCounter = 0;
+
+ //
+ // Update the SIO variable in the ACPI name space depend on the
+ // Ps2keyboard and Mouse Present state.
+ //
+ Status = RegisterProtocolCallback(
+ &gBdsAllDriversConnectedProtocolGuid,
+ UpdateSioVariableForKeyboardMouse,
+ NULL,
+ &gAllDriverConnectedEvent,
+ &gAllDriverConnectedNotifyRegistration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Initialized Keyboard irq if keys are to be read before starting driver
+ // IRQ handler will save the data in temp buffer and once the Keyboard
+ // Driver started , the temp buffer data is pushed into Keyboard driver.
+ // So that the key's are pressed in post also taken by Ps2 driver
+ //
+ if(KbRdBeforeInstall){
+ if(IoRead8(KBC_CMDSTS_PORT) != 0xFF) {
+ //
+ // Enable the Keyboard and Keyboard Interrupt
+ //
+ Write8042CommandByte(0x65);
+ InitKeyboardIrq();
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlSupported
+//
+// Description: PS/2 Controller Driver Supported function
+// This function is a part of DriverBinfing protocol
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// EFI_DEVICE_PATH_PROTOCOL - *RemainingDevicePath -
+// Pointer to last node in device path
+//
+// Output: EFI_SUCCESS - Ps2 Controller supported
+// EFI_UNSUPPORTED -- Ps2 Controller not supported
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlSupported(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{
+ ACPI_HID_DEVICE_PATH* acpiDP;
+
+ //
+ // Checking if KBC is available at all
+ //
+ if (IoRead8 (KBC_CMDSTS_PORT) == 0xFF){
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Find the last device node in the device path and return "Supported"
+ // for mouse and/or keyboard depending on the SDL switches.
+ //
+ if( !EFI_ERROR(GetPS2_DP(This, Controller, &acpiDP, EFI_OPEN_PROTOCOL_BY_DRIVER)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, 0)){
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlStart
+//
+// Description: PS/2 Controller Driver Start function
+// This function is a part of DriverBinfing protocol
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// EFI_DEVICE_PATH_PROTOCOL - *RemainingDevicePath -
+// Pointer to last node in device path
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlStart(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ PS2DEV_TABLE *ps2dev = 0;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ //
+ // The following code performs the basic KBC initialization
+ // It has to be executed only once, we use global variable
+ // gDriverStartCounter to control this. Also, this code is
+ // executed on a higher TPL to prevent re-entrance.
+ //
+ OldTpl = gSysTable->BootServices->RaiseTPL(TPL_NOTIFY);
+ if (OldTpl > TPL_NOTIFY) return EFI_DEVICE_ERROR;
+
+ while (!gDriverStartCounter) {
+ //
+ // Disable the Keyboard IRQ if it's enabled before
+ // Finish all the Keyboard Initilization and Re-enable the IRQ again
+ //
+ if(KbRdBeforeInstall){
+ mLegacy8259->DisableIrq( mLegacy8259, SYSTEM_KEYBOARD_IRQ );
+ gKeyboardIrqInstall=FALSE;
+ }
+ // Initialize KBC hardware
+ //
+ if ( KbcBasicAssuranceTest ) {
+ Status = KBCBatTest(); // Perform KBC Basic Assurance Test
+ if (EFI_ERROR(Status)) {
+ //
+ // Report the Error code if the BAT test failed
+ //
+ ERROR_CODE (DXE_KEYBOARD_STUCK_KEY_ERROR, EFI_ERROR_MAJOR);
+ break;
+ }
+
+ //
+ // Check for stuck keys
+ //
+ Status = IbFreeTimeout(IbFreeTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ //
+ // Report the Error Code.
+ //
+ ERROR_CODE (DXE_KEYBOARD_STUCK_KEY_ERROR, EFI_ERROR_MAJOR);
+ break;
+ }
+ }
+ // Swap ports if needed
+ if (AutodetectKbdMousePortsPtr!=NULL) AutodetectKbdMousePortsPtr();
+
+ gDriverStartCounter++;
+ }
+
+
+ if(!EFI_ERROR(GetPS2_DP(This, Controller, &acpiDP, EFI_OPEN_PROTOCOL_BY_DRIVER)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, &ps2dev) ){
+ Status = ps2dev->start(This, Controller);
+
+ //
+ // End of critical section - restore TPL
+ //
+ gSysTable->BootServices->RestoreTPL(OldTpl);
+
+ if(EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // End of critical section - restore TPL
+ //
+ gSysTable->BootServices->RestoreTPL(OldTpl);
+
+ //
+ // If control is here then something totally wrong happend:
+ // if device is not supported then Start shouldn't be called.
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlStop
+//
+// Description: PS/2 Controller Driver Stop function
+// This function is a part of DriverBinfing protocol
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// UINTN NumberOfChildren - Number of children of this
+// controller
+// EFI_HANDLE *ChildHandleBuffer - Pointer to a buffer
+// for child handles
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlStop(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *ChildHandleBuffer)
+{
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ PS2DEV_TABLE *ps2dev = 0;
+ EFI_STATUS Status;
+
+ if(!EFI_ERROR(GetPS2_DP(This, Controller, &acpiDP, EFI_OPEN_PROTOCOL_GET_PROTOCOL)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, &ps2dev) ){
+ Status = ps2dev->stop(This, Controller);
+ if(EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If control is here then device path was not found in the lookup table
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LookupPs2Hid
+//
+// Description: This fuction searches the PS2 device in table that
+// matches given HID and UID
+//
+// Paremeters:
+// PS2DEV_TABLE * devTable - Lookup table pointer
+// UINT32 hid - HID to look for
+// UINT32 uid - UID to look for
+// PS2DEV_TABLE** dev - address of the matched table entry
+//
+// Output:
+// BOOLEAN - TRUE if match is found, FALSE otherwise
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN LookupPs2Hid(
+ PS2DEV_TABLE * devTable,
+ UINT32 hid,
+ UINT32 uid,
+ PS2DEV_TABLE** dev)
+{
+ for( ;devTable->hid;++devTable){
+ if( devTable->hid == hid && devTable->uid==uid){
+ if ( (devTable->DeviceType == DEVICETYPE_MOUSE && Ps2MouseSupport) ||
+ (devTable->DeviceType == DEVICETYPE_KEYBOARD && Ps2KbdSupport) ) {
+ if(dev) *dev = devTable;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetPS2_DP
+//
+// Description: This fuction returns the last node in the device
+// path for the given controller.
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// ACPI_HID_DEVICE_PATH** ps2dp - Pointer to ACPI HID
+// device path
+// UINT32 Attributes - Attributes passed to driver binding
+// protocol
+//
+// Output:
+// EFI_SUCCESS or EFI_UNSUPPORTED
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetPS2_DP(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ ACPI_HID_DEVICE_PATH** ps2dp,
+ UINT32 Attributes)
+{
+ EFI_STATUS Status;
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ EFI_DEVICE_PATH_PROTOCOL * ps2DevPath, *pDP;
+
+ //
+ // Get device path from Controller handle.
+ //
+ Status = gSysTable->BootServices->OpenProtocol (
+ Controller,
+ &gDevicePathProtocolGuid,
+ (VOID**)&pDP,
+ This->DriverBindingHandle,
+ Controller,
+ Attributes
+ );
+
+ if (EFI_ERROR(Status)) {
+ if( Status != (EFI_ALREADY_STARTED || EFI_ACCESS_DENIED) ) {
+ return EFI_UNSUPPORTED;
+ } else {
+ return Status;
+ }
+ }
+
+ //
+ // Process ps2DevPath - get the node which is before the EndNode
+ //
+ ps2DevPath=DPGetLastNode(pDP);
+
+ //
+ // ps2DevPath is now the last node
+ //
+ acpiDP = *ps2dp = (ACPI_HID_DEVICE_PATH*)ps2DevPath;
+
+ Status = (acpiDP->Header.Type == ACPI_DEVICE_PATH &&
+ acpiDP->Header.SubType == ACPI_DP)? EFI_SUCCESS : EFI_UNSUPPORTED;
+
+ if (Attributes!=EFI_OPEN_PROTOCOL_GET_PROTOCOL)
+ gSysTable->BootServices->CloseProtocol (
+ Controller,
+ &gDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2mouse.h b/Core/EM/PS2CTL/ps2mouse.h
new file mode 100644
index 0000000..24fbcce
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2mouse.h
@@ -0,0 +1,178 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2mouse.h 6 9/19/11 9:37a Lavanyap $
+//
+// $Revision: 6 $
+//
+// $Date: 9/19/11 9:37a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2mouse.h $
+//
+// 6 9/19/11 9:37a Lavanyap
+// [TAG] EIP66198
+// [Category] Improvement
+// [Description] Added Mouse Wheel support in PS2 and USB drivers.
+// [Files] usbdef.h, usbms.c, efiusbms.c, ps2mouse.h, mouse.c
+//
+// 5 8/23/10 4:25a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.h
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 4 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 3 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 2 3/04/05 1:39p Mandal
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2mouse.h
+//
+// Description: Ps2 mouse support header
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include <Protocol\SimplePointer.h>
+
+typedef struct {
+ EFI_SIMPLE_POINTER_PROTOCOL iSmplPtr;
+ EFI_SIMPLE_POINTER_MODE mode;
+ EFI_SIMPLE_POINTER_STATE state;
+ UINT8 saved_flags;
+} MOUSE;
+
+
+EFI_STATUS MouseReset(
+ MOUSE *This,
+ BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS MouseGetState(
+ MOUSE *This,
+ EFI_SIMPLE_POINTER_STATE *State
+);
+
+EFI_STATUS DetectPS2mouse(
+ MOUSE*
+);
+
+VOID OnWaitingOnMouse(
+ EFI_EVENT Event,
+ MOUSE *Context
+);
+
+EFI_STATUS InitMOUSE(
+ MOUSE**
+);
+
+#define KBC_CMD_ENABLE_AUX 0x0A8
+#define KBC_CMD_DISABLE_AUX 0x0A7
+#define KBC_CMD_ENABLE_KBD 0x0AE
+#define KBC_CMD_DISABLE_KBD 0x0AD
+#define KBC_CMD_CHK_AUX 0x0A9
+#define KBC_CMD_WRT_AUX 0x0D4
+
+
+//----------------------------------------------------------------------------
+// MOUSE COMMANDS from SYSTEM SET SAMPLING RATE & SET RESOLUTION
+// Needs one more byte to be sent.
+//----------------------------------------------------------------------------
+
+#define RESET 0x0FF // Reset.
+#define DISABLE 0x0F5 // Disable.
+#define ENABLE 0x0F4 // Enable.
+#define SET_SAMPLING_RATE 0x0F3 // Set sampling rate.
+#define READ_DEVICE_TYPE 0x0F2 // Read device type.
+#define STATUS_REQUEST 0x0E9 // Status request.
+#define SET_RESOLUTION 0x0E8 // Set resolution.
+#define SET_SCALING_2X1 0x0E7 // Set scaling 2:1.
+#define RESET_SCALING 0x0E6 // Set scaling 1:1.
+#define REMOTE_MODE 0x0F0 // Set Remote Mode - mouse transfers
+ // packets by request
+#define READ_DATA 0x0eb // Forces thetransef of a mouse data packet
+#define SET_STANDART 0x0f6 // Iitialize PS/2 and set standart state
+//---------------------------------------
+// MOUSE RESPONSE ON COMMAND COMPLETION
+//---------------------------------------
+
+#define ACK 0x0fa // ACKnowledge
+#define RSND 0x0fe // RESEND
+#define ERROR 0x0fc // two invalid inputs received
+
+//---------------------------------------
+// CCB Flags
+//---------------------------------------
+
+#define CCB_PCCOMPAT 0x40 // PC Compatibility mode
+#define CCB_PS2MS_DISABLE 0x20 // Disable PS/2 mouse interface
+#define CCB_KBD_DISABLE 0x10 // Disable in succession by mouse
+#define CCB_SYSTEM 0x04 //
+#define CCB_MS_INTRPT 0x02 //
+#define CCB_KBD_INTRPT 0x01 //
+
+
+typedef struct {
+ UINT8 flags;
+ UINT8 x,y,z;
+} StdMouseDataPacket;
+
+#define BUTTON_MID 0x04
+#define BUTTON_RIGHT 0x02
+#define BUTTON_LEFT 0x01
+#define MOUSE_X_NEG 0x10
+#define MOUSE_Y_NEG 0x20
+#define MOUSE_X_OVF 0x40
+#define MOUSE_Y_OVF 0x80
+
+#define NON_WHEEL_REPORT_FORMAT 3
+#define WHEEL_REPORT_FORMAT 4
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************