summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe
diff options
context:
space:
mode:
authorkx <kx@radix.pro>2024-06-04 06:43:08 +0300
committerkx <kx@radix.pro>2024-06-04 06:43:08 +0300
commit7e2ccccace24636f29ddc210b94606abd4c7e42b (patch)
tree545d43ea12671048956cafeb12303e84d601e571 /MdeModulePkg/Bus/Isa/Ps2KeyboardDxe
parent27b044605cd5f6b33a3d231576003850b3fe305b (diff)
downloadedk2-trunk.tar.xz
Renormalized end-of-lines from master@27b044605cd5f6b33a3d231576003850b3fe305btrunk
Diffstat (limited to 'MdeModulePkg/Bus/Isa/Ps2KeyboardDxe')
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/ComponentName.c692
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c3760
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c1492
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c1350
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h1130
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf156
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.uni34
-rw-r--r--MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxeExtra.uni28
8 files changed, 4321 insertions, 4321 deletions
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/ComponentName.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/ComponentName.c
index d36e2becd6..0970d22d47 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/ComponentName.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/ComponentName.c
@@ -1,346 +1,346 @@
-/** @file
- Routines related Component Name protocol.
-
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ps2Keyboard.h"
-
-//
-// EFI Component Name Functions
-//
-
-/**
- Retrieves a Unicode string that is the user readable name of the driver.
-
- This function retrieves the user readable name of a driver in the form of a
- Unicode string. If the driver specified by This has a user readable name in
- the language specified by Language, then a pointer to the driver name is
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
- by This does not support the language specified by Language,
- then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified
- in RFC 4646 or ISO 639-2 language code format.
-
- @param DriverName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- driver specified by This in the language
- specified by Language.
-
- @retval EFI_SUCCESS The Unicode string for the Driver specified by
- This and the language specified by Language was
- returned in DriverName.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER DriverName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-Ps2KeyboardComponentNameGetDriverName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN CHAR8 *Language,
- OUT CHAR16 **DriverName
- );
-
-/**
- Retrieves a Unicode string that is the user readable name of the controller
- that is being managed by a driver.
-
- This function retrieves the user readable name of the controller specified by
- ControllerHandle and ChildHandle in the form of a Unicode string. If the
- driver specified by This has a user readable name in the language specified by
- Language, then a pointer to the controller name is returned in ControllerName,
- and EFI_SUCCESS is returned. If the driver specified by This is not currently
- managing the controller specified by ControllerHandle and ChildHandle,
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not
- support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param ControllerHandle[in] The handle of a controller that the driver
- specified by This is managing. This handle
- specifies the controller whose name is to be
- returned.
-
- @param ChildHandle[in] The handle of the child controller to retrieve
- the name of. This is an optional parameter that
- may be NULL. It will be NULL for device
- drivers. It will also be NULL for a bus drivers
- that wish to retrieve the name of the bus
- controller. It will not be NULL for a bus
- driver that wishes to retrieve the name of a
- child controller.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified in
- RFC 4646 or ISO 639-2 language code format.
-
- @param ControllerName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- controller specified by ControllerHandle and
- ChildHandle in the language specified by
- Language from the point of view of the driver
- specified by This.
-
- @retval EFI_SUCCESS The Unicode string for the user readable name in
- the language specified by Language for the
- driver specified by This was returned in
- DriverName.
-
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
-
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
- EFI_HANDLE.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This is not currently
- managing the controller specified by
- ControllerHandle and ChildHandle.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-Ps2KeyboardComponentNameGetControllerName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE ChildHandle OPTIONAL,
- IN CHAR8 *Language,
- OUT CHAR16 **ControllerName
- );
-
-//
-// EFI Component Name Protocol
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPs2KeyboardComponentName = {
- Ps2KeyboardComponentNameGetDriverName,
- Ps2KeyboardComponentNameGetControllerName,
- "eng"
-};
-
-//
-// EFI Component Name 2 Protocol
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPs2KeyboardComponentName2 = {
- (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)Ps2KeyboardComponentNameGetDriverName,
- (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)Ps2KeyboardComponentNameGetControllerName,
- "en"
-};
-
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPs2KeyboardDriverNameTable[] = {
- {
- "eng;en",
- L"PS/2 Keyboard Driver"
- },
- {
- NULL,
- NULL
- }
-};
-
-/**
- Retrieves a Unicode string that is the user readable name of the driver.
-
- This function retrieves the user readable name of a driver in the form of a
- Unicode string. If the driver specified by This has a user readable name in
- the language specified by Language, then a pointer to the driver name is
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
- by This does not support the language specified by Language,
- then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified
- in RFC 4646 or ISO 639-2 language code format.
-
- @param DriverName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- driver specified by This in the language
- specified by Language.
-
- @retval EFI_SUCCESS The Unicode string for the Driver specified by
- This and the language specified by Language was
- returned in DriverName.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER DriverName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-Ps2KeyboardComponentNameGetDriverName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN CHAR8 *Language,
- OUT CHAR16 **DriverName
- )
-{
- return LookupUnicodeString2 (
- Language,
- This->SupportedLanguages,
- mPs2KeyboardDriverNameTable,
- DriverName,
- (BOOLEAN)(This == &gPs2KeyboardComponentName)
- );
-}
-
-/**
- Retrieves a Unicode string that is the user readable name of the controller
- that is being managed by a driver.
-
- This function retrieves the user readable name of the controller specified by
- ControllerHandle and ChildHandle in the form of a Unicode string. If the
- driver specified by This has a user readable name in the language specified by
- Language, then a pointer to the controller name is returned in ControllerName,
- and EFI_SUCCESS is returned. If the driver specified by This is not currently
- managing the controller specified by ControllerHandle and ChildHandle,
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not
- support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param ControllerHandle[in] The handle of a controller that the driver
- specified by This is managing. This handle
- specifies the controller whose name is to be
- returned.
-
- @param ChildHandle[in] The handle of the child controller to retrieve
- the name of. This is an optional parameter that
- may be NULL. It will be NULL for device
- drivers. It will also be NULL for a bus drivers
- that wish to retrieve the name of the bus
- controller. It will not be NULL for a bus
- driver that wishes to retrieve the name of a
- child controller.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified in
- RFC 4646 or ISO 639-2 language code format.
-
- @param ControllerName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- controller specified by ControllerHandle and
- ChildHandle in the language specified by
- Language from the point of view of the driver
- specified by This.
-
- @retval EFI_SUCCESS The Unicode string for the user readable name in
- the language specified by Language for the
- driver specified by This was returned in
- DriverName.
-
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
-
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
- EFI_HANDLE.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This is not currently
- managing the controller specified by
- ControllerHandle and ChildHandle.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-Ps2KeyboardComponentNameGetControllerName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE ChildHandle OPTIONAL,
- IN CHAR8 *Language,
- OUT CHAR16 **ControllerName
- )
-{
- EFI_STATUS Status;
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
-
- //
- // This is a device driver, so ChildHandle must be NULL.
- //
- if (ChildHandle != NULL) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Check Controller's handle
- //
- Status = EfiTestManagedDevice (ControllerHandle, gKeyboardControllerDriver.DriverBindingHandle, &gEfiSioProtocolGuid);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Get the device context
- //
- Status = gBS->OpenProtocol (
- ControllerHandle,
- &gEfiSimpleTextInProtocolGuid,
- (VOID **)&ConIn,
- gKeyboardControllerDriver.DriverBindingHandle,
- ControllerHandle,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
-
- return LookupUnicodeString2 (
- Language,
- This->SupportedLanguages,
- ConsoleIn->ControllerNameTable,
- ControllerName,
- (BOOLEAN)(This == &gPs2KeyboardComponentName)
- );
-}
+/** @file
+ Routines related Component Name protocol.
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ps2Keyboard.h"
+
+//
+// EFI Component Name Functions
+//
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+Ps2KeyboardComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+Ps2KeyboardComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gPs2KeyboardComponentName = {
+ Ps2KeyboardComponentNameGetDriverName,
+ Ps2KeyboardComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gPs2KeyboardComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)Ps2KeyboardComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)Ps2KeyboardComponentNameGetControllerName,
+ "en"
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mPs2KeyboardDriverNameTable[] = {
+ {
+ "eng;en",
+ L"PS/2 Keyboard Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+Ps2KeyboardComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mPs2KeyboardDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gPs2KeyboardComponentName)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+Ps2KeyboardComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check Controller's handle
+ //
+ Status = EfiTestManagedDevice (ControllerHandle, gKeyboardControllerDriver.DriverBindingHandle, &gEfiSioProtocolGuid);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get the device context
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextInProtocolGuid,
+ (VOID **)&ConIn,
+ gKeyboardControllerDriver.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ ConsoleIn->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gPs2KeyboardComponentName)
+ );
+}
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
index 981309f8b0..e9566c0c30 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdCtrller.c
@@ -1,1880 +1,1880 @@
-/** @file
- Routines that access 8042 keyboard controller
-
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ps2Keyboard.h"
-
-struct {
- UINT8 ScanCode; ///< follows value defined in Scan Code Set1
- UINT16 EfiScanCode;
- CHAR16 UnicodeChar;
- CHAR16 ShiftUnicodeChar;
-} ConvertKeyboardScanCodeToEfiKey[] = {
- {
- 0x01, // Escape
- SCAN_ESC,
- 0x0000,
- 0x0000
- },
- {
- 0x02,
- SCAN_NULL,
- L'1',
- L'!'
- },
- {
- 0x03,
- SCAN_NULL,
- L'2',
- L'@'
- },
- {
- 0x04,
- SCAN_NULL,
- L'3',
- L'#'
- },
- {
- 0x05,
- SCAN_NULL,
- L'4',
- L'$'
- },
- {
- 0x06,
- SCAN_NULL,
- L'5',
- L'%'
- },
- {
- 0x07,
- SCAN_NULL,
- L'6',
- L'^'
- },
- {
- 0x08,
- SCAN_NULL,
- L'7',
- L'&'
- },
- {
- 0x09,
- SCAN_NULL,
- L'8',
- L'*'
- },
- {
- 0x0A,
- SCAN_NULL,
- L'9',
- L'('
- },
- {
- 0x0B,
- SCAN_NULL,
- L'0',
- L')'
- },
- {
- 0x0C,
- SCAN_NULL,
- L'-',
- L'_'
- },
- {
- 0x0D,
- SCAN_NULL,
- L'=',
- L'+'
- },
- {
- 0x0E, // BackSpace
- SCAN_NULL,
- 0x0008,
- 0x0008
- },
- {
- 0x0F, // Tab
- SCAN_NULL,
- 0x0009,
- 0x0009
- },
- {
- 0x10,
- SCAN_NULL,
- L'q',
- L'Q'
- },
- {
- 0x11,
- SCAN_NULL,
- L'w',
- L'W'
- },
- {
- 0x12,
- SCAN_NULL,
- L'e',
- L'E'
- },
- {
- 0x13,
- SCAN_NULL,
- L'r',
- L'R'
- },
- {
- 0x14,
- SCAN_NULL,
- L't',
- L'T'
- },
- {
- 0x15,
- SCAN_NULL,
- L'y',
- L'Y'
- },
- {
- 0x16,
- SCAN_NULL,
- L'u',
- L'U'
- },
- {
- 0x17,
- SCAN_NULL,
- L'i',
- L'I'
- },
- {
- 0x18,
- SCAN_NULL,
- L'o',
- L'O'
- },
- {
- 0x19,
- SCAN_NULL,
- L'p',
- L'P'
- },
- {
- 0x1a,
- SCAN_NULL,
- L'[',
- L'{'
- },
- {
- 0x1b,
- SCAN_NULL,
- L']',
- L'}'
- },
- {
- 0x1c, // Enter
- SCAN_NULL,
- 0x000d,
- 0x000d
- },
- {
- 0x1d,
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x1e,
- SCAN_NULL,
- L'a',
- L'A'
- },
- {
- 0x1f,
- SCAN_NULL,
- L's',
- L'S'
- },
- {
- 0x20,
- SCAN_NULL,
- L'd',
- L'D'
- },
- {
- 0x21,
- SCAN_NULL,
- L'f',
- L'F'
- },
- {
- 0x22,
- SCAN_NULL,
- L'g',
- L'G'
- },
- {
- 0x23,
- SCAN_NULL,
- L'h',
- L'H'
- },
- {
- 0x24,
- SCAN_NULL,
- L'j',
- L'J'
- },
- {
- 0x25,
- SCAN_NULL,
- L'k',
- L'K'
- },
- {
- 0x26,
- SCAN_NULL,
- L'l',
- L'L'
- },
- {
- 0x27,
- SCAN_NULL,
- L';',
- L':'
- },
- {
- 0x28,
- SCAN_NULL,
- L'\'',
- L'"'
- },
- {
- 0x29,
- SCAN_NULL,
- L'`',
- L'~'
- },
- {
- 0x2a, // Left Shift
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x2b,
- SCAN_NULL,
- L'\\',
- L'|'
- },
- {
- 0x2c,
- SCAN_NULL,
- L'z',
- L'Z'
- },
- {
- 0x2d,
- SCAN_NULL,
- L'x',
- L'X'
- },
- {
- 0x2e,
- SCAN_NULL,
- L'c',
- L'C'
- },
- {
- 0x2f,
- SCAN_NULL,
- L'v',
- L'V'
- },
- {
- 0x30,
- SCAN_NULL,
- L'b',
- L'B'
- },
- {
- 0x31,
- SCAN_NULL,
- L'n',
- L'N'
- },
- {
- 0x32,
- SCAN_NULL,
- L'm',
- L'M'
- },
- {
- 0x33,
- SCAN_NULL,
- L',',
- L'<'
- },
- {
- 0x34,
- SCAN_NULL,
- L'.',
- L'>'
- },
- {
- 0x35,
- SCAN_NULL,
- L'/',
- L'?'
- },
- {
- 0x36, // Right Shift
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x37, // Numeric Keypad *
- SCAN_NULL,
- L'*',
- L'*'
- },
- {
- 0x38, // Left Alt/Extended Right Alt
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x39,
- SCAN_NULL,
- L' ',
- L' '
- },
- {
- 0x3A, // CapsLock
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x3B,
- SCAN_F1,
- 0x0000,
- 0x0000
- },
- {
- 0x3C,
- SCAN_F2,
- 0x0000,
- 0x0000
- },
- {
- 0x3D,
- SCAN_F3,
- 0x0000,
- 0x0000
- },
- {
- 0x3E,
- SCAN_F4,
- 0x0000,
- 0x0000
- },
- {
- 0x3F,
- SCAN_F5,
- 0x0000,
- 0x0000
- },
- {
- 0x40,
- SCAN_F6,
- 0x0000,
- 0x0000
- },
- {
- 0x41,
- SCAN_F7,
- 0x0000,
- 0x0000
- },
- {
- 0x42,
- SCAN_F8,
- 0x0000,
- 0x0000
- },
- {
- 0x43,
- SCAN_F9,
- 0x0000,
- 0x0000
- },
- {
- 0x44,
- SCAN_F10,
- 0x0000,
- 0x0000
- },
- {
- 0x45, // NumLock
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x46, // ScrollLock
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x47,
- SCAN_HOME,
- L'7',
- L'7'
- },
- {
- 0x48,
- SCAN_UP,
- L'8',
- L'8'
- },
- {
- 0x49,
- SCAN_PAGE_UP,
- L'9',
- L'9'
- },
- {
- 0x4a,
- SCAN_NULL,
- L'-',
- L'-'
- },
- {
- 0x4b,
- SCAN_LEFT,
- L'4',
- L'4'
- },
- {
- 0x4c, // Numeric Keypad 5
- SCAN_NULL,
- L'5',
- L'5'
- },
- {
- 0x4d,
- SCAN_RIGHT,
- L'6',
- L'6'
- },
- {
- 0x4e,
- SCAN_NULL,
- L'+',
- L'+'
- },
- {
- 0x4f,
- SCAN_END,
- L'1',
- L'1'
- },
- {
- 0x50,
- SCAN_DOWN,
- L'2',
- L'2'
- },
- {
- 0x51,
- SCAN_PAGE_DOWN,
- L'3',
- L'3'
- },
- {
- 0x52,
- SCAN_INSERT,
- L'0',
- L'0'
- },
- {
- 0x53,
- SCAN_DELETE,
- L'.',
- L'.'
- },
- {
- 0x57,
- SCAN_F11,
- 0x0000,
- 0x0000
- },
- {
- 0x58,
- SCAN_F12,
- 0x0000,
- 0x0000
- },
- {
- 0x5B, // Left LOGO
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x5C, // Right LOGO
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- 0x5D, // Menu key
- SCAN_NULL,
- 0x0000,
- 0x0000
- },
- {
- TABLE_END,
- TABLE_END,
- SCAN_NULL,
- SCAN_NULL
- },
-};
-
-//
-// The WaitForValue time out
-//
-UINTN mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
-
-BOOLEAN mEnableMouseInterface;
-
-/**
- Return the count of scancode in the queue.
-
- @param Queue Pointer to instance of SCAN_CODE_QUEUE.
-
- @return Count of the scancode.
-**/
-UINTN
-GetScancodeBufCount (
- IN SCAN_CODE_QUEUE *Queue
- )
-{
- if (Queue->Head <= Queue->Tail) {
- return Queue->Tail - Queue->Head;
- } else {
- return Queue->Tail + KEYBOARD_SCAN_CODE_MAX_COUNT - Queue->Head;
- }
-}
-
-/**
- Read several bytes from the scancode buffer without removing them.
- This function is called to see if there are enough bytes of scancode
- representing a single key.
-
- @param Queue Pointer to instance of SCAN_CODE_QUEUE.
- @param Count Number of bytes to be read
- @param Buf Store the results
-
- @retval EFI_SUCCESS success to scan the keyboard code
- @retval EFI_NOT_READY invalid parameter
-**/
-EFI_STATUS
-GetScancodeBufHead (
- IN SCAN_CODE_QUEUE *Queue,
- IN UINTN Count,
- OUT UINT8 *Buf
- )
-{
- UINTN Index;
- UINTN Pos;
-
- //
- // check the valid range of parameter 'Count'
- //
- if (GetScancodeBufCount (Queue) < Count) {
- return EFI_NOT_READY;
- }
-
- //
- // retrieve the values
- //
- for (Index = 0, Pos = Queue->Head; Index < Count; Index++, Pos = (Pos + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
- Buf[Index] = Queue->Buffer[Pos];
- }
-
- return EFI_SUCCESS;
-}
-
-/**
-
- Read & remove several bytes from the scancode buffer.
- This function is usually called after GetScancodeBufHead()
-
- @param Queue Pointer to instance of SCAN_CODE_QUEUE.
- @param Count Number of bytes to be read
- @param Buf Store the results
-
- @retval EFI_SUCCESS success to scan the keyboard code
- @retval EFI_NOT_READY invalid parameter
-**/
-EFI_STATUS
-PopScancodeBufHead (
- IN SCAN_CODE_QUEUE *Queue,
- IN UINTN Count,
- OUT UINT8 *Buf OPTIONAL
- )
-{
- UINTN Index;
-
- //
- // Check the valid range of parameter 'Count'
- //
- if (GetScancodeBufCount (Queue) < Count) {
- return EFI_NOT_READY;
- }
-
- //
- // Retrieve and remove the values
- //
- for (Index = 0; Index < Count; Index++, Queue->Head = (Queue->Head + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
- if (Buf != NULL) {
- Buf[Index] = Queue->Buffer[Queue->Head];
- }
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Push one byte to the scancode buffer.
-
- @param Queue Pointer to instance of SCAN_CODE_QUEUE.
- @param Scancode The byte to push.
-**/
-VOID
-PushScancodeBufTail (
- IN SCAN_CODE_QUEUE *Queue,
- IN UINT8 Scancode
- )
-{
- if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {
- PopScancodeBufHead (Queue, 1, NULL);
- }
-
- Queue->Buffer[Queue->Tail] = Scancode;
- Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;
-}
-
-/**
- Read data register .
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
-
- @return return the value
-
-**/
-UINT8
-KeyReadDataRegister (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- )
-
-{
- return IoRead8 (ConsoleIn->DataRegisterAddress);
-}
-
-/**
- Write data register.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param Data value wanted to be written
-
-**/
-VOID
-KeyWriteDataRegister (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN UINT8 Data
- )
-{
- IoWrite8 (ConsoleIn->DataRegisterAddress, Data);
-}
-
-/**
- Read status register.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
-
- @return value in status register
-
-**/
-UINT8
-KeyReadStatusRegister (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- )
-{
- return IoRead8 (ConsoleIn->StatusRegisterAddress);
-}
-
-/**
- Write command register .
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param Data The value wanted to be written
-
-**/
-VOID
-KeyWriteCommandRegister (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN UINT8 Data
- )
-{
- IoWrite8 (ConsoleIn->CommandRegisterAddress, Data);
-}
-
-/**
- Display error message.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param ErrMsg Unicode string of error message
-
-**/
-VOID
-KeyboardError (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN CHAR16 *ErrMsg
- )
-{
- ConsoleIn->KeyboardErr = TRUE;
-}
-
-/**
- Timer event handler: read a series of scancodes from 8042
- and put them into memory scancode buffer.
- it read as much scancodes to either fill
- the memory buffer or empty the keyboard buffer.
- It is registered as running under TPL_NOTIFY
-
- @param Event The timer event
- @param Context A KEYBOARD_CONSOLE_IN_DEV pointer
-
-**/
-VOID
-EFIAPI
-KeyboardTimerHandler (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-
-{
- UINT8 Data;
- EFI_TPL OldTpl;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
-
- ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;
-
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- if (((KEYBOARD_CONSOLE_IN_DEV *)Context)->KeyboardErr) {
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return;
- }
-
- //
- // To let KB driver support Hot plug, here should skip the 'resend' command for the case that
- // KB is not connected to system. If KB is not connected to system, driver will find there's something
- // error in the following code and wait for the input buffer empty, this waiting time should be short enough since
- // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.
- // Just skip the 'resend' process simply.
- //
-
- while ((KeyReadStatusRegister (ConsoleIn) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) ==
- KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA
- )
- {
- //
- // Read one byte of the scan code and store it into the memory buffer
- //
- Data = KeyReadDataRegister (ConsoleIn);
- PushScancodeBufTail (&ConsoleIn->ScancodeQueue, Data);
- }
-
- KeyGetchar (ConsoleIn);
-
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
-}
-
-/**
- Read key value .
-
- @param ConsoleIn - Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param Data - Pointer to outof buffer for keeping key value
-
- @retval EFI_TIMEOUT Status register time out
- @retval EFI_SUCCESS Success to read keyboard
-
-**/
-EFI_STATUS
-KeyboardRead (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- OUT UINT8 *Data
- )
-
-{
- UINT32 TimeOut;
- UINT32 RegFilled;
-
- TimeOut = 0;
- RegFilled = 0;
-
- //
- // wait till output buffer full then perform the read
- //
- for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
- if (KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {
- RegFilled = 1;
- *Data = KeyReadDataRegister (ConsoleIn);
- break;
- }
-
- MicroSecondDelay (30);
- }
-
- if (RegFilled == 0) {
- return EFI_TIMEOUT;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- write key to keyboard
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param Data value wanted to be written
-
- @retval EFI_TIMEOUT The input buffer register is full for putting new value util timeout
- @retval EFI_SUCCESS The new value is success put into input buffer register.
-
-**/
-EFI_STATUS
-KeyboardWrite (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN UINT8 Data
- )
-{
- UINT32 TimeOut;
- UINT32 RegEmptied;
-
- TimeOut = 0;
- RegEmptied = 0;
-
- //
- // wait for input buffer empty
- //
- for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
- if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
- RegEmptied = 1;
- break;
- }
-
- MicroSecondDelay (30);
- }
-
- if (RegEmptied == 0) {
- return EFI_TIMEOUT;
- }
-
- //
- // Write it
- //
- KeyWriteDataRegister (ConsoleIn, Data);
-
- return EFI_SUCCESS;
-}
-
-/**
- Issue keyboard command.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param Data The buff holding the command
-
- @retval EFI_TIMEOUT Keyboard is not ready to issuing
- @retval EFI_SUCCESS Success to issue keyboard command
-
-**/
-EFI_STATUS
-KeyboardCommand (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN UINT8 Data
- )
-{
- UINT32 TimeOut;
- UINT32 RegEmptied;
-
- TimeOut = 0;
- RegEmptied = 0;
-
- //
- // Wait For Input Buffer Empty
- //
- for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
- if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
- RegEmptied = 1;
- break;
- }
-
- MicroSecondDelay (30);
- }
-
- if (RegEmptied == 0) {
- return EFI_TIMEOUT;
- }
-
- //
- // issue the command
- //
- KeyWriteCommandRegister (ConsoleIn, Data);
-
- //
- // Wait For Input Buffer Empty again
- //
- RegEmptied = 0;
- for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
- if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
- RegEmptied = 1;
- break;
- }
-
- MicroSecondDelay (30);
- }
-
- if (RegEmptied == 0) {
- return EFI_TIMEOUT;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- wait for a specific value to be presented on
- 8042 Data register by keyboard and then read it,
- used in keyboard commands ack
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param Value the value wanted to be waited.
-
- @retval EFI_TIMEOUT Fail to get specific value in given time
- @retval EFI_SUCCESS Success to get specific value in given time.
-
-**/
-EFI_STATUS
-KeyboardWaitForValue (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN UINT8 Value
- )
-{
- UINT8 Data;
- UINT32 TimeOut;
- UINT32 SumTimeOut;
- UINT32 GotIt;
-
- GotIt = 0;
- TimeOut = 0;
- SumTimeOut = 0;
-
- //
- // Make sure the initial value of 'Data' is different from 'Value'
- //
- Data = 0;
- if (Data == Value) {
- Data = 1;
- }
-
- //
- // Read from 8042 (multiple times if needed)
- // until the expected value appears
- // use SumTimeOut to control the iteration
- //
- while (1) {
- //
- // Perform a read
- //
- for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
- if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
- Data = KeyReadDataRegister (ConsoleIn);
- break;
- }
-
- MicroSecondDelay (30);
- }
-
- SumTimeOut += TimeOut;
-
- if (Data == Value) {
- GotIt = 1;
- break;
- }
-
- if (SumTimeOut >= mWaitForValueTimeOut) {
- break;
- }
- }
-
- //
- // Check results
- //
- if (GotIt == 1) {
- return EFI_SUCCESS;
- } else {
- return EFI_TIMEOUT;
- }
-}
-
-/**
- Show keyboard status lights according to
- indicators in ConsoleIn.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
-
- @return status of updating keyboard register
-
-**/
-EFI_STATUS
-UpdateStatusLights (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- )
-{
- EFI_STATUS Status;
- UINT8 Command;
-
- //
- // Send keyboard command
- //
- Status = KeyboardWrite (ConsoleIn, 0xed);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- KeyboardWaitForValue (ConsoleIn, 0xfa);
-
- //
- // Light configuration
- //
- Command = 0;
- if (ConsoleIn->CapsLock) {
- Command |= 4;
- }
-
- if (ConsoleIn->NumLock) {
- Command |= 2;
- }
-
- if (ConsoleIn->ScrollLock) {
- Command |= 1;
- }
-
- Status = KeyboardWrite (ConsoleIn, Command);
-
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- KeyboardWaitForValue (ConsoleIn, 0xfa);
- return Status;
-}
-
-/**
- Initialize the key state.
-
- @param ConsoleIn The KEYBOARD_CONSOLE_IN_DEV instance.
- @param KeyState A pointer to receive the key state information.
-**/
-VOID
-InitializeKeyState (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- OUT EFI_KEY_STATE *KeyState
- )
-{
- KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID
- | (ConsoleIn->LeftCtrl ? EFI_LEFT_CONTROL_PRESSED : 0)
- | (ConsoleIn->RightCtrl ? EFI_RIGHT_CONTROL_PRESSED : 0)
- | (ConsoleIn->LeftAlt ? EFI_LEFT_ALT_PRESSED : 0)
- | (ConsoleIn->RightAlt ? EFI_RIGHT_ALT_PRESSED : 0)
- | (ConsoleIn->LeftShift ? EFI_LEFT_SHIFT_PRESSED : 0)
- | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED : 0)
- | (ConsoleIn->LeftLogo ? EFI_LEFT_LOGO_PRESSED : 0)
- | (ConsoleIn->RightLogo ? EFI_RIGHT_LOGO_PRESSED : 0)
- | (ConsoleIn->Menu ? EFI_MENU_KEY_PRESSED : 0)
- | (ConsoleIn->SysReq ? EFI_SYS_REQ_PRESSED : 0)
- ;
- KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID
- | (ConsoleIn->CapsLock ? EFI_CAPS_LOCK_ACTIVE : 0)
- | (ConsoleIn->NumLock ? EFI_NUM_LOCK_ACTIVE : 0)
- | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
- | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
- ;
-}
-
-/**
- Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
-
- The function is always called in TPL_NOTIFY.
-
- @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer
-
-**/
-VOID
-KeyGetchar (
- IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- )
-{
- EFI_STATUS Status;
- UINT16 ScanCode;
- BOOLEAN Extend0;
- BOOLEAN Extend1;
- UINTN Index;
- EFI_KEY_DATA KeyData;
- LIST_ENTRY *Link;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
- //
- // 3 bytes most
- //
- UINT8 ScancodeArr[3];
- UINT32 ScancodeArrPos;
-
- //
- // Check if there are enough bytes of scancode representing a single key
- // available in the buffer
- //
- while (TRUE) {
- Extend0 = FALSE;
- Extend1 = FALSE;
- ScancodeArrPos = 0;
- Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
- if (EFI_ERROR (Status)) {
- return;
- }
-
- if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED0) {
- //
- // E0 to look ahead 2 bytes
- //
- Extend0 = TRUE;
- ScancodeArrPos = 1;
- Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
- if (EFI_ERROR (Status)) {
- return;
- }
- } else if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {
- //
- // E1 to look ahead 3 bytes
- //
- Extend1 = TRUE;
- ScancodeArrPos = 2;
- Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
- if (EFI_ERROR (Status)) {
- return;
- }
- }
-
- //
- // if we reach this position, scancodes for a key is in buffer now,pop them
- //
- Status = PopScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
- ASSERT_EFI_ERROR (Status);
-
- //
- // store the last available byte, this byte of scancode will be checked
- //
- ScanCode = ScancodeArr[ScancodeArrPos];
-
- if (!Extend1) {
- //
- // Check for special keys and update the driver state.
- //
- switch (ScanCode) {
- case SCANCODE_CTRL_MAKE:
- if (Extend0) {
- ConsoleIn->RightCtrl = TRUE;
- } else {
- ConsoleIn->LeftCtrl = TRUE;
- }
-
- break;
- case SCANCODE_CTRL_BREAK:
- if (Extend0) {
- ConsoleIn->RightCtrl = FALSE;
- } else {
- ConsoleIn->LeftCtrl = FALSE;
- }
-
- break;
-
- case SCANCODE_ALT_MAKE:
- if (Extend0) {
- ConsoleIn->RightAlt = TRUE;
- } else {
- ConsoleIn->LeftAlt = TRUE;
- }
-
- break;
- case SCANCODE_ALT_BREAK:
- if (Extend0) {
- ConsoleIn->RightAlt = FALSE;
- } else {
- ConsoleIn->LeftAlt = FALSE;
- }
-
- break;
-
- case SCANCODE_LEFT_SHIFT_MAKE:
- //
- // To avoid recognize PRNT_SCRN key as a L_SHIFT key
- // because PRNT_SCRN key generates E0 followed by L_SHIFT scan code.
- // If it the second byte of the PRNT_ScRN skip it.
- //
- if (!Extend0) {
- ConsoleIn->LeftShift = TRUE;
- break;
- }
-
- continue;
-
- case SCANCODE_LEFT_SHIFT_BREAK:
- if (!Extend0) {
- ConsoleIn->LeftShift = FALSE;
- }
-
- break;
-
- case SCANCODE_RIGHT_SHIFT_MAKE:
- ConsoleIn->RightShift = TRUE;
- break;
- case SCANCODE_RIGHT_SHIFT_BREAK:
- ConsoleIn->RightShift = FALSE;
- break;
-
- case SCANCODE_LEFT_LOGO_MAKE:
- ConsoleIn->LeftLogo = TRUE;
- break;
- case SCANCODE_LEFT_LOGO_BREAK:
- ConsoleIn->LeftLogo = FALSE;
- break;
-
- case SCANCODE_RIGHT_LOGO_MAKE:
- ConsoleIn->RightLogo = TRUE;
- break;
- case SCANCODE_RIGHT_LOGO_BREAK:
- ConsoleIn->RightLogo = FALSE;
- break;
-
- case SCANCODE_MENU_MAKE:
- ConsoleIn->Menu = TRUE;
- break;
- case SCANCODE_MENU_BREAK:
- ConsoleIn->Menu = FALSE;
- break;
-
- case SCANCODE_SYS_REQ_MAKE:
- if (Extend0) {
- ConsoleIn->SysReq = TRUE;
- }
-
- break;
- case SCANCODE_SYS_REQ_BREAK:
- if (Extend0) {
- ConsoleIn->SysReq = FALSE;
- }
-
- break;
-
- case SCANCODE_SYS_REQ_MAKE_WITH_ALT:
- ConsoleIn->SysReq = TRUE;
- break;
- case SCANCODE_SYS_REQ_BREAK_WITH_ALT:
- ConsoleIn->SysReq = FALSE;
- break;
-
- case SCANCODE_CAPS_LOCK_MAKE:
- ConsoleIn->CapsLock = (BOOLEAN) !ConsoleIn->CapsLock;
- UpdateStatusLights (ConsoleIn);
- break;
- case SCANCODE_NUM_LOCK_MAKE:
- ConsoleIn->NumLock = (BOOLEAN) !ConsoleIn->NumLock;
- UpdateStatusLights (ConsoleIn);
- break;
- case SCANCODE_SCROLL_LOCK_MAKE:
- if (!Extend0) {
- ConsoleIn->ScrollLock = (BOOLEAN) !ConsoleIn->ScrollLock;
- UpdateStatusLights (ConsoleIn);
- }
-
- break;
- }
- }
-
- //
- // If this is above the valid range, ignore it
- //
- if (ScanCode >= SCANCODE_MAX_MAKE) {
- continue;
- } else {
- break;
- }
- }
-
- //
- // Handle Ctrl+Alt+Del hotkey
- //
- if ((ConsoleIn->LeftCtrl || ConsoleIn->RightCtrl) &&
- (ConsoleIn->LeftAlt || ConsoleIn->RightAlt) &&
- (ScanCode == SCANCODE_DELETE_MAKE)
- )
- {
- gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
- }
-
- //
- // Save the Shift/Toggle state
- //
- InitializeKeyState (ConsoleIn, &KeyData.KeyState);
- KeyData.Key.ScanCode = SCAN_NULL;
- KeyData.Key.UnicodeChar = CHAR_NULL;
-
- //
- // Key Pad "/" shares the same scancode as that of "/" except Key Pad "/" has E0 prefix
- //
- if (Extend0 && (ScanCode == 0x35)) {
- KeyData.Key.UnicodeChar = L'/';
- KeyData.Key.ScanCode = SCAN_NULL;
-
- //
- // PAUSE shares the same scancode as that of NUM except PAUSE has E1 prefix
- //
- } else if (Extend1 && (ScanCode == SCANCODE_NUM_LOCK_MAKE)) {
- KeyData.Key.UnicodeChar = CHAR_NULL;
- KeyData.Key.ScanCode = SCAN_PAUSE;
-
- //
- // PAUSE shares the same scancode as that of SCROLL except PAUSE (CTRL pressed) has E0 prefix
- //
- } else if (Extend0 && (ScanCode == SCANCODE_SCROLL_LOCK_MAKE)) {
- KeyData.Key.UnicodeChar = CHAR_NULL;
- KeyData.Key.ScanCode = SCAN_PAUSE;
-
- //
- // PRNT_SCRN shares the same scancode as that of Key Pad "*" except PRNT_SCRN has E0 prefix
- //
- } else if (Extend0 && (ScanCode == SCANCODE_SYS_REQ_MAKE)) {
- KeyData.Key.UnicodeChar = CHAR_NULL;
- KeyData.Key.ScanCode = SCAN_NULL;
-
- //
- // Except the above special case, all others can be handled by convert table
- //
- } else {
- for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index++) {
- if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {
- KeyData.Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;
- KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
-
- if ((ConsoleIn->LeftShift || ConsoleIn->RightShift) &&
- (ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar))
- {
- KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;
- //
- // Need not return associated shift state if a class of printable characters that
- // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
- //
- KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
- }
-
- //
- // alphabetic key is affected by CapsLock State
- //
- if (ConsoleIn->CapsLock) {
- if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {
- KeyData.Key.UnicodeChar = (UINT16)(KeyData.Key.UnicodeChar - L'a' + L'A');
- } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {
- KeyData.Key.UnicodeChar = (UINT16)(KeyData.Key.UnicodeChar - L'A' + L'a');
- }
- }
-
- break;
- }
- }
- }
-
- //
- // distinguish numeric key pad keys' 'up symbol' and 'down symbol'
- //
- if ((ScanCode >= 0x47) && (ScanCode <= 0x53)) {
- if (ConsoleIn->NumLock && !(ConsoleIn->LeftShift || ConsoleIn->RightShift) && !Extend0) {
- KeyData.Key.ScanCode = SCAN_NULL;
- } else if ((ScanCode != 0x4a) && (ScanCode != 0x4e)) {
- KeyData.Key.UnicodeChar = CHAR_NULL;
- }
- }
-
- //
- // If the key can not be converted then just return.
- //
- if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {
- if (!ConsoleIn->IsSupportPartialKey) {
- return;
- }
- }
-
- //
- // Signal KeyNotify process event if this key pressed matches any key registered.
- //
- for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {
- CurrentNotify = CR (
- Link,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
- );
- if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
- //
- // The key notification function needs to run at TPL_CALLBACK
- // while current TPL is TPL_NOTIFY. It will be invoked in
- // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
- //
- PushEfikeyBufTail (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
- gBS->SignalEvent (ConsoleIn->KeyNotifyProcessEvent);
- break;
- }
- }
-
- PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, &KeyData);
-}
-
-/**
- Perform 8042 controller and keyboard Initialization.
- If ExtendedVerification is TRUE, do additional test for
- the keyboard interface
-
- @param ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer
- @param ExtendedVerification - indicates a thorough initialization
-
- @retval EFI_DEVICE_ERROR Fail to init keyboard
- @retval EFI_SUCCESS Success to init keyboard
-**/
-EFI_STATUS
-InitKeyboard (
- IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN BOOLEAN ExtendedVerification
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status1;
- UINT8 CommandByte;
- EFI_PS2_POLICY_PROTOCOL *Ps2Policy;
- UINT32 TryTime;
-
- Status = EFI_SUCCESS;
- mEnableMouseInterface = TRUE;
- TryTime = 0;
-
- //
- // Get Ps2 policy to set this
- //
- gBS->LocateProtocol (
- &gEfiPs2PolicyProtocolGuid,
- NULL,
- (VOID **)&Ps2Policy
- );
-
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER,
- ConsoleIn->DevicePath
- );
-
- //
- // Perform a read to cleanup the Status Register's
- // output buffer full bits within MAX TRY times
- //
- if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) != 0) {
- while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) {
- Status = KeyboardRead (ConsoleIn, &CommandByte);
- TryTime++;
- }
-
- //
- // Exceed the max try times. The device may be error.
- //
- if (TryTime == KEYBOARD_MAX_TRY) {
- Status = EFI_DEVICE_ERROR;
- goto Done;
- }
- }
-
- //
- // We should disable mouse interface during the initialization process
- // since mouse device output could block keyboard device output in the
- // 60H port of 8042 controller.
- //
- // So if we are not initializing 8042 controller for the
- // first time, we have to remember the previous mouse interface
- // enabling state
- //
- // Test the system flag in to determine whether this is the first
- // time initialization
- //
- if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG) != 0) {
- if (!PcdGetBool (PcdFastPS2Detection)) {
- //
- // 8042 controller is already setup (by myself or by mouse driver):
- // See whether mouse interface is already enabled
- // which determines whether we should enable it later
- //
- //
- // Read the command byte of 8042 controller
- //
- Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_READ);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"\n\r");
- goto Done;
- }
-
- Status = KeyboardRead (ConsoleIn, &CommandByte);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"\n\r");
- goto Done;
- }
-
- //
- // Test the mouse enabling bit
- //
- if ((CommandByte & 0x20) != 0) {
- mEnableMouseInterface = FALSE;
- } else {
- mEnableMouseInterface = TRUE;
- }
- } else {
- mEnableMouseInterface = FALSE;
- }
- } else {
- //
- // 8042 controller is not setup yet:
- // 8042 controller selftest;
- // Don't enable mouse interface later.
- //
- //
- // Disable keyboard and mouse interfaces
- //
- if (!PcdGetBool (PcdFastPS2Detection)) {
- Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"\n\r");
- goto Done;
- }
-
- Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"\n\r");
- goto Done;
- }
-
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,
- ConsoleIn->DevicePath
- );
- //
- // 8042 Controller Self Test
- //
- Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
- goto Done;
- }
-
- Status = KeyboardWaitForValue (ConsoleIn, 0x55);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r");
- goto Done;
- }
- }
-
- //
- // Don't enable mouse interface later
- //
- mEnableMouseInterface = FALSE;
- }
-
- if (Ps2Policy != NULL) {
- Ps2Policy->Ps2InitHardware (ConsoleIn->Handle);
- }
-
- //
- // Write 8042 Command Byte, set System Flag
- // While at the same time:
- // 1. disable mouse interface,
- // 2. enable kbd interface,
- // 3. enable PC/XT kbd translation mode
- // 4. enable mouse and kbd interrupts
- //
- // ( Command Byte bits:
- // 7: Reserved
- // 6: PC/XT translation mode
- // 5: Disable Auxiliary device interface
- // 4: Disable keyboard interface
- // 3: Reserved
- // 2: System Flag
- // 1: Enable Auxiliary device interrupt
- // 0: Enable Keyboard interrupt )
- //
- Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_WRITE);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
- goto Done;
- }
-
- Status = KeyboardWrite (ConsoleIn, 0x67);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
- goto Done;
- }
-
- //
- // Clear Memory Scancode Buffer
- //
- ConsoleIn->ScancodeQueue.Head = 0;
- ConsoleIn->ScancodeQueue.Tail = 0;
- ConsoleIn->EfiKeyQueue.Head = 0;
- ConsoleIn->EfiKeyQueue.Tail = 0;
- ConsoleIn->EfiKeyQueueForNotify.Head = 0;
- ConsoleIn->EfiKeyQueueForNotify.Tail = 0;
-
- //
- // Reset the status indicators
- //
- ConsoleIn->CapsLock = FALSE;
- ConsoleIn->NumLock = FALSE;
- ConsoleIn->ScrollLock = FALSE;
- ConsoleIn->LeftCtrl = FALSE;
- ConsoleIn->RightCtrl = FALSE;
- ConsoleIn->LeftAlt = FALSE;
- ConsoleIn->RightAlt = FALSE;
- ConsoleIn->LeftShift = FALSE;
- ConsoleIn->RightShift = FALSE;
- ConsoleIn->LeftLogo = FALSE;
- ConsoleIn->RightLogo = FALSE;
- ConsoleIn->Menu = FALSE;
- ConsoleIn->SysReq = FALSE;
-
- ConsoleIn->IsSupportPartialKey = FALSE;
- //
- // For resetting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,
- // and to support KB hot plug, we need to let the InitKB succeed no matter whether there is a KB device connected
- // to system. So we only do the real resetting for keyboard when user asks and there is a real KB connected t system,
- // and normally during booting an OS, it's skipped.
- //
- if (ExtendedVerification && CheckKeyboardConnect (ConsoleIn)) {
- //
- // Additional verifications for keyboard interface
- //
- //
- // Keyboard Interface Test
- //
- Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
- goto Done;
- }
-
- Status = KeyboardWaitForValue (ConsoleIn, 0x00);
- if (EFI_ERROR (Status)) {
- KeyboardError (
- ConsoleIn,
- L"Some specific value not acquired from 8042 controller!\n\r"
- );
- goto Done;
- }
-
- //
- // Keyboard reset with a BAT(Basic Assurance Test)
- //
- Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_RESET);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
- goto Done;
- }
-
- Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
- goto Done;
- }
-
- //
- // wait for BAT completion code
- //
- KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_BAT_SUCCESS);
-
- mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
-
- //
- // Set Keyboard to use Scan Code Set 2
- //
- Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
- goto Done;
- }
-
- Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
- goto Done;
- }
-
- Status = KeyboardWrite (ConsoleIn, 0x02);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller data write error!!\n\r");
- goto Done;
- }
-
- Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
- goto Done;
- }
-
- //
- // Clear Keyboard Scancode Buffer
- //
- Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
- goto Done;
- }
-
- Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
- goto Done;
- }
-
- //
- if (Ps2Policy != NULL) {
- if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_CAPSLOCK) == EFI_KEYBOARD_CAPSLOCK) {
- ConsoleIn->CapsLock = TRUE;
- }
-
- if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_NUMLOCK) == EFI_KEYBOARD_NUMLOCK) {
- ConsoleIn->NumLock = TRUE;
- }
-
- if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_SCROLLLOCK) == EFI_KEYBOARD_SCROLLLOCK) {
- ConsoleIn->ScrollLock = TRUE;
- }
- }
-
- //
- // Update Keyboard Lights
- //
- Status = UpdateStatusLights (ConsoleIn);
- if (EFI_ERROR (Status)) {
- KeyboardError (ConsoleIn, L"Update keyboard status lights error!\n\r");
- goto Done;
- }
- }
-
- //
- // At last, we can now enable the mouse interface if appropriate
- //
-Done:
-
- if (mEnableMouseInterface) {
- //
- // Enable mouse interface
- //
- Status1 = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE);
- if (EFI_ERROR (Status1)) {
- KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
- return EFI_DEVICE_ERROR;
- }
- }
-
- if (!EFI_ERROR (Status)) {
- return EFI_SUCCESS;
- } else {
- return EFI_DEVICE_ERROR;
- }
-}
-
-/**
- Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command
- If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device
- should not be in system.
-
- @param[in] ConsoleIn Keyboard Private Data Structure
-
- @retval TRUE Keyboard in System.
- @retval FALSE Keyboard not in System.
-**/
-BOOLEAN
-EFIAPI
-CheckKeyboardConnect (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- )
-{
- EFI_STATUS Status;
- UINTN WaitForValueTimeOutBcakup;
-
- //
- // enable keyboard itself and wait for its ack
- // If can't receive ack, Keyboard should not be connected.
- //
- if (!PcdGetBool (PcdFastPS2Detection)) {
- Status = KeyboardWrite (
- ConsoleIn,
- KEYBOARD_KBEN
- );
-
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- //
- // wait for 1s
- //
- WaitForValueTimeOutBcakup = mWaitForValueTimeOut;
- mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
- Status = KeyboardWaitForValue (
- ConsoleIn,
- KEYBOARD_CMDECHO_ACK
- );
- mWaitForValueTimeOut = WaitForValueTimeOutBcakup;
-
- if (EFI_ERROR (Status)) {
- return FALSE;
- }
-
- return TRUE;
- } else {
- return TRUE;
- }
-}
+/** @file
+ Routines that access 8042 keyboard controller
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ps2Keyboard.h"
+
+struct {
+ UINT8 ScanCode; ///< follows value defined in Scan Code Set1
+ UINT16 EfiScanCode;
+ CHAR16 UnicodeChar;
+ CHAR16 ShiftUnicodeChar;
+} ConvertKeyboardScanCodeToEfiKey[] = {
+ {
+ 0x01, // Escape
+ SCAN_ESC,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x02,
+ SCAN_NULL,
+ L'1',
+ L'!'
+ },
+ {
+ 0x03,
+ SCAN_NULL,
+ L'2',
+ L'@'
+ },
+ {
+ 0x04,
+ SCAN_NULL,
+ L'3',
+ L'#'
+ },
+ {
+ 0x05,
+ SCAN_NULL,
+ L'4',
+ L'$'
+ },
+ {
+ 0x06,
+ SCAN_NULL,
+ L'5',
+ L'%'
+ },
+ {
+ 0x07,
+ SCAN_NULL,
+ L'6',
+ L'^'
+ },
+ {
+ 0x08,
+ SCAN_NULL,
+ L'7',
+ L'&'
+ },
+ {
+ 0x09,
+ SCAN_NULL,
+ L'8',
+ L'*'
+ },
+ {
+ 0x0A,
+ SCAN_NULL,
+ L'9',
+ L'('
+ },
+ {
+ 0x0B,
+ SCAN_NULL,
+ L'0',
+ L')'
+ },
+ {
+ 0x0C,
+ SCAN_NULL,
+ L'-',
+ L'_'
+ },
+ {
+ 0x0D,
+ SCAN_NULL,
+ L'=',
+ L'+'
+ },
+ {
+ 0x0E, // BackSpace
+ SCAN_NULL,
+ 0x0008,
+ 0x0008
+ },
+ {
+ 0x0F, // Tab
+ SCAN_NULL,
+ 0x0009,
+ 0x0009
+ },
+ {
+ 0x10,
+ SCAN_NULL,
+ L'q',
+ L'Q'
+ },
+ {
+ 0x11,
+ SCAN_NULL,
+ L'w',
+ L'W'
+ },
+ {
+ 0x12,
+ SCAN_NULL,
+ L'e',
+ L'E'
+ },
+ {
+ 0x13,
+ SCAN_NULL,
+ L'r',
+ L'R'
+ },
+ {
+ 0x14,
+ SCAN_NULL,
+ L't',
+ L'T'
+ },
+ {
+ 0x15,
+ SCAN_NULL,
+ L'y',
+ L'Y'
+ },
+ {
+ 0x16,
+ SCAN_NULL,
+ L'u',
+ L'U'
+ },
+ {
+ 0x17,
+ SCAN_NULL,
+ L'i',
+ L'I'
+ },
+ {
+ 0x18,
+ SCAN_NULL,
+ L'o',
+ L'O'
+ },
+ {
+ 0x19,
+ SCAN_NULL,
+ L'p',
+ L'P'
+ },
+ {
+ 0x1a,
+ SCAN_NULL,
+ L'[',
+ L'{'
+ },
+ {
+ 0x1b,
+ SCAN_NULL,
+ L']',
+ L'}'
+ },
+ {
+ 0x1c, // Enter
+ SCAN_NULL,
+ 0x000d,
+ 0x000d
+ },
+ {
+ 0x1d,
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x1e,
+ SCAN_NULL,
+ L'a',
+ L'A'
+ },
+ {
+ 0x1f,
+ SCAN_NULL,
+ L's',
+ L'S'
+ },
+ {
+ 0x20,
+ SCAN_NULL,
+ L'd',
+ L'D'
+ },
+ {
+ 0x21,
+ SCAN_NULL,
+ L'f',
+ L'F'
+ },
+ {
+ 0x22,
+ SCAN_NULL,
+ L'g',
+ L'G'
+ },
+ {
+ 0x23,
+ SCAN_NULL,
+ L'h',
+ L'H'
+ },
+ {
+ 0x24,
+ SCAN_NULL,
+ L'j',
+ L'J'
+ },
+ {
+ 0x25,
+ SCAN_NULL,
+ L'k',
+ L'K'
+ },
+ {
+ 0x26,
+ SCAN_NULL,
+ L'l',
+ L'L'
+ },
+ {
+ 0x27,
+ SCAN_NULL,
+ L';',
+ L':'
+ },
+ {
+ 0x28,
+ SCAN_NULL,
+ L'\'',
+ L'"'
+ },
+ {
+ 0x29,
+ SCAN_NULL,
+ L'`',
+ L'~'
+ },
+ {
+ 0x2a, // Left Shift
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x2b,
+ SCAN_NULL,
+ L'\\',
+ L'|'
+ },
+ {
+ 0x2c,
+ SCAN_NULL,
+ L'z',
+ L'Z'
+ },
+ {
+ 0x2d,
+ SCAN_NULL,
+ L'x',
+ L'X'
+ },
+ {
+ 0x2e,
+ SCAN_NULL,
+ L'c',
+ L'C'
+ },
+ {
+ 0x2f,
+ SCAN_NULL,
+ L'v',
+ L'V'
+ },
+ {
+ 0x30,
+ SCAN_NULL,
+ L'b',
+ L'B'
+ },
+ {
+ 0x31,
+ SCAN_NULL,
+ L'n',
+ L'N'
+ },
+ {
+ 0x32,
+ SCAN_NULL,
+ L'm',
+ L'M'
+ },
+ {
+ 0x33,
+ SCAN_NULL,
+ L',',
+ L'<'
+ },
+ {
+ 0x34,
+ SCAN_NULL,
+ L'.',
+ L'>'
+ },
+ {
+ 0x35,
+ SCAN_NULL,
+ L'/',
+ L'?'
+ },
+ {
+ 0x36, // Right Shift
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x37, // Numeric Keypad *
+ SCAN_NULL,
+ L'*',
+ L'*'
+ },
+ {
+ 0x38, // Left Alt/Extended Right Alt
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x39,
+ SCAN_NULL,
+ L' ',
+ L' '
+ },
+ {
+ 0x3A, // CapsLock
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x3B,
+ SCAN_F1,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x3C,
+ SCAN_F2,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x3D,
+ SCAN_F3,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x3E,
+ SCAN_F4,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x3F,
+ SCAN_F5,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x40,
+ SCAN_F6,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x41,
+ SCAN_F7,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x42,
+ SCAN_F8,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x43,
+ SCAN_F9,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x44,
+ SCAN_F10,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x45, // NumLock
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x46, // ScrollLock
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x47,
+ SCAN_HOME,
+ L'7',
+ L'7'
+ },
+ {
+ 0x48,
+ SCAN_UP,
+ L'8',
+ L'8'
+ },
+ {
+ 0x49,
+ SCAN_PAGE_UP,
+ L'9',
+ L'9'
+ },
+ {
+ 0x4a,
+ SCAN_NULL,
+ L'-',
+ L'-'
+ },
+ {
+ 0x4b,
+ SCAN_LEFT,
+ L'4',
+ L'4'
+ },
+ {
+ 0x4c, // Numeric Keypad 5
+ SCAN_NULL,
+ L'5',
+ L'5'
+ },
+ {
+ 0x4d,
+ SCAN_RIGHT,
+ L'6',
+ L'6'
+ },
+ {
+ 0x4e,
+ SCAN_NULL,
+ L'+',
+ L'+'
+ },
+ {
+ 0x4f,
+ SCAN_END,
+ L'1',
+ L'1'
+ },
+ {
+ 0x50,
+ SCAN_DOWN,
+ L'2',
+ L'2'
+ },
+ {
+ 0x51,
+ SCAN_PAGE_DOWN,
+ L'3',
+ L'3'
+ },
+ {
+ 0x52,
+ SCAN_INSERT,
+ L'0',
+ L'0'
+ },
+ {
+ 0x53,
+ SCAN_DELETE,
+ L'.',
+ L'.'
+ },
+ {
+ 0x57,
+ SCAN_F11,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x58,
+ SCAN_F12,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x5B, // Left LOGO
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x5C, // Right LOGO
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ 0x5D, // Menu key
+ SCAN_NULL,
+ 0x0000,
+ 0x0000
+ },
+ {
+ TABLE_END,
+ TABLE_END,
+ SCAN_NULL,
+ SCAN_NULL
+ },
+};
+
+//
+// The WaitForValue time out
+//
+UINTN mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
+
+BOOLEAN mEnableMouseInterface;
+
+/**
+ Return the count of scancode in the queue.
+
+ @param Queue Pointer to instance of SCAN_CODE_QUEUE.
+
+ @return Count of the scancode.
+**/
+UINTN
+GetScancodeBufCount (
+ IN SCAN_CODE_QUEUE *Queue
+ )
+{
+ if (Queue->Head <= Queue->Tail) {
+ return Queue->Tail - Queue->Head;
+ } else {
+ return Queue->Tail + KEYBOARD_SCAN_CODE_MAX_COUNT - Queue->Head;
+ }
+}
+
+/**
+ Read several bytes from the scancode buffer without removing them.
+ This function is called to see if there are enough bytes of scancode
+ representing a single key.
+
+ @param Queue Pointer to instance of SCAN_CODE_QUEUE.
+ @param Count Number of bytes to be read
+ @param Buf Store the results
+
+ @retval EFI_SUCCESS success to scan the keyboard code
+ @retval EFI_NOT_READY invalid parameter
+**/
+EFI_STATUS
+GetScancodeBufHead (
+ IN SCAN_CODE_QUEUE *Queue,
+ IN UINTN Count,
+ OUT UINT8 *Buf
+ )
+{
+ UINTN Index;
+ UINTN Pos;
+
+ //
+ // check the valid range of parameter 'Count'
+ //
+ if (GetScancodeBufCount (Queue) < Count) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // retrieve the values
+ //
+ for (Index = 0, Pos = Queue->Head; Index < Count; Index++, Pos = (Pos + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
+ Buf[Index] = Queue->Buffer[Pos];
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Read & remove several bytes from the scancode buffer.
+ This function is usually called after GetScancodeBufHead()
+
+ @param Queue Pointer to instance of SCAN_CODE_QUEUE.
+ @param Count Number of bytes to be read
+ @param Buf Store the results
+
+ @retval EFI_SUCCESS success to scan the keyboard code
+ @retval EFI_NOT_READY invalid parameter
+**/
+EFI_STATUS
+PopScancodeBufHead (
+ IN SCAN_CODE_QUEUE *Queue,
+ IN UINTN Count,
+ OUT UINT8 *Buf OPTIONAL
+ )
+{
+ UINTN Index;
+
+ //
+ // Check the valid range of parameter 'Count'
+ //
+ if (GetScancodeBufCount (Queue) < Count) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Retrieve and remove the values
+ //
+ for (Index = 0; Index < Count; Index++, Queue->Head = (Queue->Head + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT) {
+ if (Buf != NULL) {
+ Buf[Index] = Queue->Buffer[Queue->Head];
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Push one byte to the scancode buffer.
+
+ @param Queue Pointer to instance of SCAN_CODE_QUEUE.
+ @param Scancode The byte to push.
+**/
+VOID
+PushScancodeBufTail (
+ IN SCAN_CODE_QUEUE *Queue,
+ IN UINT8 Scancode
+ )
+{
+ if (GetScancodeBufCount (Queue) == KEYBOARD_SCAN_CODE_MAX_COUNT - 1) {
+ PopScancodeBufHead (Queue, 1, NULL);
+ }
+
+ Queue->Buffer[Queue->Tail] = Scancode;
+ Queue->Tail = (Queue->Tail + 1) % KEYBOARD_SCAN_CODE_MAX_COUNT;
+}
+
+/**
+ Read data register .
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+
+ @return return the value
+
+**/
+UINT8
+KeyReadDataRegister (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ )
+
+{
+ return IoRead8 (ConsoleIn->DataRegisterAddress);
+}
+
+/**
+ Write data register.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param Data value wanted to be written
+
+**/
+VOID
+KeyWriteDataRegister (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN UINT8 Data
+ )
+{
+ IoWrite8 (ConsoleIn->DataRegisterAddress, Data);
+}
+
+/**
+ Read status register.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+
+ @return value in status register
+
+**/
+UINT8
+KeyReadStatusRegister (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ )
+{
+ return IoRead8 (ConsoleIn->StatusRegisterAddress);
+}
+
+/**
+ Write command register .
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param Data The value wanted to be written
+
+**/
+VOID
+KeyWriteCommandRegister (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN UINT8 Data
+ )
+{
+ IoWrite8 (ConsoleIn->CommandRegisterAddress, Data);
+}
+
+/**
+ Display error message.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param ErrMsg Unicode string of error message
+
+**/
+VOID
+KeyboardError (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN CHAR16 *ErrMsg
+ )
+{
+ ConsoleIn->KeyboardErr = TRUE;
+}
+
+/**
+ Timer event handler: read a series of scancodes from 8042
+ and put them into memory scancode buffer.
+ it read as much scancodes to either fill
+ the memory buffer or empty the keyboard buffer.
+ It is registered as running under TPL_NOTIFY
+
+ @param Event The timer event
+ @param Context A KEYBOARD_CONSOLE_IN_DEV pointer
+
+**/
+VOID
+EFIAPI
+KeyboardTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+
+{
+ UINT8 Data;
+ EFI_TPL OldTpl;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+
+ ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ if (((KEYBOARD_CONSOLE_IN_DEV *)Context)->KeyboardErr) {
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return;
+ }
+
+ //
+ // To let KB driver support Hot plug, here should skip the 'resend' command for the case that
+ // KB is not connected to system. If KB is not connected to system, driver will find there's something
+ // error in the following code and wait for the input buffer empty, this waiting time should be short enough since
+ // this is a NOTIFY TPL period function, or the system performance will degrade hardly when KB is not connected.
+ // Just skip the 'resend' process simply.
+ //
+
+ while ((KeyReadStatusRegister (ConsoleIn) & (KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT|KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA)) ==
+ KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA
+ )
+ {
+ //
+ // Read one byte of the scan code and store it into the memory buffer
+ //
+ Data = KeyReadDataRegister (ConsoleIn);
+ PushScancodeBufTail (&ConsoleIn->ScancodeQueue, Data);
+ }
+
+ KeyGetchar (ConsoleIn);
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+}
+
+/**
+ Read key value .
+
+ @param ConsoleIn - Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param Data - Pointer to outof buffer for keeping key value
+
+ @retval EFI_TIMEOUT Status register time out
+ @retval EFI_SUCCESS Success to read keyboard
+
+**/
+EFI_STATUS
+KeyboardRead (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ OUT UINT8 *Data
+ )
+
+{
+ UINT32 TimeOut;
+ UINT32 RegFilled;
+
+ TimeOut = 0;
+ RegFilled = 0;
+
+ //
+ // wait till output buffer full then perform the read
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if (KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) {
+ RegFilled = 1;
+ *Data = KeyReadDataRegister (ConsoleIn);
+ break;
+ }
+
+ MicroSecondDelay (30);
+ }
+
+ if (RegFilled == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ write key to keyboard
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param Data value wanted to be written
+
+ @retval EFI_TIMEOUT The input buffer register is full for putting new value util timeout
+ @retval EFI_SUCCESS The new value is success put into input buffer register.
+
+**/
+EFI_STATUS
+KeyboardWrite (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN UINT8 Data
+ )
+{
+ UINT32 TimeOut;
+ UINT32 RegEmptied;
+
+ TimeOut = 0;
+ RegEmptied = 0;
+
+ //
+ // wait for input buffer empty
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
+ RegEmptied = 1;
+ break;
+ }
+
+ MicroSecondDelay (30);
+ }
+
+ if (RegEmptied == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // Write it
+ //
+ KeyWriteDataRegister (ConsoleIn, Data);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Issue keyboard command.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param Data The buff holding the command
+
+ @retval EFI_TIMEOUT Keyboard is not ready to issuing
+ @retval EFI_SUCCESS Success to issue keyboard command
+
+**/
+EFI_STATUS
+KeyboardCommand (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN UINT8 Data
+ )
+{
+ UINT32 TimeOut;
+ UINT32 RegEmptied;
+
+ TimeOut = 0;
+ RegEmptied = 0;
+
+ //
+ // Wait For Input Buffer Empty
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
+ RegEmptied = 1;
+ break;
+ }
+
+ MicroSecondDelay (30);
+ }
+
+ if (RegEmptied == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ // issue the command
+ //
+ KeyWriteCommandRegister (ConsoleIn, Data);
+
+ //
+ // Wait For Input Buffer Empty again
+ //
+ RegEmptied = 0;
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if ((KeyReadStatusRegister (ConsoleIn) & 0x02) == 0) {
+ RegEmptied = 1;
+ break;
+ }
+
+ MicroSecondDelay (30);
+ }
+
+ if (RegEmptied == 0) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ wait for a specific value to be presented on
+ 8042 Data register by keyboard and then read it,
+ used in keyboard commands ack
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param Value the value wanted to be waited.
+
+ @retval EFI_TIMEOUT Fail to get specific value in given time
+ @retval EFI_SUCCESS Success to get specific value in given time.
+
+**/
+EFI_STATUS
+KeyboardWaitForValue (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN UINT8 Value
+ )
+{
+ UINT8 Data;
+ UINT32 TimeOut;
+ UINT32 SumTimeOut;
+ UINT32 GotIt;
+
+ GotIt = 0;
+ TimeOut = 0;
+ SumTimeOut = 0;
+
+ //
+ // Make sure the initial value of 'Data' is different from 'Value'
+ //
+ Data = 0;
+ if (Data == Value) {
+ Data = 1;
+ }
+
+ //
+ // Read from 8042 (multiple times if needed)
+ // until the expected value appears
+ // use SumTimeOut to control the iteration
+ //
+ while (1) {
+ //
+ // Perform a read
+ //
+ for (TimeOut = 0; TimeOut < KEYBOARD_TIMEOUT; TimeOut += 30) {
+ if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
+ Data = KeyReadDataRegister (ConsoleIn);
+ break;
+ }
+
+ MicroSecondDelay (30);
+ }
+
+ SumTimeOut += TimeOut;
+
+ if (Data == Value) {
+ GotIt = 1;
+ break;
+ }
+
+ if (SumTimeOut >= mWaitForValueTimeOut) {
+ break;
+ }
+ }
+
+ //
+ // Check results
+ //
+ if (GotIt == 1) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_TIMEOUT;
+ }
+}
+
+/**
+ Show keyboard status lights according to
+ indicators in ConsoleIn.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+
+ @return status of updating keyboard register
+
+**/
+EFI_STATUS
+UpdateStatusLights (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Command;
+
+ //
+ // Send keyboard command
+ //
+ Status = KeyboardWrite (ConsoleIn, 0xed);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ KeyboardWaitForValue (ConsoleIn, 0xfa);
+
+ //
+ // Light configuration
+ //
+ Command = 0;
+ if (ConsoleIn->CapsLock) {
+ Command |= 4;
+ }
+
+ if (ConsoleIn->NumLock) {
+ Command |= 2;
+ }
+
+ if (ConsoleIn->ScrollLock) {
+ Command |= 1;
+ }
+
+ Status = KeyboardWrite (ConsoleIn, Command);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ KeyboardWaitForValue (ConsoleIn, 0xfa);
+ return Status;
+}
+
+/**
+ Initialize the key state.
+
+ @param ConsoleIn The KEYBOARD_CONSOLE_IN_DEV instance.
+ @param KeyState A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ OUT EFI_KEY_STATE *KeyState
+ )
+{
+ KeyState->KeyShiftState = EFI_SHIFT_STATE_VALID
+ | (ConsoleIn->LeftCtrl ? EFI_LEFT_CONTROL_PRESSED : 0)
+ | (ConsoleIn->RightCtrl ? EFI_RIGHT_CONTROL_PRESSED : 0)
+ | (ConsoleIn->LeftAlt ? EFI_LEFT_ALT_PRESSED : 0)
+ | (ConsoleIn->RightAlt ? EFI_RIGHT_ALT_PRESSED : 0)
+ | (ConsoleIn->LeftShift ? EFI_LEFT_SHIFT_PRESSED : 0)
+ | (ConsoleIn->RightShift ? EFI_RIGHT_SHIFT_PRESSED : 0)
+ | (ConsoleIn->LeftLogo ? EFI_LEFT_LOGO_PRESSED : 0)
+ | (ConsoleIn->RightLogo ? EFI_RIGHT_LOGO_PRESSED : 0)
+ | (ConsoleIn->Menu ? EFI_MENU_KEY_PRESSED : 0)
+ | (ConsoleIn->SysReq ? EFI_SYS_REQ_PRESSED : 0)
+ ;
+ KeyState->KeyToggleState = EFI_TOGGLE_STATE_VALID
+ | (ConsoleIn->CapsLock ? EFI_CAPS_LOCK_ACTIVE : 0)
+ | (ConsoleIn->NumLock ? EFI_NUM_LOCK_ACTIVE : 0)
+ | (ConsoleIn->ScrollLock ? EFI_SCROLL_LOCK_ACTIVE : 0)
+ | (ConsoleIn->IsSupportPartialKey ? EFI_KEY_STATE_EXPOSED : 0)
+ ;
+}
+
+/**
+ Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
+
+ The function is always called in TPL_NOTIFY.
+
+ @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer
+
+**/
+VOID
+KeyGetchar (
+ IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ )
+{
+ EFI_STATUS Status;
+ UINT16 ScanCode;
+ BOOLEAN Extend0;
+ BOOLEAN Extend1;
+ UINTN Index;
+ EFI_KEY_DATA KeyData;
+ LIST_ENTRY *Link;
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ //
+ // 3 bytes most
+ //
+ UINT8 ScancodeArr[3];
+ UINT32 ScancodeArrPos;
+
+ //
+ // Check if there are enough bytes of scancode representing a single key
+ // available in the buffer
+ //
+ while (TRUE) {
+ Extend0 = FALSE;
+ Extend1 = FALSE;
+ ScancodeArrPos = 0;
+ Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED0) {
+ //
+ // E0 to look ahead 2 bytes
+ //
+ Extend0 = TRUE;
+ ScancodeArrPos = 1;
+ Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ } else if (ScancodeArr[ScancodeArrPos] == SCANCODE_EXTENDED1) {
+ //
+ // E1 to look ahead 3 bytes
+ //
+ Extend1 = TRUE;
+ ScancodeArrPos = 2;
+ Status = GetScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ }
+
+ //
+ // if we reach this position, scancodes for a key is in buffer now,pop them
+ //
+ Status = PopScancodeBufHead (&ConsoleIn->ScancodeQueue, ScancodeArrPos + 1, ScancodeArr);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // store the last available byte, this byte of scancode will be checked
+ //
+ ScanCode = ScancodeArr[ScancodeArrPos];
+
+ if (!Extend1) {
+ //
+ // Check for special keys and update the driver state.
+ //
+ switch (ScanCode) {
+ case SCANCODE_CTRL_MAKE:
+ if (Extend0) {
+ ConsoleIn->RightCtrl = TRUE;
+ } else {
+ ConsoleIn->LeftCtrl = TRUE;
+ }
+
+ break;
+ case SCANCODE_CTRL_BREAK:
+ if (Extend0) {
+ ConsoleIn->RightCtrl = FALSE;
+ } else {
+ ConsoleIn->LeftCtrl = FALSE;
+ }
+
+ break;
+
+ case SCANCODE_ALT_MAKE:
+ if (Extend0) {
+ ConsoleIn->RightAlt = TRUE;
+ } else {
+ ConsoleIn->LeftAlt = TRUE;
+ }
+
+ break;
+ case SCANCODE_ALT_BREAK:
+ if (Extend0) {
+ ConsoleIn->RightAlt = FALSE;
+ } else {
+ ConsoleIn->LeftAlt = FALSE;
+ }
+
+ break;
+
+ case SCANCODE_LEFT_SHIFT_MAKE:
+ //
+ // To avoid recognize PRNT_SCRN key as a L_SHIFT key
+ // because PRNT_SCRN key generates E0 followed by L_SHIFT scan code.
+ // If it the second byte of the PRNT_ScRN skip it.
+ //
+ if (!Extend0) {
+ ConsoleIn->LeftShift = TRUE;
+ break;
+ }
+
+ continue;
+
+ case SCANCODE_LEFT_SHIFT_BREAK:
+ if (!Extend0) {
+ ConsoleIn->LeftShift = FALSE;
+ }
+
+ break;
+
+ case SCANCODE_RIGHT_SHIFT_MAKE:
+ ConsoleIn->RightShift = TRUE;
+ break;
+ case SCANCODE_RIGHT_SHIFT_BREAK:
+ ConsoleIn->RightShift = FALSE;
+ break;
+
+ case SCANCODE_LEFT_LOGO_MAKE:
+ ConsoleIn->LeftLogo = TRUE;
+ break;
+ case SCANCODE_LEFT_LOGO_BREAK:
+ ConsoleIn->LeftLogo = FALSE;
+ break;
+
+ case SCANCODE_RIGHT_LOGO_MAKE:
+ ConsoleIn->RightLogo = TRUE;
+ break;
+ case SCANCODE_RIGHT_LOGO_BREAK:
+ ConsoleIn->RightLogo = FALSE;
+ break;
+
+ case SCANCODE_MENU_MAKE:
+ ConsoleIn->Menu = TRUE;
+ break;
+ case SCANCODE_MENU_BREAK:
+ ConsoleIn->Menu = FALSE;
+ break;
+
+ case SCANCODE_SYS_REQ_MAKE:
+ if (Extend0) {
+ ConsoleIn->SysReq = TRUE;
+ }
+
+ break;
+ case SCANCODE_SYS_REQ_BREAK:
+ if (Extend0) {
+ ConsoleIn->SysReq = FALSE;
+ }
+
+ break;
+
+ case SCANCODE_SYS_REQ_MAKE_WITH_ALT:
+ ConsoleIn->SysReq = TRUE;
+ break;
+ case SCANCODE_SYS_REQ_BREAK_WITH_ALT:
+ ConsoleIn->SysReq = FALSE;
+ break;
+
+ case SCANCODE_CAPS_LOCK_MAKE:
+ ConsoleIn->CapsLock = (BOOLEAN) !ConsoleIn->CapsLock;
+ UpdateStatusLights (ConsoleIn);
+ break;
+ case SCANCODE_NUM_LOCK_MAKE:
+ ConsoleIn->NumLock = (BOOLEAN) !ConsoleIn->NumLock;
+ UpdateStatusLights (ConsoleIn);
+ break;
+ case SCANCODE_SCROLL_LOCK_MAKE:
+ if (!Extend0) {
+ ConsoleIn->ScrollLock = (BOOLEAN) !ConsoleIn->ScrollLock;
+ UpdateStatusLights (ConsoleIn);
+ }
+
+ break;
+ }
+ }
+
+ //
+ // If this is above the valid range, ignore it
+ //
+ if (ScanCode >= SCANCODE_MAX_MAKE) {
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ //
+ // Handle Ctrl+Alt+Del hotkey
+ //
+ if ((ConsoleIn->LeftCtrl || ConsoleIn->RightCtrl) &&
+ (ConsoleIn->LeftAlt || ConsoleIn->RightAlt) &&
+ (ScanCode == SCANCODE_DELETE_MAKE)
+ )
+ {
+ gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+
+ //
+ // Save the Shift/Toggle state
+ //
+ InitializeKeyState (ConsoleIn, &KeyData.KeyState);
+ KeyData.Key.ScanCode = SCAN_NULL;
+ KeyData.Key.UnicodeChar = CHAR_NULL;
+
+ //
+ // Key Pad "/" shares the same scancode as that of "/" except Key Pad "/" has E0 prefix
+ //
+ if (Extend0 && (ScanCode == 0x35)) {
+ KeyData.Key.UnicodeChar = L'/';
+ KeyData.Key.ScanCode = SCAN_NULL;
+
+ //
+ // PAUSE shares the same scancode as that of NUM except PAUSE has E1 prefix
+ //
+ } else if (Extend1 && (ScanCode == SCANCODE_NUM_LOCK_MAKE)) {
+ KeyData.Key.UnicodeChar = CHAR_NULL;
+ KeyData.Key.ScanCode = SCAN_PAUSE;
+
+ //
+ // PAUSE shares the same scancode as that of SCROLL except PAUSE (CTRL pressed) has E0 prefix
+ //
+ } else if (Extend0 && (ScanCode == SCANCODE_SCROLL_LOCK_MAKE)) {
+ KeyData.Key.UnicodeChar = CHAR_NULL;
+ KeyData.Key.ScanCode = SCAN_PAUSE;
+
+ //
+ // PRNT_SCRN shares the same scancode as that of Key Pad "*" except PRNT_SCRN has E0 prefix
+ //
+ } else if (Extend0 && (ScanCode == SCANCODE_SYS_REQ_MAKE)) {
+ KeyData.Key.UnicodeChar = CHAR_NULL;
+ KeyData.Key.ScanCode = SCAN_NULL;
+
+ //
+ // Except the above special case, all others can be handled by convert table
+ //
+ } else {
+ for (Index = 0; ConvertKeyboardScanCodeToEfiKey[Index].ScanCode != TABLE_END; Index++) {
+ if (ScanCode == ConvertKeyboardScanCodeToEfiKey[Index].ScanCode) {
+ KeyData.Key.ScanCode = ConvertKeyboardScanCodeToEfiKey[Index].EfiScanCode;
+ KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar;
+
+ if ((ConsoleIn->LeftShift || ConsoleIn->RightShift) &&
+ (ConvertKeyboardScanCodeToEfiKey[Index].UnicodeChar != ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar))
+ {
+ KeyData.Key.UnicodeChar = ConvertKeyboardScanCodeToEfiKey[Index].ShiftUnicodeChar;
+ //
+ // Need not return associated shift state if a class of printable characters that
+ // are normally adjusted by shift modifiers. e.g. Shift Key + 'f' key = 'F'
+ //
+ KeyData.KeyState.KeyShiftState &= ~(EFI_LEFT_SHIFT_PRESSED | EFI_RIGHT_SHIFT_PRESSED);
+ }
+
+ //
+ // alphabetic key is affected by CapsLock State
+ //
+ if (ConsoleIn->CapsLock) {
+ if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {
+ KeyData.Key.UnicodeChar = (UINT16)(KeyData.Key.UnicodeChar - L'a' + L'A');
+ } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {
+ KeyData.Key.UnicodeChar = (UINT16)(KeyData.Key.UnicodeChar - L'A' + L'a');
+ }
+ }
+
+ break;
+ }
+ }
+ }
+
+ //
+ // distinguish numeric key pad keys' 'up symbol' and 'down symbol'
+ //
+ if ((ScanCode >= 0x47) && (ScanCode <= 0x53)) {
+ if (ConsoleIn->NumLock && !(ConsoleIn->LeftShift || ConsoleIn->RightShift) && !Extend0) {
+ KeyData.Key.ScanCode = SCAN_NULL;
+ } else if ((ScanCode != 0x4a) && (ScanCode != 0x4e)) {
+ KeyData.Key.UnicodeChar = CHAR_NULL;
+ }
+ }
+
+ //
+ // If the key can not be converted then just return.
+ //
+ if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {
+ if (!ConsoleIn->IsSupportPartialKey) {
+ return;
+ }
+ }
+
+ //
+ // Signal KeyNotify process event if this key pressed matches any key registered.
+ //
+ for (Link = GetFirstNode (&ConsoleIn->NotifyList); !IsNull (&ConsoleIn->NotifyList, Link); Link = GetNextNode (&ConsoleIn->NotifyList, Link)) {
+ CurrentNotify = CR (
+ Link,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ //
+ // The key notification function needs to run at TPL_CALLBACK
+ // while current TPL is TPL_NOTIFY. It will be invoked in
+ // KeyNotifyProcessHandler() which runs at TPL_CALLBACK.
+ //
+ PushEfikeyBufTail (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
+ gBS->SignalEvent (ConsoleIn->KeyNotifyProcessEvent);
+ break;
+ }
+ }
+
+ PushEfikeyBufTail (&ConsoleIn->EfiKeyQueue, &KeyData);
+}
+
+/**
+ Perform 8042 controller and keyboard Initialization.
+ If ExtendedVerification is TRUE, do additional test for
+ the keyboard interface
+
+ @param ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer
+ @param ExtendedVerification - indicates a thorough initialization
+
+ @retval EFI_DEVICE_ERROR Fail to init keyboard
+ @retval EFI_SUCCESS Success to init keyboard
+**/
+EFI_STATUS
+InitKeyboard (
+ IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ UINT8 CommandByte;
+ EFI_PS2_POLICY_PROTOCOL *Ps2Policy;
+ UINT32 TryTime;
+
+ Status = EFI_SUCCESS;
+ mEnableMouseInterface = TRUE;
+ TryTime = 0;
+
+ //
+ // Get Ps2 policy to set this
+ //
+ gBS->LocateProtocol (
+ &gEfiPs2PolicyProtocolGuid,
+ NULL,
+ (VOID **)&Ps2Policy
+ );
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_CLEAR_BUFFER,
+ ConsoleIn->DevicePath
+ );
+
+ //
+ // Perform a read to cleanup the Status Register's
+ // output buffer full bits within MAX TRY times
+ //
+ if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA) != 0) {
+ while (!EFI_ERROR (Status) && TryTime < KEYBOARD_MAX_TRY) {
+ Status = KeyboardRead (ConsoleIn, &CommandByte);
+ TryTime++;
+ }
+
+ //
+ // Exceed the max try times. The device may be error.
+ //
+ if (TryTime == KEYBOARD_MAX_TRY) {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+ }
+
+ //
+ // We should disable mouse interface during the initialization process
+ // since mouse device output could block keyboard device output in the
+ // 60H port of 8042 controller.
+ //
+ // So if we are not initializing 8042 controller for the
+ // first time, we have to remember the previous mouse interface
+ // enabling state
+ //
+ // Test the system flag in to determine whether this is the first
+ // time initialization
+ //
+ if ((KeyReadStatusRegister (ConsoleIn) & KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG) != 0) {
+ if (!PcdGetBool (PcdFastPS2Detection)) {
+ //
+ // 8042 controller is already setup (by myself or by mouse driver):
+ // See whether mouse interface is already enabled
+ // which determines whether we should enable it later
+ //
+ //
+ // Read the command byte of 8042 controller
+ //
+ Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_READ);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardRead (ConsoleIn, &CommandByte);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"\n\r");
+ goto Done;
+ }
+
+ //
+ // Test the mouse enabling bit
+ //
+ if ((CommandByte & 0x20) != 0) {
+ mEnableMouseInterface = FALSE;
+ } else {
+ mEnableMouseInterface = TRUE;
+ }
+ } else {
+ mEnableMouseInterface = FALSE;
+ }
+ } else {
+ //
+ // 8042 controller is not setup yet:
+ // 8042 controller selftest;
+ // Don't enable mouse interface later.
+ //
+ //
+ // Disable keyboard and mouse interfaces
+ //
+ if (!PcdGetBool (PcdFastPS2Detection)) {
+ Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"\n\r");
+ goto Done;
+ }
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_PC_SELF_TEST,
+ ConsoleIn->DevicePath
+ );
+ //
+ // 8042 Controller Self Test
+ //
+ Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWaitForValue (ConsoleIn, 0x55);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller self test failed!\n\r");
+ goto Done;
+ }
+ }
+
+ //
+ // Don't enable mouse interface later
+ //
+ mEnableMouseInterface = FALSE;
+ }
+
+ if (Ps2Policy != NULL) {
+ Ps2Policy->Ps2InitHardware (ConsoleIn->Handle);
+ }
+
+ //
+ // Write 8042 Command Byte, set System Flag
+ // While at the same time:
+ // 1. disable mouse interface,
+ // 2. enable kbd interface,
+ // 3. enable PC/XT kbd translation mode
+ // 4. enable mouse and kbd interrupts
+ //
+ // ( Command Byte bits:
+ // 7: Reserved
+ // 6: PC/XT translation mode
+ // 5: Disable Auxiliary device interface
+ // 4: Disable keyboard interface
+ // 3: Reserved
+ // 2: System Flag
+ // 1: Enable Auxiliary device interrupt
+ // 0: Enable Keyboard interrupt )
+ //
+ Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_WRITE);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWrite (ConsoleIn, 0x67);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
+ goto Done;
+ }
+
+ //
+ // Clear Memory Scancode Buffer
+ //
+ ConsoleIn->ScancodeQueue.Head = 0;
+ ConsoleIn->ScancodeQueue.Tail = 0;
+ ConsoleIn->EfiKeyQueue.Head = 0;
+ ConsoleIn->EfiKeyQueue.Tail = 0;
+ ConsoleIn->EfiKeyQueueForNotify.Head = 0;
+ ConsoleIn->EfiKeyQueueForNotify.Tail = 0;
+
+ //
+ // Reset the status indicators
+ //
+ ConsoleIn->CapsLock = FALSE;
+ ConsoleIn->NumLock = FALSE;
+ ConsoleIn->ScrollLock = FALSE;
+ ConsoleIn->LeftCtrl = FALSE;
+ ConsoleIn->RightCtrl = FALSE;
+ ConsoleIn->LeftAlt = FALSE;
+ ConsoleIn->RightAlt = FALSE;
+ ConsoleIn->LeftShift = FALSE;
+ ConsoleIn->RightShift = FALSE;
+ ConsoleIn->LeftLogo = FALSE;
+ ConsoleIn->RightLogo = FALSE;
+ ConsoleIn->Menu = FALSE;
+ ConsoleIn->SysReq = FALSE;
+
+ ConsoleIn->IsSupportPartialKey = FALSE;
+ //
+ // For resetting keyboard is not mandatory before booting OS and sometimes keyboard responses very slow,
+ // and to support KB hot plug, we need to let the InitKB succeed no matter whether there is a KB device connected
+ // to system. So we only do the real resetting for keyboard when user asks and there is a real KB connected t system,
+ // and normally during booting an OS, it's skipped.
+ //
+ if (ExtendedVerification && CheckKeyboardConnect (ConsoleIn)) {
+ //
+ // Additional verifications for keyboard interface
+ //
+ //
+ // Keyboard Interface Test
+ //
+ Status = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWaitForValue (ConsoleIn, 0x00);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (
+ ConsoleIn,
+ L"Some specific value not acquired from 8042 controller!\n\r"
+ );
+ goto Done;
+ }
+
+ //
+ // Keyboard reset with a BAT(Basic Assurance Test)
+ //
+ Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_RESET);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
+ goto Done;
+ }
+
+ //
+ // wait for BAT completion code
+ //
+ KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_BAT_SUCCESS);
+
+ mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
+
+ //
+ // Set Keyboard to use Scan Code Set 2
+ //
+ Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWrite (ConsoleIn, 0x02);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller data write error!!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
+ goto Done;
+ }
+
+ //
+ // Clear Keyboard Scancode Buffer
+ //
+ Status = KeyboardWrite (ConsoleIn, KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"8042 controller data write error!\n\r");
+ goto Done;
+ }
+
+ Status = KeyboardWaitForValue (ConsoleIn, KEYBOARD_8048_RETURN_8042_ACK);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"Some specific value not acquired from 8042 controller!\n\r");
+ goto Done;
+ }
+
+ //
+ if (Ps2Policy != NULL) {
+ if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_CAPSLOCK) == EFI_KEYBOARD_CAPSLOCK) {
+ ConsoleIn->CapsLock = TRUE;
+ }
+
+ if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_NUMLOCK) == EFI_KEYBOARD_NUMLOCK) {
+ ConsoleIn->NumLock = TRUE;
+ }
+
+ if ((Ps2Policy->KeyboardLight & EFI_KEYBOARD_SCROLLLOCK) == EFI_KEYBOARD_SCROLLLOCK) {
+ ConsoleIn->ScrollLock = TRUE;
+ }
+ }
+
+ //
+ // Update Keyboard Lights
+ //
+ Status = UpdateStatusLights (ConsoleIn);
+ if (EFI_ERROR (Status)) {
+ KeyboardError (ConsoleIn, L"Update keyboard status lights error!\n\r");
+ goto Done;
+ }
+ }
+
+ //
+ // At last, we can now enable the mouse interface if appropriate
+ //
+Done:
+
+ if (mEnableMouseInterface) {
+ //
+ // Enable mouse interface
+ //
+ Status1 = KeyboardCommand (ConsoleIn, KEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE);
+ if (EFI_ERROR (Status1)) {
+ KeyboardError (ConsoleIn, L"8042 controller command write error!\n\r");
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+}
+
+/**
+ Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command
+ If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device
+ should not be in system.
+
+ @param[in] ConsoleIn Keyboard Private Data Structure
+
+ @retval TRUE Keyboard in System.
+ @retval FALSE Keyboard not in System.
+**/
+BOOLEAN
+EFIAPI
+CheckKeyboardConnect (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ )
+{
+ EFI_STATUS Status;
+ UINTN WaitForValueTimeOutBcakup;
+
+ //
+ // enable keyboard itself and wait for its ack
+ // If can't receive ack, Keyboard should not be connected.
+ //
+ if (!PcdGetBool (PcdFastPS2Detection)) {
+ Status = KeyboardWrite (
+ ConsoleIn,
+ KEYBOARD_KBEN
+ );
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ //
+ // wait for 1s
+ //
+ WaitForValueTimeOutBcakup = mWaitForValueTimeOut;
+ mWaitForValueTimeOut = KEYBOARD_WAITFORVALUE_TIMEOUT;
+ Status = KeyboardWaitForValue (
+ ConsoleIn,
+ KEYBOARD_CMDECHO_ACK
+ );
+ mWaitForValueTimeOut = WaitForValueTimeOutBcakup;
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+ } else {
+ return TRUE;
+ }
+}
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
index 81d3c6eb70..bcadd766e3 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KbdTextIn.c
@@ -1,746 +1,746 @@
-/** @file
- Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces
- provided by Ps2KbdCtrller.c.
-
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ps2Keyboard.h"
-
-/**
- Check whether the EFI key buffer is empty.
-
- @param Queue Pointer to instance of EFI_KEY_QUEUE.
-
- @retval TRUE The EFI key buffer is empty.
- @retval FALSE The EFI key buffer isn't empty.
-**/
-BOOLEAN
-IsEfikeyBufEmpty (
- IN EFI_KEY_QUEUE *Queue
- )
-{
- return (BOOLEAN)(Queue->Head == Queue->Tail);
-}
-
-/**
- Read & remove one key data from the EFI key buffer.
-
- @param Queue Pointer to instance of EFI_KEY_QUEUE.
- @param KeyData Receive the key data.
-
- @retval EFI_SUCCESS The key data is popped successfully.
- @retval EFI_NOT_READY There is no key data available.
-**/
-EFI_STATUS
-PopEfikeyBufHead (
- IN EFI_KEY_QUEUE *Queue,
- OUT EFI_KEY_DATA *KeyData OPTIONAL
- )
-{
- if (IsEfikeyBufEmpty (Queue)) {
- return EFI_NOT_READY;
- }
-
- //
- // Retrieve and remove the values
- //
- if (KeyData != NULL) {
- CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));
- }
-
- Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
- return EFI_SUCCESS;
-}
-
-/**
- Push one key data to the EFI key buffer.
-
- @param Queue Pointer to instance of EFI_KEY_QUEUE.
- @param KeyData The key data to push.
-**/
-VOID
-PushEfikeyBufTail (
- IN EFI_KEY_QUEUE *Queue,
- IN EFI_KEY_DATA *KeyData
- )
-{
- if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {
- //
- // If Queue is full, pop the one from head.
- //
- PopEfikeyBufHead (Queue, NULL);
- }
-
- CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));
- Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
-}
-
-/**
- Judge whether is a registered key
-
- @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was registered.
- @param InputData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
- @retval TRUE Key be pressed matches a registered key.
- @retval FALSE Match failed.
-
-**/
-BOOLEAN
-IsKeyRegistered (
- IN EFI_KEY_DATA *RegsiteredData,
- IN EFI_KEY_DATA *InputData
- )
-
-{
- ASSERT (RegsiteredData != NULL && InputData != NULL);
-
- if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
- (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))
- {
- return FALSE;
- }
-
- //
- // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
- //
- if ((RegsiteredData->KeyState.KeyShiftState != 0) &&
- (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))
- {
- return FALSE;
- }
-
- if ((RegsiteredData->KeyState.KeyToggleState != 0) &&
- (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))
- {
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- Reads the next keystroke from the input device. The WaitForKey Event can
- be used to test for existence of a keystroke via WaitForEvent () call.
-
- @param ConsoleInDev Ps2 Keyboard private structure
- @param KeyData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
-
- @retval EFI_SUCCESS The keystroke information was returned.
- @retval EFI_NOT_READY There was no keystroke data available.
- @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
- hardware errors.
- @retval EFI_INVALID_PARAMETER KeyData is NULL.
-
-**/
-EFI_STATUS
-KeyboardReadKeyStrokeWorker (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev,
- OUT EFI_KEY_DATA *KeyData
- )
-
-{
- EFI_STATUS Status;
- EFI_TPL OldTpl;
-
- if (KeyData == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- KeyboardTimerHandler (NULL, ConsoleInDev);
-
- if (ConsoleInDev->KeyboardErr) {
- Status = EFI_DEVICE_ERROR;
- } else {
- Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);
- if (Status == EFI_NOT_READY) {
- ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
- InitializeKeyState (ConsoleInDev, &KeyData->KeyState);
- }
- }
-
- gBS->RestoreTPL (OldTpl);
- return Status;
-}
-
-/**
- Perform 8042 controller and keyboard initialization which implement SIMPLE_TEXT_IN.Reset()
-
- @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
- @param ExtendedVerification Indicate that the driver may perform a more
- exhaustive verification operation of the device during
- reset, now this par is ignored in this driver
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardEfiReset (
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
-{
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_TPL OldTpl;
-
- ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- if (ConsoleIn->KeyboardErr) {
- return EFI_DEVICE_ERROR;
- }
-
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,
- ConsoleIn->DevicePath
- );
-
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- //
- // Call InitKeyboard to initialize the keyboard
- //
- Status = InitKeyboard (ConsoleIn, ExtendedVerification);
- if (EFI_ERROR (Status)) {
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
-
- //
- // Report the status If a stuck key was detected
- //
- if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_STUCK_KEY,
- ConsoleIn->DevicePath
- );
- }
-
- //
- // Report the status If keyboard is locked
- //
- if ((KeyReadStatusRegister (ConsoleIn) & 0x10) == 0) {
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_LOCKED,
- ConsoleIn->DevicePath
- );
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke().
-
- @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
- @param Key The output buffer for key value
-
- @retval EFI_SUCCESS success to read key stroke
- @retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
-**/
-EFI_STATUS
-EFIAPI
-KeyboardReadKeyStroke (
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
- OUT EFI_INPUT_KEY *Key
- )
-{
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_KEY_DATA KeyData;
-
- ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
-
- //
- // Considering if the partial keystroke is enabled, there maybe a partial
- // keystroke in the queue, so here skip the partial keystroke and get the
- // next key from the queue
- //
- while (1) {
- //
- // If there is no pending key, then return.
- //
- Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // If it is partial keystroke, skip it.
- //
- if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {
- continue;
- }
-
- //
- // Translate the CTRL-Alpha characters to their corresponding control value
- // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
- //
- if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
- if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {
- KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'a' + 1);
- } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {
- KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'A' + 1);
- }
- }
-
- CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
- return EFI_SUCCESS;
- }
-}
-
-/**
- Event notification function for SIMPLE_TEXT_IN.WaitForKey event
- Signal the event if there is key available
-
- @param Event the event object
- @param Context waiting context
-
-**/
-VOID
-EFIAPI
-KeyboardWaitForKey (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_TPL OldTpl;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_KEY_DATA KeyData;
-
- ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;
-
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- KeyboardTimerHandler (NULL, ConsoleIn);
-
- if (!ConsoleIn->KeyboardErr) {
- //
- // WaitforKey doesn't support the partial key.
- // Considering if the partial keystroke is enabled, there maybe a partial
- // keystroke in the queue, so here skip the partial keystroke and get the
- // next key from the queue
- //
- while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
- CopyMem (
- &KeyData,
- &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),
- sizeof (EFI_KEY_DATA)
- );
- if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {
- PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);
- continue;
- }
-
- //
- // if there is pending value key, signal the event.
- //
- gBS->SignalEvent (Event);
- break;
- }
- }
-
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
-}
-
-/**
- Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
- Signal the event if there is key available
-
- @param Event event object
- @param Context waiting context
-
-**/
-VOID
-EFIAPI
-KeyboardWaitForKeyEx (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-
-{
- KeyboardWaitForKey (Event, Context);
-}
-
-/**
- Reset the input device and optionally run diagnostics
-
- @param This Protocol instance pointer.
- @param ExtendedVerification Driver may perform diagnostics on reset.
-
- @retval EFI_SUCCESS The device was reset.
- @retval EFI_DEVICE_ERROR The device is not functioning properly and could
- not be reset.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardEfiResetEx (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- )
-
-{
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
-
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
-
- return ConsoleInDev->ConIn.Reset (
- &ConsoleInDev->ConIn,
- ExtendedVerification
- );
-}
-
-/**
- Reads the next keystroke from the input device. The WaitForKey Event can
- be used to test for existence of a keystroke via WaitForEvent () call.
-
-
- @param This Protocol instance pointer.
- @param KeyData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
- @retval EFI_SUCCESS The keystroke information was returned.
- @retval EFI_NOT_READY There was no keystroke data available.
- @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
- hardware errors.
- @retval EFI_INVALID_PARAMETER KeyData is NULL.
- @retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardReadKeyStrokeEx (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- OUT EFI_KEY_DATA *KeyData
- )
-
-{
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
-
- if (KeyData == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
- return KeyboardReadKeyStrokeWorker (ConsoleInDev, KeyData);
-}
-
-/**
- Set certain state for the input device.
-
- @param This Protocol instance pointer.
- @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
- state for the input device.
-
- @retval EFI_SUCCESS The device state was set successfully.
- @retval EFI_DEVICE_ERROR The device is not functioning correctly and could
- not have the setting adjusted.
- @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
- @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardSetState (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN EFI_KEY_TOGGLE_STATE *KeyToggleState
- )
-
-{
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- EFI_TPL OldTpl;
-
- if (KeyToggleState == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
-
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- if (ConsoleInDev->KeyboardErr) {
- Status = EFI_DEVICE_ERROR;
- goto Exit;
- }
-
- if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
- Status = EFI_UNSUPPORTED;
- goto Exit;
- }
-
- //
- // Update the status light
- //
- ConsoleInDev->ScrollLock = FALSE;
- ConsoleInDev->NumLock = FALSE;
- ConsoleInDev->CapsLock = FALSE;
- ConsoleInDev->IsSupportPartialKey = FALSE;
-
- if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
- ConsoleInDev->ScrollLock = TRUE;
- }
-
- if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
- ConsoleInDev->NumLock = TRUE;
- }
-
- if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
- ConsoleInDev->CapsLock = TRUE;
- }
-
- if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
- ConsoleInDev->IsSupportPartialKey = TRUE;
- }
-
- Status = UpdateStatusLights (ConsoleInDev);
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- }
-
-Exit:
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
-
- return Status;
-}
-
-/**
- Register a notification function for a particular keystroke for the input device.
-
- @param This Protocol instance pointer.
- @param KeyData A pointer to a buffer that is filled in with the keystroke
- information data for the key that was pressed. If KeyData.Key,
- KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0,
- then any incomplete keystroke will trigger a notification of the KeyNotificationFunction.
- @param KeyNotificationFunction Points to the function to be called when the key
- sequence is typed specified by KeyData. This notification function
- should be called at <=TPL_CALLBACK.
- @param NotifyHandle Points to the unique handle assigned to the registered notification.
-
- @retval EFI_SUCCESS The notification function was registered successfully.
- @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data structures.
- @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardRegisterKeyNotify (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN EFI_KEY_DATA *KeyData,
- IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
- OUT VOID **NotifyHandle
- )
-{
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- EFI_TPL OldTpl;
- LIST_ENTRY *Link;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;
-
- if ((KeyData == NULL) || (NotifyHandle == NULL) || (KeyNotificationFunction == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
-
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- //
- // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
- //
- for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
- CurrentNotify = CR (
- Link,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
- );
- if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
- if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
- *NotifyHandle = CurrentNotify;
- Status = EFI_SUCCESS;
- goto Exit;
- }
- }
- }
-
- //
- // Allocate resource to save the notification function
- //
- NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *)AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));
- if (NewNotify == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Exit;
- }
-
- NewNotify->Signature = KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
- NewNotify->KeyNotificationFn = KeyNotificationFunction;
- CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
- InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);
-
- *NotifyHandle = NewNotify;
- Status = EFI_SUCCESS;
-
-Exit:
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return Status;
-}
-
-/**
- Remove a registered notification function from a particular keystroke.
-
- @param This Protocol instance pointer.
- @param NotificationHandle The handle of the notification function being unregistered.
-
-
- @retval EFI_SUCCESS The notification function was unregistered successfully.
- @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardUnregisterKeyNotify (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN VOID *NotificationHandle
- )
-{
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
- EFI_TPL OldTpl;
- LIST_ENTRY *Link;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
-
- if (NotificationHandle == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
-
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
-
- for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
- CurrentNotify = CR (
- Link,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
- );
- if (CurrentNotify == NotificationHandle) {
- //
- // Remove the notification function from NotifyList and free resources
- //
- RemoveEntryList (&CurrentNotify->NotifyEntry);
-
- gBS->FreePool (CurrentNotify);
- Status = EFI_SUCCESS;
- goto Exit;
- }
- }
-
- //
- // Can not find the specified Notification Handle
- //
- Status = EFI_INVALID_PARAMETER;
-Exit:
- //
- // Leave critical section and return
- //
- gBS->RestoreTPL (OldTpl);
- return Status;
-}
-
-/**
- Process key notify.
-
- @param Event Indicates the event that invoke this function.
- @param Context Indicates the calling context.
-**/
-VOID
-EFIAPI
-KeyNotifyProcessHandler (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
-{
- EFI_STATUS Status;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- EFI_KEY_DATA KeyData;
- LIST_ENTRY *Link;
- LIST_ENTRY *NotifyList;
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
- EFI_TPL OldTpl;
-
- ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;
-
- //
- // Invoke notification functions.
- //
- NotifyList = &ConsoleIn->NotifyList;
- while (TRUE) {
- //
- // Enter critical section
- //
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
- //
- // Leave critical section
- //
- gBS->RestoreTPL (OldTpl);
- if (EFI_ERROR (Status)) {
- break;
- }
-
- for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
- CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
- if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
- CurrentNotify->KeyNotificationFn (&KeyData);
- }
- }
- }
-}
+/** @file
+ Routines implements SIMPLE_TEXT_IN protocol's interfaces based on 8042 interfaces
+ provided by Ps2KbdCtrller.c.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ps2Keyboard.h"
+
+/**
+ Check whether the EFI key buffer is empty.
+
+ @param Queue Pointer to instance of EFI_KEY_QUEUE.
+
+ @retval TRUE The EFI key buffer is empty.
+ @retval FALSE The EFI key buffer isn't empty.
+**/
+BOOLEAN
+IsEfikeyBufEmpty (
+ IN EFI_KEY_QUEUE *Queue
+ )
+{
+ return (BOOLEAN)(Queue->Head == Queue->Tail);
+}
+
+/**
+ Read & remove one key data from the EFI key buffer.
+
+ @param Queue Pointer to instance of EFI_KEY_QUEUE.
+ @param KeyData Receive the key data.
+
+ @retval EFI_SUCCESS The key data is popped successfully.
+ @retval EFI_NOT_READY There is no key data available.
+**/
+EFI_STATUS
+PopEfikeyBufHead (
+ IN EFI_KEY_QUEUE *Queue,
+ OUT EFI_KEY_DATA *KeyData OPTIONAL
+ )
+{
+ if (IsEfikeyBufEmpty (Queue)) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Retrieve and remove the values
+ //
+ if (KeyData != NULL) {
+ CopyMem (KeyData, &Queue->Buffer[Queue->Head], sizeof (EFI_KEY_DATA));
+ }
+
+ Queue->Head = (Queue->Head + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
+ return EFI_SUCCESS;
+}
+
+/**
+ Push one key data to the EFI key buffer.
+
+ @param Queue Pointer to instance of EFI_KEY_QUEUE.
+ @param KeyData The key data to push.
+**/
+VOID
+PushEfikeyBufTail (
+ IN EFI_KEY_QUEUE *Queue,
+ IN EFI_KEY_DATA *KeyData
+ )
+{
+ if ((Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT == Queue->Head) {
+ //
+ // If Queue is full, pop the one from head.
+ //
+ PopEfikeyBufHead (Queue, NULL);
+ }
+
+ CopyMem (&Queue->Buffer[Queue->Tail], KeyData, sizeof (EFI_KEY_DATA));
+ Queue->Tail = (Queue->Tail + 1) % KEYBOARD_EFI_KEY_MAX_COUNT;
+}
+
+/**
+ Judge whether is a registered key
+
+ @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was registered.
+ @param InputData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval TRUE Key be pressed matches a registered key.
+ @retval FALSE Match failed.
+
+**/
+BOOLEAN
+IsKeyRegistered (
+ IN EFI_KEY_DATA *RegsiteredData,
+ IN EFI_KEY_DATA *InputData
+ )
+
+{
+ ASSERT (RegsiteredData != NULL && InputData != NULL);
+
+ if ((RegsiteredData->Key.ScanCode != InputData->Key.ScanCode) ||
+ (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar))
+ {
+ return FALSE;
+ }
+
+ //
+ // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
+ //
+ if ((RegsiteredData->KeyState.KeyShiftState != 0) &&
+ (RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState))
+ {
+ return FALSE;
+ }
+
+ if ((RegsiteredData->KeyState.KeyToggleState != 0) &&
+ (RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState))
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+ @param ConsoleInDev Ps2 Keyboard private structure
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data available.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+ hardware errors.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+
+**/
+EFI_STATUS
+KeyboardReadKeyStrokeWorker (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev,
+ OUT EFI_KEY_DATA *KeyData
+ )
+
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ KeyboardTimerHandler (NULL, ConsoleInDev);
+
+ if (ConsoleInDev->KeyboardErr) {
+ Status = EFI_DEVICE_ERROR;
+ } else {
+ Status = PopEfikeyBufHead (&ConsoleInDev->EfiKeyQueue, KeyData);
+ if (Status == EFI_NOT_READY) {
+ ZeroMem (&KeyData->Key, sizeof (KeyData->Key));
+ InitializeKeyState (ConsoleInDev, &KeyData->KeyState);
+ }
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Perform 8042 controller and keyboard initialization which implement SIMPLE_TEXT_IN.Reset()
+
+ @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+ @param ExtendedVerification Indicate that the driver may perform a more
+ exhaustive verification operation of the device during
+ reset, now this par is ignored in this driver
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardEfiReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EFI_STATUS Status;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+ EFI_TPL OldTpl;
+
+ ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
+ if (ConsoleIn->KeyboardErr) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_RESET,
+ ConsoleIn->DevicePath
+ );
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // Call InitKeyboard to initialize the keyboard
+ //
+ Status = InitKeyboard (ConsoleIn, ExtendedVerification);
+ if (EFI_ERROR (Status)) {
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ //
+ // Report the status If a stuck key was detected
+ //
+ if (KeyReadStatusRegister (ConsoleIn) & 0x01) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_STUCK_KEY,
+ ConsoleIn->DevicePath
+ );
+ }
+
+ //
+ // Report the status If keyboard is locked
+ //
+ if ((KeyReadStatusRegister (ConsoleIn) & 0x10) == 0) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_KEYBOARD_EC_LOCKED,
+ ConsoleIn->DevicePath
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieve key values for driver user which implement SIMPLE_TEXT_IN.ReadKeyStroke().
+
+ @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+ @param Key The output buffer for key value
+
+ @retval EFI_SUCCESS success to read key stroke
+ @retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
+**/
+EFI_STATUS
+EFIAPI
+KeyboardReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ )
+{
+ EFI_STATUS Status;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+ EFI_KEY_DATA KeyData;
+
+ ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
+
+ //
+ // Considering if the partial keystroke is enabled, there maybe a partial
+ // keystroke in the queue, so here skip the partial keystroke and get the
+ // next key from the queue
+ //
+ while (1) {
+ //
+ // If there is no pending key, then return.
+ //
+ Status = KeyboardReadKeyStrokeWorker (ConsoleIn, &KeyData);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // If it is partial keystroke, skip it.
+ //
+ if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {
+ continue;
+ }
+
+ //
+ // Translate the CTRL-Alpha characters to their corresponding control value
+ // (ctrl-a = 0x0001 through ctrl-Z = 0x001A)
+ //
+ if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
+ if ((KeyData.Key.UnicodeChar >= L'a') && (KeyData.Key.UnicodeChar <= L'z')) {
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'a' + 1);
+ } else if ((KeyData.Key.UnicodeChar >= L'A') && (KeyData.Key.UnicodeChar <= L'Z')) {
+ KeyData.Key.UnicodeChar = (CHAR16)(KeyData.Key.UnicodeChar - L'A' + 1);
+ }
+ }
+
+ CopyMem (Key, &KeyData.Key, sizeof (EFI_INPUT_KEY));
+ return EFI_SUCCESS;
+ }
+}
+
+/**
+ Event notification function for SIMPLE_TEXT_IN.WaitForKey event
+ Signal the event if there is key available
+
+ @param Event the event object
+ @param Context waiting context
+
+**/
+VOID
+EFIAPI
+KeyboardWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_TPL OldTpl;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+ EFI_KEY_DATA KeyData;
+
+ ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ KeyboardTimerHandler (NULL, ConsoleIn);
+
+ if (!ConsoleIn->KeyboardErr) {
+ //
+ // WaitforKey doesn't support the partial key.
+ // Considering if the partial keystroke is enabled, there maybe a partial
+ // keystroke in the queue, so here skip the partial keystroke and get the
+ // next key from the queue
+ //
+ while (!IsEfikeyBufEmpty (&ConsoleIn->EfiKeyQueue)) {
+ CopyMem (
+ &KeyData,
+ &(ConsoleIn->EfiKeyQueue.Buffer[ConsoleIn->EfiKeyQueue.Head]),
+ sizeof (EFI_KEY_DATA)
+ );
+ if ((KeyData.Key.ScanCode == SCAN_NULL) && (KeyData.Key.UnicodeChar == CHAR_NULL)) {
+ PopEfikeyBufHead (&ConsoleIn->EfiKeyQueue, &KeyData);
+ continue;
+ }
+
+ //
+ // if there is pending value key, signal the event.
+ //
+ gBS->SignalEvent (Event);
+ break;
+ }
+ }
+
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+}
+
+/**
+ Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
+ Signal the event if there is key available
+
+ @param Event event object
+ @param Context waiting context
+
+**/
+VOID
+EFIAPI
+KeyboardWaitForKeyEx (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+
+{
+ KeyboardWaitForKey (Event, Context);
+}
+
+/**
+ Reset the input device and optionally run diagnostics
+
+ @param This Protocol instance pointer.
+ @param ExtendedVerification Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning properly and could
+ not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardEfiResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+
+{
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
+
+ ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
+
+ return ConsoleInDev->ConIn.Reset (
+ &ConsoleInDev->ConIn,
+ ExtendedVerification
+ );
+}
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval EFI_SUCCESS The keystroke information was returned.
+ @retval EFI_NOT_READY There was no keystroke data available.
+ @retval EFI_DEVICE_ERROR The keystroke information was not returned due to
+ hardware errors.
+ @retval EFI_INVALID_PARAMETER KeyData is NULL.
+ @retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ )
+
+{
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
+
+ if (KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
+ return KeyboardReadKeyStrokeWorker (ConsoleInDev, KeyData);
+}
+
+/**
+ Set certain state for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyToggleState A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ @retval EFI_SUCCESS The device state was set successfully.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and could
+ not have the setting adjusted.
+ @retval EFI_UNSUPPORTED The device does not have the ability to set its state.
+ @retval EFI_INVALID_PARAMETER KeyToggleState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ )
+
+{
+ EFI_STATUS Status;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
+ EFI_TPL OldTpl;
+
+ if (KeyToggleState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ if (ConsoleInDev->KeyboardErr) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID) {
+ Status = EFI_UNSUPPORTED;
+ goto Exit;
+ }
+
+ //
+ // Update the status light
+ //
+ ConsoleInDev->ScrollLock = FALSE;
+ ConsoleInDev->NumLock = FALSE;
+ ConsoleInDev->CapsLock = FALSE;
+ ConsoleInDev->IsSupportPartialKey = FALSE;
+
+ if ((*KeyToggleState & EFI_SCROLL_LOCK_ACTIVE) == EFI_SCROLL_LOCK_ACTIVE) {
+ ConsoleInDev->ScrollLock = TRUE;
+ }
+
+ if ((*KeyToggleState & EFI_NUM_LOCK_ACTIVE) == EFI_NUM_LOCK_ACTIVE) {
+ ConsoleInDev->NumLock = TRUE;
+ }
+
+ if ((*KeyToggleState & EFI_CAPS_LOCK_ACTIVE) == EFI_CAPS_LOCK_ACTIVE) {
+ ConsoleInDev->CapsLock = TRUE;
+ }
+
+ if ((*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED) {
+ ConsoleInDev->IsSupportPartialKey = TRUE;
+ }
+
+ Status = UpdateStatusLights (ConsoleInDev);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+Exit:
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Register a notification function for a particular keystroke for the input device.
+
+ @param This Protocol instance pointer.
+ @param KeyData A pointer to a buffer that is filled in with the keystroke
+ information data for the key that was pressed. If KeyData.Key,
+ KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0,
+ then any incomplete keystroke will trigger a notification of the KeyNotificationFunction.
+ @param KeyNotificationFunction Points to the function to be called when the key
+ sequence is typed specified by KeyData. This notification function
+ should be called at <=TPL_CALLBACK.
+ @param NotifyHandle Points to the unique handle assigned to the registered notification.
+
+ @retval EFI_SUCCESS The notification function was registered successfully.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate resources for necessary data structures.
+ @retval EFI_INVALID_PARAMETER KeyData or NotifyHandle or KeyNotificationFunction is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT VOID **NotifyHandle
+ )
+{
+ EFI_STATUS Status;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
+ EFI_TPL OldTpl;
+ LIST_ENTRY *Link;
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *NewNotify;
+
+ if ((KeyData == NULL) || (NotifyHandle == NULL) || (KeyNotificationFunction == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ //
+ // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
+ //
+ for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (IsKeyRegistered (&CurrentNotify->KeyData, KeyData)) {
+ if (CurrentNotify->KeyNotificationFn == KeyNotificationFunction) {
+ *NotifyHandle = CurrentNotify;
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ }
+ }
+
+ //
+ // Allocate resource to save the notification function
+ //
+ NewNotify = (KEYBOARD_CONSOLE_IN_EX_NOTIFY *)AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_EX_NOTIFY));
+ if (NewNotify == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ NewNotify->Signature = KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
+ NewNotify->KeyNotificationFn = KeyNotificationFunction;
+ CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
+ InsertTailList (&ConsoleInDev->NotifyList, &NewNotify->NotifyEntry);
+
+ *NotifyHandle = NewNotify;
+ Status = EFI_SUCCESS;
+
+Exit:
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Remove a registered notification function from a particular keystroke.
+
+ @param This Protocol instance pointer.
+ @param NotificationHandle The handle of the notification function being unregistered.
+
+
+ @retval EFI_SUCCESS The notification function was unregistered successfully.
+ @retval EFI_INVALID_PARAMETER The NotificationHandle is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN VOID *NotificationHandle
+ )
+{
+ EFI_STATUS Status;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleInDev;
+ EFI_TPL OldTpl;
+ LIST_ENTRY *Link;
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+
+ if (NotificationHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConsoleInDev = TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (This);
+
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+ for (Link = ConsoleInDev->NotifyList.ForwardLink; Link != &ConsoleInDev->NotifyList; Link = Link->ForwardLink) {
+ CurrentNotify = CR (
+ Link,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ if (CurrentNotify == NotificationHandle) {
+ //
+ // Remove the notification function from NotifyList and free resources
+ //
+ RemoveEntryList (&CurrentNotify->NotifyEntry);
+
+ gBS->FreePool (CurrentNotify);
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ }
+
+ //
+ // Can not find the specified Notification Handle
+ //
+ Status = EFI_INVALID_PARAMETER;
+Exit:
+ //
+ // Leave critical section and return
+ //
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Process key notify.
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+**/
+VOID
+EFIAPI
+KeyNotifyProcessHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+ EFI_KEY_DATA KeyData;
+ LIST_ENTRY *Link;
+ LIST_ENTRY *NotifyList;
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *CurrentNotify;
+ EFI_TPL OldTpl;
+
+ ConsoleIn = (KEYBOARD_CONSOLE_IN_DEV *)Context;
+
+ //
+ // Invoke notification functions.
+ //
+ NotifyList = &ConsoleIn->NotifyList;
+ while (TRUE) {
+ //
+ // Enter critical section
+ //
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+ Status = PopEfikeyBufHead (&ConsoleIn->EfiKeyQueueForNotify, &KeyData);
+ //
+ // Leave critical section
+ //
+ gBS->RestoreTPL (OldTpl);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ for (Link = GetFirstNode (NotifyList); !IsNull (NotifyList, Link); Link = GetNextNode (NotifyList, Link)) {
+ CurrentNotify = CR (Link, KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
+ if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
+ CurrentNotify->KeyNotificationFn (&KeyData);
+ }
+ }
+ }
+}
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
index a328931f59..9230e6c9c1 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.c
@@ -1,675 +1,675 @@
-/** @file
-
- PS/2 Keyboard driver. Routines that interacts with callers,
- conforming to EFI driver model
-
-Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "Ps2Keyboard.h"
-
-//
-// Function prototypes
-//
-
-/**
- Test controller is a keyboard Controller.
-
- @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
- @param Controller driver's controller
- @param RemainingDevicePath children device path
-
- @retval EFI_UNSUPPORTED controller is not floppy disk
- @retval EFI_SUCCESS controller is floppy disk
-**/
-EFI_STATUS
-EFIAPI
-KbdControllerDriverSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- );
-
-/**
- Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
-
- @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
- @param Controller driver controller handle
- @param RemainingDevicePath Children's device path
-
- @retval whether success to create floppy control instance.
-**/
-EFI_STATUS
-EFIAPI
-KbdControllerDriverStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- );
-
-/**
- Stop this driver on ControllerHandle. Support stopping any child handles
- created by this driver.
-
- @param This Protocol instance pointer.
- @param ControllerHandle Handle of device to stop driver on
- @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
- children is zero stop the entire bus driver.
- @param ChildHandleBuffer List of Child Handles to Stop.
-
- @retval EFI_SUCCESS This driver is removed ControllerHandle
- @retval other This driver was not removed from this device
-
-**/
-EFI_STATUS
-EFIAPI
-KbdControllerDriverStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- );
-
-/**
- Free the waiting key notify list.
-
- @param ListHead Pointer to list head
-
- @retval EFI_INVALID_PARAMETER ListHead is NULL
- @retval EFI_SUCCESS Success to free NotifyList
-**/
-EFI_STATUS
-KbdFreeNotifyList (
- IN OUT LIST_ENTRY *ListHead
- );
-
-//
-// DriverBinding Protocol Instance
-//
-EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver = {
- KbdControllerDriverSupported,
- KbdControllerDriverStart,
- KbdControllerDriverStop,
- 0xa,
- NULL,
- NULL
-};
-
-/**
- Test controller is a keyboard Controller.
-
- @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
- @param Controller driver's controller
- @param RemainingDevicePath children device path
-
- @retval EFI_UNSUPPORTED controller is not floppy disk
- @retval EFI_SUCCESS controller is floppy disk
-**/
-EFI_STATUS
-EFIAPI
-KbdControllerDriverSupported (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-{
- EFI_STATUS Status;
- EFI_SIO_PROTOCOL *Sio;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- ACPI_HID_DEVICE_PATH *Acpi;
-
- //
- // Check whether the controller is keyboard.
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&DevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- do {
- Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath;
- DevicePath = NextDevicePathNode (DevicePath);
- } while (!IsDevicePathEnd (DevicePath));
-
- if ((DevicePathType (Acpi) != ACPI_DEVICE_PATH) ||
- ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)))
- {
- return EFI_UNSUPPORTED;
- }
-
- if ((Acpi->HID != EISA_PNP_ID (0x303)) || (Acpi->UID != 0)) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Open the IO Abstraction(s) needed to perform the supported test
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiSioProtocolGuid,
- (VOID **)&Sio,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Close the I/O Abstraction(s) used to perform the supported test
- //
- gBS->CloseProtocol (
- Controller,
- &gEfiSioProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- return Status;
-}
-
-/**
- Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
-
- @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
- @param Controller driver controller handle
- @param RemainingDevicePath Children's device path
-
- @retval whether success to create floppy control instance.
-**/
-EFI_STATUS
-EFIAPI
-KbdControllerDriverStart (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
- )
-{
- EFI_STATUS Status;
- EFI_STATUS Status1;
- EFI_SIO_PROTOCOL *Sio;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- UINT8 Data;
- EFI_STATUS_CODE_VALUE StatusCode;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
-
- StatusCode = 0;
-
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiDevicePathProtocolGuid,
- (VOID **)&DevicePath,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Report that the keyboard is being enabled
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
- DevicePath
- );
-
- //
- // Get the ISA I/O Protocol on Controller's handle
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiSioProtocolGuid,
- (VOID **)&Sio,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_BY_DRIVER
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- //
- // Allocate private data
- //
- ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));
- if (ConsoleIn == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
- goto ErrorExit;
- }
-
- //
- // Setup the device instance
- //
- ConsoleIn->Signature = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;
- ConsoleIn->Handle = Controller;
- (ConsoleIn->ConIn).Reset = KeyboardEfiReset;
- (ConsoleIn->ConIn).ReadKeyStroke = KeyboardReadKeyStroke;
- ConsoleIn->DataRegisterAddress = KEYBOARD_8042_DATA_REGISTER;
- ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;
- ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
- ConsoleIn->DevicePath = DevicePath;
-
- ConsoleIn->ConInEx.Reset = KeyboardEfiResetEx;
- ConsoleIn->ConInEx.ReadKeyStrokeEx = KeyboardReadKeyStrokeEx;
- ConsoleIn->ConInEx.SetState = KeyboardSetState;
- ConsoleIn->ConInEx.RegisterKeyNotify = KeyboardRegisterKeyNotify;
- ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;
-
- InitializeListHead (&ConsoleIn->NotifyList);
-
- //
- // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
- // When KBC decode (IO port 0x60/0x64 decode) is not enabled,
- // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.
- // So instead we read status register to detect after read if KBC decode is enabled.
- //
-
- //
- // Return code is ignored on purpose.
- //
- if (!PcdGetBool (PcdFastPS2Detection)) {
- KeyboardRead (ConsoleIn, &Data);
- if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
- //
- // If nobody decodes KBC I/O port, it will read back as 0xFF.
- // Check the Time-Out and Parity bit to see if it has an active KBC in system
- //
- Status = EFI_DEVICE_ERROR;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
- goto ErrorExit;
- }
- }
-
- //
- // Setup the WaitForKey event
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_WAIT,
- TPL_NOTIFY,
- KeyboardWaitForKey,
- ConsoleIn,
- &((ConsoleIn->ConIn).WaitForKey)
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
- goto ErrorExit;
- }
-
- //
- // Setup the WaitForKeyEx event
- //
- Status = gBS->CreateEvent (
- EVT_NOTIFY_WAIT,
- TPL_NOTIFY,
- KeyboardWaitForKeyEx,
- ConsoleIn,
- &(ConsoleIn->ConInEx.WaitForKeyEx)
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
- goto ErrorExit;
- }
-
- // Setup a periodic timer, used for reading keystrokes at a fixed interval
- //
- Status = gBS->CreateEvent (
- EVT_TIMER | EVT_NOTIFY_SIGNAL,
- TPL_NOTIFY,
- KeyboardTimerHandler,
- ConsoleIn,
- &ConsoleIn->TimerEvent
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
- goto ErrorExit;
- }
-
- Status = gBS->SetTimer (
- ConsoleIn->TimerEvent,
- TimerPeriodic,
- KEYBOARD_TIMER_INTERVAL
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
- goto ErrorExit;
- }
-
- Status = gBS->CreateEvent (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- KeyNotifyProcessHandler,
- ConsoleIn,
- &ConsoleIn->KeyNotifyProcessEvent
- );
- if (EFI_ERROR (Status)) {
- Status = EFI_OUT_OF_RESOURCES;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
- goto ErrorExit;
- }
-
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
- DevicePath
- );
-
- //
- // Reset the keyboard device
- //
- Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));
- if (EFI_ERROR (Status)) {
- Status = EFI_DEVICE_ERROR;
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
- goto ErrorExit;
- }
-
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,
- DevicePath
- );
-
- ConsoleIn->ControllerNameTable = NULL;
- AddUnicodeString2 (
- "eng",
- gPs2KeyboardComponentName.SupportedLanguages,
- &ConsoleIn->ControllerNameTable,
- L"PS/2 Keyboard Device",
- TRUE
- );
- AddUnicodeString2 (
- "en",
- gPs2KeyboardComponentName2.SupportedLanguages,
- &ConsoleIn->ControllerNameTable,
- L"PS/2 Keyboard Device",
- FALSE
- );
-
- //
- // Install protocol interfaces for the keyboard device.
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &Controller,
- &gEfiSimpleTextInProtocolGuid,
- &ConsoleIn->ConIn,
- &gEfiSimpleTextInputExProtocolGuid,
- &ConsoleIn->ConInEx,
- NULL
- );
- if (EFI_ERROR (Status)) {
- StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
- goto ErrorExit;
- }
-
- return Status;
-
-ErrorExit:
- //
- // Report error code
- //
- if (StatusCode != 0) {
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_ERROR_CODE | EFI_ERROR_MINOR,
- StatusCode,
- DevicePath
- );
- }
-
- if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
- gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
- }
-
- if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
- gBS->CloseEvent (ConsoleIn->TimerEvent);
- }
-
- if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
- gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
- }
-
- if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
- gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
- }
-
- KbdFreeNotifyList (&ConsoleIn->NotifyList);
- if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
- FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
- }
-
- //
- // Since there will be no timer handler for keyboard input any more,
- // exhaust input data just in case there is still keyboard data left
- //
- if (ConsoleIn != NULL) {
- Status1 = EFI_SUCCESS;
- while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {
- Status1 = KeyboardRead (ConsoleIn, &Data);
- }
- }
-
- if (ConsoleIn != NULL) {
- gBS->FreePool (ConsoleIn);
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiSioProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- return Status;
-}
-
-/**
- Stop this driver on ControllerHandle. Support stopping any child handles
- created by this driver.
-
- @param This Protocol instance pointer.
- @param ControllerHandle Handle of device to stop driver on
- @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
- children is zero stop the entire bus driver.
- @param ChildHandleBuffer List of Child Handles to Stop.
-
- @retval EFI_SUCCESS This driver is removed ControllerHandle
- @retval other This driver was not removed from this device
-
-**/
-EFI_STATUS
-EFIAPI
-KbdControllerDriverStop (
- IN EFI_DRIVER_BINDING_PROTOCOL *This,
- IN EFI_HANDLE Controller,
- IN UINTN NumberOfChildren,
- IN EFI_HANDLE *ChildHandleBuffer
- )
-{
- EFI_STATUS Status;
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
- KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
- UINT8 Data;
-
- //
- // Disable Keyboard
- //
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiSimpleTextInProtocolGuid,
- (VOID **)&ConIn,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_GET_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Status = gBS->OpenProtocol (
- Controller,
- &gEfiSimpleTextInputExProtocolGuid,
- NULL,
- This->DriverBindingHandle,
- Controller,
- EFI_OPEN_PROTOCOL_TEST_PROTOCOL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
-
- //
- // Report that the keyboard is being disabled
- //
- REPORT_STATUS_CODE_WITH_DEVICE_PATH (
- EFI_PROGRESS_CODE,
- EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE,
- ConsoleIn->DevicePath
- );
-
- if (ConsoleIn->TimerEvent != NULL) {
- gBS->CloseEvent (ConsoleIn->TimerEvent);
- ConsoleIn->TimerEvent = NULL;
- }
-
- //
- // Since there will be no timer handler for keyboard input any more,
- // exhaust input data just in case there is still keyboard data left
- //
- Status = EFI_SUCCESS;
- while (!EFI_ERROR (Status)) {
- Status = KeyboardRead (ConsoleIn, &Data);
- }
-
- //
- // Uninstall the SimpleTextIn and SimpleTextInEx protocols
- //
- Status = gBS->UninstallMultipleProtocolInterfaces (
- Controller,
- &gEfiSimpleTextInProtocolGuid,
- &ConsoleIn->ConIn,
- &gEfiSimpleTextInputExProtocolGuid,
- &ConsoleIn->ConInEx,
- NULL
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- gBS->CloseProtocol (
- Controller,
- &gEfiSioProtocolGuid,
- This->DriverBindingHandle,
- Controller
- );
-
- //
- // Free other resources
- //
- if ((ConsoleIn->ConIn).WaitForKey != NULL) {
- gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);
- (ConsoleIn->ConIn).WaitForKey = NULL;
- }
-
- if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
- gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
- ConsoleIn->ConInEx.WaitForKeyEx = NULL;
- }
-
- if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
- gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
- ConsoleIn->KeyNotifyProcessEvent = NULL;
- }
-
- KbdFreeNotifyList (&ConsoleIn->NotifyList);
- FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
- gBS->FreePool (ConsoleIn);
-
- return EFI_SUCCESS;
-}
-
-/**
- Free the waiting key notify list.
-
- @param ListHead Pointer to list head
-
- @retval EFI_INVALID_PARAMETER ListHead is NULL
- @retval EFI_SUCCESS Success to free NotifyList
-**/
-EFI_STATUS
-KbdFreeNotifyList (
- IN OUT LIST_ENTRY *ListHead
- )
-{
- KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
-
- if (ListHead == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- while (!IsListEmpty (ListHead)) {
- NotifyNode = CR (
- ListHead->ForwardLink,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY,
- NotifyEntry,
- KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
- );
- RemoveEntryList (ListHead->ForwardLink);
- gBS->FreePool (NotifyNode);
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- The module Entry Point for module Ps2Keyboard.
-
- @param[in] ImageHandle The firmware allocated handle for the EFI image.
- @param[in] SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The entry point is executed successfully.
- @retval other Some error occurs when executing this entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-InitializePs2Keyboard (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
-
- //
- // Install driver model protocol(s).
- //
- Status = EfiLibInstallDriverBindingComponentName2 (
- ImageHandle,
- SystemTable,
- &gKeyboardControllerDriver,
- ImageHandle,
- &gPs2KeyboardComponentName,
- &gPs2KeyboardComponentName2
- );
- ASSERT_EFI_ERROR (Status);
-
- return Status;
-}
+/** @file
+
+ PS/2 Keyboard driver. Routines that interacts with callers,
+ conforming to EFI driver model
+
+Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Ps2Keyboard.h"
+
+//
+// Function prototypes
+//
+
+/**
+ Test controller is a keyboard Controller.
+
+ @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
+ @param Controller driver's controller
+ @param RemainingDevicePath children device path
+
+ @retval EFI_UNSUPPORTED controller is not floppy disk
+ @retval EFI_SUCCESS controller is floppy disk
+**/
+EFI_STATUS
+EFIAPI
+KbdControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
+
+ @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
+ @param Controller driver controller handle
+ @param RemainingDevicePath Children's device path
+
+ @retval whether success to create floppy control instance.
+**/
+EFI_STATUS
+EFIAPI
+KbdControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop this driver on ControllerHandle. Support stopping any child handles
+ created by this driver.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to stop driver on
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+
+**/
+EFI_STATUS
+EFIAPI
+KbdControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+/**
+ Free the waiting key notify list.
+
+ @param ListHead Pointer to list head
+
+ @retval EFI_INVALID_PARAMETER ListHead is NULL
+ @retval EFI_SUCCESS Success to free NotifyList
+**/
+EFI_STATUS
+KbdFreeNotifyList (
+ IN OUT LIST_ENTRY *ListHead
+ );
+
+//
+// DriverBinding Protocol Instance
+//
+EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver = {
+ KbdControllerDriverSupported,
+ KbdControllerDriverStart,
+ KbdControllerDriverStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+/**
+ Test controller is a keyboard Controller.
+
+ @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
+ @param Controller driver's controller
+ @param RemainingDevicePath children device path
+
+ @retval EFI_UNSUPPORTED controller is not floppy disk
+ @retval EFI_SUCCESS controller is floppy disk
+**/
+EFI_STATUS
+EFIAPI
+KbdControllerDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIO_PROTOCOL *Sio;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ //
+ // Check whether the controller is keyboard.
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ do {
+ Acpi = (ACPI_HID_DEVICE_PATH *)DevicePath;
+ DevicePath = NextDevicePathNode (DevicePath);
+ } while (!IsDevicePathEnd (DevicePath));
+
+ if ((DevicePathType (Acpi) != ACPI_DEVICE_PATH) ||
+ ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != ACPI_EXTENDED_DP)))
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((Acpi->HID != EISA_PNP_ID (0x303)) || (Acpi->UID != 0)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSioProtocolGuid,
+ (VOID **)&Sio,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Close the I/O Abstraction(s) used to perform the supported test
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiSioProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+/**
+ Create KEYBOARD_CONSOLE_IN_DEV instance on controller.
+
+ @param This Pointer of EFI_DRIVER_BINDING_PROTOCOL
+ @param Controller driver controller handle
+ @param RemainingDevicePath Children's device path
+
+ @retval whether success to create floppy control instance.
+**/
+EFI_STATUS
+EFIAPI
+KbdControllerDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ EFI_SIO_PROTOCOL *Sio;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+ UINT8 Data;
+ EFI_STATUS_CODE_VALUE StatusCode;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ StatusCode = 0;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Report that the keyboard is being enabled
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE,
+ DevicePath
+ );
+
+ //
+ // Get the ISA I/O Protocol on Controller's handle
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSioProtocolGuid,
+ (VOID **)&Sio,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Allocate private data
+ //
+ ConsoleIn = AllocateZeroPool (sizeof (KEYBOARD_CONSOLE_IN_DEV));
+ if (ConsoleIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
+ //
+ // Setup the device instance
+ //
+ ConsoleIn->Signature = KEYBOARD_CONSOLE_IN_DEV_SIGNATURE;
+ ConsoleIn->Handle = Controller;
+ (ConsoleIn->ConIn).Reset = KeyboardEfiReset;
+ (ConsoleIn->ConIn).ReadKeyStroke = KeyboardReadKeyStroke;
+ ConsoleIn->DataRegisterAddress = KEYBOARD_8042_DATA_REGISTER;
+ ConsoleIn->StatusRegisterAddress = KEYBOARD_8042_STATUS_REGISTER;
+ ConsoleIn->CommandRegisterAddress = KEYBOARD_8042_COMMAND_REGISTER;
+ ConsoleIn->DevicePath = DevicePath;
+
+ ConsoleIn->ConInEx.Reset = KeyboardEfiResetEx;
+ ConsoleIn->ConInEx.ReadKeyStrokeEx = KeyboardReadKeyStrokeEx;
+ ConsoleIn->ConInEx.SetState = KeyboardSetState;
+ ConsoleIn->ConInEx.RegisterKeyNotify = KeyboardRegisterKeyNotify;
+ ConsoleIn->ConInEx.UnregisterKeyNotify = KeyboardUnregisterKeyNotify;
+
+ InitializeListHead (&ConsoleIn->NotifyList);
+
+ //
+ // Fix for random hangs in System waiting for the Key if no KBC is present in BIOS.
+ // When KBC decode (IO port 0x60/0x64 decode) is not enabled,
+ // KeyboardRead will read back as 0xFF and return status is EFI_SUCCESS.
+ // So instead we read status register to detect after read if KBC decode is enabled.
+ //
+
+ //
+ // Return code is ignored on purpose.
+ //
+ if (!PcdGetBool (PcdFastPS2Detection)) {
+ KeyboardRead (ConsoleIn, &Data);
+ if ((KeyReadStatusRegister (ConsoleIn) & (KBC_PARE | KBC_TIM)) == (KBC_PARE | KBC_TIM)) {
+ //
+ // If nobody decodes KBC I/O port, it will read back as 0xFF.
+ // Check the Time-Out and Parity bit to see if it has an active KBC in system
+ //
+ Status = EFI_DEVICE_ERROR;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
+ goto ErrorExit;
+ }
+ }
+
+ //
+ // Setup the WaitForKey event
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ KeyboardWaitForKey,
+ ConsoleIn,
+ &((ConsoleIn->ConIn).WaitForKey)
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
+ //
+ // Setup the WaitForKeyEx event
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ KeyboardWaitForKeyEx,
+ ConsoleIn,
+ &(ConsoleIn->ConInEx.WaitForKeyEx)
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
+ // Setup a periodic timer, used for reading keystrokes at a fixed interval
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ KeyboardTimerHandler,
+ ConsoleIn,
+ &ConsoleIn->TimerEvent
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
+ Status = gBS->SetTimer (
+ ConsoleIn->TimerEvent,
+ TimerPeriodic,
+ KEYBOARD_TIMER_INTERVAL
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ KeyNotifyProcessHandler,
+ ConsoleIn,
+ &ConsoleIn->KeyNotifyProcessEvent
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_PRESENCE_DETECT,
+ DevicePath
+ );
+
+ //
+ // Reset the keyboard device
+ //
+ Status = ConsoleIn->ConInEx.Reset (&ConsoleIn->ConInEx, FeaturePcdGet (PcdPs2KbdExtendedVerification));
+ if (EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED;
+ goto ErrorExit;
+ }
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DETECTED,
+ DevicePath
+ );
+
+ ConsoleIn->ControllerNameTable = NULL;
+ AddUnicodeString2 (
+ "eng",
+ gPs2KeyboardComponentName.SupportedLanguages,
+ &ConsoleIn->ControllerNameTable,
+ L"PS/2 Keyboard Device",
+ TRUE
+ );
+ AddUnicodeString2 (
+ "en",
+ gPs2KeyboardComponentName2.SupportedLanguages,
+ &ConsoleIn->ControllerNameTable,
+ L"PS/2 Keyboard Device",
+ FALSE
+ );
+
+ //
+ // Install protocol interfaces for the keyboard device.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ &ConsoleIn->ConIn,
+ &gEfiSimpleTextInputExProtocolGuid,
+ &ConsoleIn->ConInEx,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ StatusCode = EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_CONTROLLER_ERROR;
+ goto ErrorExit;
+ }
+
+ return Status;
+
+ErrorExit:
+ //
+ // Report error code
+ //
+ if (StatusCode != 0) {
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ StatusCode,
+ DevicePath
+ );
+ }
+
+ if ((ConsoleIn != NULL) && (ConsoleIn->ConIn.WaitForKey != NULL)) {
+ gBS->CloseEvent (ConsoleIn->ConIn.WaitForKey);
+ }
+
+ if ((ConsoleIn != NULL) && (ConsoleIn->TimerEvent != NULL)) {
+ gBS->CloseEvent (ConsoleIn->TimerEvent);
+ }
+
+ if ((ConsoleIn != NULL) && (ConsoleIn->ConInEx.WaitForKeyEx != NULL)) {
+ gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
+ }
+
+ if ((ConsoleIn != NULL) && (ConsoleIn->KeyNotifyProcessEvent != NULL)) {
+ gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
+ }
+
+ KbdFreeNotifyList (&ConsoleIn->NotifyList);
+ if ((ConsoleIn != NULL) && (ConsoleIn->ControllerNameTable != NULL)) {
+ FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
+ }
+
+ //
+ // Since there will be no timer handler for keyboard input any more,
+ // exhaust input data just in case there is still keyboard data left
+ //
+ if (ConsoleIn != NULL) {
+ Status1 = EFI_SUCCESS;
+ while (!EFI_ERROR (Status1) && (Status != EFI_DEVICE_ERROR)) {
+ Status1 = KeyboardRead (ConsoleIn, &Data);
+ }
+ }
+
+ if (ConsoleIn != NULL) {
+ gBS->FreePool (ConsoleIn);
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiSioProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+/**
+ Stop this driver on ControllerHandle. Support stopping any child handles
+ created by this driver.
+
+ @param This Protocol instance pointer.
+ @param ControllerHandle Handle of device to stop driver on
+ @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
+ children is zero stop the entire bus driver.
+ @param ChildHandleBuffer List of Child Handles to Stop.
+
+ @retval EFI_SUCCESS This driver is removed ControllerHandle
+ @retval other This driver was not removed from this device
+
+**/
+EFI_STATUS
+EFIAPI
+KbdControllerDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *ConIn;
+ KEYBOARD_CONSOLE_IN_DEV *ConsoleIn;
+ UINT8 Data;
+
+ //
+ // Disable Keyboard
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ (VOID **)&ConIn,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSimpleTextInputExProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ConsoleIn = KEYBOARD_CONSOLE_IN_DEV_FROM_THIS (ConIn);
+
+ //
+ // Report that the keyboard is being disabled
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_DISABLE,
+ ConsoleIn->DevicePath
+ );
+
+ if (ConsoleIn->TimerEvent != NULL) {
+ gBS->CloseEvent (ConsoleIn->TimerEvent);
+ ConsoleIn->TimerEvent = NULL;
+ }
+
+ //
+ // Since there will be no timer handler for keyboard input any more,
+ // exhaust input data just in case there is still keyboard data left
+ //
+ Status = EFI_SUCCESS;
+ while (!EFI_ERROR (Status)) {
+ Status = KeyboardRead (ConsoleIn, &Data);
+ }
+
+ //
+ // Uninstall the SimpleTextIn and SimpleTextInEx protocols
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ &ConsoleIn->ConIn,
+ &gEfiSimpleTextInputExProtocolGuid,
+ &ConsoleIn->ConInEx,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiSioProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Free other resources
+ //
+ if ((ConsoleIn->ConIn).WaitForKey != NULL) {
+ gBS->CloseEvent ((ConsoleIn->ConIn).WaitForKey);
+ (ConsoleIn->ConIn).WaitForKey = NULL;
+ }
+
+ if (ConsoleIn->ConInEx.WaitForKeyEx != NULL) {
+ gBS->CloseEvent (ConsoleIn->ConInEx.WaitForKeyEx);
+ ConsoleIn->ConInEx.WaitForKeyEx = NULL;
+ }
+
+ if (ConsoleIn->KeyNotifyProcessEvent != NULL) {
+ gBS->CloseEvent (ConsoleIn->KeyNotifyProcessEvent);
+ ConsoleIn->KeyNotifyProcessEvent = NULL;
+ }
+
+ KbdFreeNotifyList (&ConsoleIn->NotifyList);
+ FreeUnicodeStringTable (ConsoleIn->ControllerNameTable);
+ gBS->FreePool (ConsoleIn);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Free the waiting key notify list.
+
+ @param ListHead Pointer to list head
+
+ @retval EFI_INVALID_PARAMETER ListHead is NULL
+ @retval EFI_SUCCESS Success to free NotifyList
+**/
+EFI_STATUS
+KbdFreeNotifyList (
+ IN OUT LIST_ENTRY *ListHead
+ )
+{
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
+
+ if (ListHead == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ while (!IsListEmpty (ListHead)) {
+ NotifyNode = CR (
+ ListHead->ForwardLink,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY,
+ NotifyEntry,
+ KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
+ );
+ RemoveEntryList (ListHead->ForwardLink);
+ gBS->FreePool (NotifyNode);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The module Entry Point for module Ps2Keyboard.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializePs2Keyboard (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gKeyboardControllerDriver,
+ ImageHandle,
+ &gPs2KeyboardComponentName,
+ &gPs2KeyboardComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
index 7b4db9c778..f81add6257 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2Keyboard.h
@@ -1,565 +1,565 @@
-/** @file
- PS/2 keyboard driver header file
-
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _PS2KEYBOARD_H_
-#define _PS2KEYBOARD_H_
-
-#include <Uefi.h>
-
-#include <Protocol/SuperIo.h>
-#include <Protocol/SimpleTextIn.h>
-#include <Protocol/SimpleTextInEx.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/Ps2Policy.h>
-
-#include <Library/IoLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/ReportStatusCodeLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/TimerLib.h>
-#include <Library/PcdLib.h>
-
-//
-// Global Variables
-//
-extern EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver;
-extern EFI_COMPONENT_NAME_PROTOCOL gPs2KeyboardComponentName;
-extern EFI_COMPONENT_NAME2_PROTOCOL gPs2KeyboardComponentName2;
-
-//
-// Driver Private Data
-//
-#define KEYBOARD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32 ('k', 'k', 'e', 'y')
-#define KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n')
-
-typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY {
- UINTN Signature;
- EFI_KEY_DATA KeyData;
- EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
- LIST_ENTRY NotifyEntry;
-} KEYBOARD_CONSOLE_IN_EX_NOTIFY;
-
-#define KEYBOARD_SCAN_CODE_MAX_COUNT 32
-typedef struct {
- UINT8 Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];
- UINTN Head;
- UINTN Tail;
-} SCAN_CODE_QUEUE;
-
-#define KEYBOARD_EFI_KEY_MAX_COUNT 256
-typedef struct {
- EFI_KEY_DATA Buffer[KEYBOARD_EFI_KEY_MAX_COUNT];
- UINTN Head;
- UINTN Tail;
-} EFI_KEY_QUEUE;
-
-typedef struct {
- UINTN Signature;
-
- EFI_HANDLE Handle;
- EFI_SIMPLE_TEXT_INPUT_PROTOCOL ConIn;
- EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL ConInEx;
-
- EFI_EVENT TimerEvent;
-
- UINT32 DataRegisterAddress;
- UINT32 StatusRegisterAddress;
- UINT32 CommandRegisterAddress;
-
- BOOLEAN LeftCtrl;
- BOOLEAN RightCtrl;
- BOOLEAN LeftAlt;
- BOOLEAN RightAlt;
- BOOLEAN LeftShift;
- BOOLEAN RightShift;
- BOOLEAN LeftLogo;
- BOOLEAN RightLogo;
- BOOLEAN Menu;
- BOOLEAN SysReq;
-
- BOOLEAN CapsLock;
- BOOLEAN NumLock;
- BOOLEAN ScrollLock;
-
- BOOLEAN IsSupportPartialKey;
- //
- // Queue storing key scancodes
- //
- SCAN_CODE_QUEUE ScancodeQueue;
- EFI_KEY_QUEUE EfiKeyQueue;
- EFI_KEY_QUEUE EfiKeyQueueForNotify;
-
- //
- // Error state
- //
- BOOLEAN KeyboardErr;
-
- EFI_UNICODE_STRING_TABLE *ControllerNameTable;
-
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- //
- // Notification Function List
- //
- LIST_ENTRY NotifyList;
- EFI_EVENT KeyNotifyProcessEvent;
-} KEYBOARD_CONSOLE_IN_DEV;
-
-#define KEYBOARD_CONSOLE_IN_DEV_FROM_THIS(a) CR (a, KEYBOARD_CONSOLE_IN_DEV, ConIn, KEYBOARD_CONSOLE_IN_DEV_SIGNATURE)
-#define TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS(a) \
- CR (a, \
- KEYBOARD_CONSOLE_IN_DEV, \
- ConInEx, \
- KEYBOARD_CONSOLE_IN_DEV_SIGNATURE \
- )
-
-#define TABLE_END 0x0
-
-//
-// Driver entry point
-//
-
-/**
- The user Entry Point for module Ps2Keyboard. The user code starts with this function.
-
- @param[in] ImageHandle The firmware allocated handle for the EFI image.
- @param[in] SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The entry point is executed successfully.
- @retval other Some error occurs when executing this entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-InstallPs2KeyboardDriver (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-#define KEYBOARD_8042_DATA_REGISTER 0x60
-#define KEYBOARD_8042_STATUS_REGISTER 0x64
-#define KEYBOARD_8042_COMMAND_REGISTER 0x64
-
-#define KEYBOARD_KBEN 0xF4
-#define KEYBOARD_CMDECHO_ACK 0xFA
-
-#define KEYBOARD_MAX_TRY 256 // 256
-#define KEYBOARD_TIMEOUT 65536 // 0.07s
-#define KEYBOARD_WAITFORVALUE_TIMEOUT 1000000 // 1s
-#define KEYBOARD_BAT_TIMEOUT 4000000 // 4s
-#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
-#define SCANCODE_EXTENDED0 0xE0
-#define SCANCODE_EXTENDED1 0xE1
-#define SCANCODE_CTRL_MAKE 0x1D
-#define SCANCODE_CTRL_BREAK 0x9D
-#define SCANCODE_ALT_MAKE 0x38
-#define SCANCODE_ALT_BREAK 0xB8
-#define SCANCODE_LEFT_SHIFT_MAKE 0x2A
-#define SCANCODE_LEFT_SHIFT_BREAK 0xAA
-#define SCANCODE_RIGHT_SHIFT_MAKE 0x36
-#define SCANCODE_RIGHT_SHIFT_BREAK 0xB6
-#define SCANCODE_CAPS_LOCK_MAKE 0x3A
-#define SCANCODE_NUM_LOCK_MAKE 0x45
-#define SCANCODE_SCROLL_LOCK_MAKE 0x46
-#define SCANCODE_DELETE_MAKE 0x53
-#define SCANCODE_LEFT_LOGO_MAKE 0x5B// GUI key defined in Keyboard scan code
-#define SCANCODE_LEFT_LOGO_BREAK 0xDB
-#define SCANCODE_RIGHT_LOGO_MAKE 0x5C
-#define SCANCODE_RIGHT_LOGO_BREAK 0xDC
-#define SCANCODE_MENU_MAKE 0x5D// APPS key defined in Keyboard scan code
-#define SCANCODE_MENU_BREAK 0xDD
-#define SCANCODE_SYS_REQ_MAKE 0x37
-#define SCANCODE_SYS_REQ_BREAK 0xB7
-#define SCANCODE_SYS_REQ_MAKE_WITH_ALT 0x54
-#define SCANCODE_SYS_REQ_BREAK_WITH_ALT 0xD4
-
-#define SCANCODE_MAX_MAKE 0x60
-
-#define KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA BIT0 ///< 0 - Output register has no data; 1 - Output register has data
-#define KEYBOARD_STATUS_REGISTER_HAS_INPUT_DATA BIT1 ///< 0 - Input register has no data; 1 - Input register has data
-#define KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG BIT2 ///< Set to 0 after power on reset
-#define KEYBOARD_STATUS_REGISTER_INPUT_DATA_TYPE BIT3 ///< 0 - Data in input register is data; 1 - Data in input register is command
-#define KEYBOARD_STATUS_REGISTER_ENABLE_FLAG BIT4 ///< 0 - Keyboard is disable; 1 - Keyboard is enable
-#define KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT BIT5 ///< 0 - Transmit is complete without timeout; 1 - Transmit is timeout without complete
-#define KEYBOARD_STATUS_REGISTER_RECEIVE_TIMEOUT BIT6 ///< 0 - Receive is complete without timeout; 1 - Receive is timeout without complete
-#define KEYBOARD_STATUS_REGISTER_PARITY BIT7 ///< 0 - Odd parity; 1 - Even parity
-
-#define KEYBOARD_8042_COMMAND_READ 0x20
-#define KEYBOARD_8042_COMMAND_WRITE 0x60
-#define KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE 0xA7
-#define KEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE 0xA8
-#define KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST 0xAA
-#define KEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST 0xAB
-#define KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE 0xAD
-
-#define KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA 0xF4
-#define KEYBOARD_8048_COMMAND_RESET 0xFF
-#define KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET 0xF0
-
-#define KEYBOARD_8048_RETURN_8042_BAT_SUCCESS 0xAA
-#define KEYBOARD_8048_RETURN_8042_BAT_ERROR 0xFC
-#define KEYBOARD_8048_RETURN_8042_ACK 0xFA
-
-//
-// Keyboard Controller Status
-//
-#define KBC_PARE 0x80 // Parity Error
-#define KBC_TIM 0x40 // General Time Out
-
-//
-// Other functions that are used among .c files
-//
-
-/**
- Show keyboard status lights according to
- indicators in ConsoleIn.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
-
- @return status
-
-**/
-EFI_STATUS
-UpdateStatusLights (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- );
-
-/**
- write key to keyboard.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
- @param Data value wanted to be written
-
- @retval EFI_TIMEOUT - GC_TODO: Add description for return value
- @retval EFI_SUCCESS - GC_TODO: Add description for return value
-
-**/
-EFI_STATUS
-KeyboardRead (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- OUT UINT8 *Data
- );
-
-/**
- Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
-
- The function is always called in TPL_NOTIFY.
-
- @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer
-
-**/
-VOID
-KeyGetchar (
- IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- );
-
-/**
- Process key notify.
-
- @param Event Indicates the event that invoke this function.
- @param Context Indicates the calling context.
-**/
-VOID
-EFIAPI
-KeyNotifyProcessHandler (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-/**
- Perform 8042 controller and keyboard Initialization.
- If ExtendedVerification is TRUE, do additional test for
- the keyboard interface
-
- @param ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer
- @param ExtendedVerification - indicates a thorough initialization
-
- @retval EFI_DEVICE_ERROR Fail to init keyboard
- @retval EFI_SUCCESS Success to init keyboard
-**/
-EFI_STATUS
-InitKeyboard (
- IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- IN BOOLEAN ExtendedVerification
- );
-
-/**
- Timer event handler: read a series of scancodes from 8042
- and put them into memory scancode buffer.
- it read as much scancodes to either fill
- the memory buffer or empty the keyboard buffer.
- It is registered as running under TPL_NOTIFY
-
- @param Event - The timer event
- @param Context - A KEYBOARD_CONSOLE_IN_DEV pointer
-
-**/
-VOID
-EFIAPI
-KeyboardTimerHandler (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-/**
- logic reset keyboard
- Implement SIMPLE_TEXT_IN.Reset()
- Perform 8042 controller and keyboard initialization
-
- @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
- @param ExtendedVerification Indicate that the driver may perform a more
- exhaustive verification operation of the device during
- reset, now this par is ignored in this driver
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardEfiReset (
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- );
-
-/**
- Implement SIMPLE_TEXT_IN.ReadKeyStroke().
- Retrieve key values for driver user.
-
- @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
- @param Key The output buffer for key value
-
- @retval EFI_SUCCESS success to read key stroke
- @retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
-**/
-EFI_STATUS
-EFIAPI
-KeyboardReadKeyStroke (
- IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
- OUT EFI_INPUT_KEY *Key
- );
-
-/**
- Event notification function for SIMPLE_TEXT_IN.WaitForKey event
- Signal the event if there is key available
-
- @param Event the event object
- @param Context waiting context
-
-**/
-VOID
-EFIAPI
-KeyboardWaitForKey (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-/**
- Read status register.
-
- @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
-
- @return value in status register
-
-**/
-UINT8
-KeyReadStatusRegister (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- );
-
-/**
- Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command
- If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device
- should not be in system.
-
- @param[in] ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
-
- @retval TRUE Keyboard in System.
- @retval FALSE Keyboard not in System.
-**/
-BOOLEAN
-EFIAPI
-CheckKeyboardConnect (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
- );
-
-/**
- Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
- Signal the event if there is key available
-
- @param Event event object
- @param Context waiting context
-
-**/
-VOID
-EFIAPI
-KeyboardWaitForKeyEx (
- IN EFI_EVENT Event,
- IN VOID *Context
- );
-
-//
-// Simple Text Input Ex protocol function prototypes
-//
-
-/**
- Reset the input device and optionally run diagnostics
-
- @param This - Protocol instance pointer.
- @param ExtendedVerification - Driver may perform diagnostics on reset.
-
- @retval EFI_SUCCESS - The device was reset.
- @retval EFI_DEVICE_ERROR - The device is not functioning properly and could
- not be reset.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardEfiResetEx (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN BOOLEAN ExtendedVerification
- );
-
-/**
- Reads the next keystroke from the input device. The WaitForKey Event can
- be used to test for existence of a keystroke via WaitForEvent () call.
-
-
- @param This - Protocol instance pointer.
- @param KeyData - A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
- @retval EFI_SUCCESS - The keystroke information was returned.
- @retval EFI_NOT_READY - There was no keystroke data available.
- @retval EFI_DEVICE_ERROR - The keystroke information was not returned due to
- hardware errors.
- @retval EFI_INVALID_PARAMETER - KeyData is NULL.
- @retval EFI_UNSUPPORTED - The device does not support the ability to read
- keystroke data.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardReadKeyStrokeEx (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- OUT EFI_KEY_DATA *KeyData
- );
-
-/**
- Set certain state for the input device.
-
- @param This - Protocol instance pointer.
- @param KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
- state for the input device.
-
- @retval EFI_SUCCESS - The device state was set successfully.
- @retval EFI_DEVICE_ERROR - The device is not functioning correctly and could
- not have the setting adjusted.
- @retval EFI_UNSUPPORTED - The device does not have the ability to set its state.
- @retval EFI_INVALID_PARAMETER - KeyToggleState is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardSetState (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN EFI_KEY_TOGGLE_STATE *KeyToggleState
- );
-
-/**
- Register a notification function for a particular keystroke for the input device.
-
- @param This - Protocol instance pointer.
- @param KeyData - A pointer to a buffer that is filled in with the keystroke
- information data for the key that was pressed. If KeyData.Key,
- KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0,
- then any incomplete keystroke will trigger a notification of the KeyNotificationFunction.
- @param KeyNotificationFunction - Points to the function to be called when the key
- sequence is typed specified by KeyData. This notification function
- should be called at <=TPL_CALLBACK.
- @param NotifyHandle - Points to the unique handle assigned to the registered notification.
-
- @retval EFI_SUCCESS - The notification function was registered successfully.
- @retval EFI_OUT_OF_RESOURCES - Unable to allocate resources for necessary data structures.
- @retval EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardRegisterKeyNotify (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN EFI_KEY_DATA *KeyData,
- IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
- OUT VOID **NotifyHandle
- );
-
-/**
- Remove a registered notification function from a particular keystroke.
-
- @param This - Protocol instance pointer.
- @param NotificationHandle - The handle of the notification function being unregistered.
-
-
- @retval EFI_SUCCESS - The notification function was unregistered successfully.
- @retval EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
- @retval EFI_NOT_FOUND - Can not find the matching entry in database.
-
-**/
-EFI_STATUS
-EFIAPI
-KeyboardUnregisterKeyNotify (
- IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
- IN VOID *NotificationHandle
- );
-
-/**
- Push one key data to the EFI key buffer.
-
- @param Queue Pointer to instance of EFI_KEY_QUEUE.
- @param KeyData The key data to push.
-**/
-VOID
-PushEfikeyBufTail (
- IN EFI_KEY_QUEUE *Queue,
- IN EFI_KEY_DATA *KeyData
- );
-
-/**
- Judge whether is a registered key
-
- @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was registered.
- @param InputData A pointer to a buffer that is filled in with the keystroke
- state data for the key that was pressed.
-
- @retval TRUE Key be pressed matches a registered key.
- @retval FALSE Match failed.
-
-**/
-BOOLEAN
-IsKeyRegistered (
- IN EFI_KEY_DATA *RegsiteredData,
- IN EFI_KEY_DATA *InputData
- );
-
-/**
- Initialize the key state.
-
- @param ConsoleIn The KEYBOARD_CONSOLE_IN_DEV instance.
- @param KeyState A pointer to receive the key state information.
-**/
-VOID
-InitializeKeyState (
- IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
- OUT EFI_KEY_STATE *KeyState
- );
-
-#endif
+/** @file
+ PS/2 keyboard driver header file
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _PS2KEYBOARD_H_
+#define _PS2KEYBOARD_H_
+
+#include <Uefi.h>
+
+#include <Protocol/SuperIo.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextInEx.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/Ps2Policy.h>
+
+#include <Library/IoLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gKeyboardControllerDriver;
+extern EFI_COMPONENT_NAME_PROTOCOL gPs2KeyboardComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gPs2KeyboardComponentName2;
+
+//
+// Driver Private Data
+//
+#define KEYBOARD_CONSOLE_IN_DEV_SIGNATURE SIGNATURE_32 ('k', 'k', 'e', 'y')
+#define KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('k', 'c', 'e', 'n')
+
+typedef struct _KEYBOARD_CONSOLE_IN_EX_NOTIFY {
+ UINTN Signature;
+ EFI_KEY_DATA KeyData;
+ EFI_KEY_NOTIFY_FUNCTION KeyNotificationFn;
+ LIST_ENTRY NotifyEntry;
+} KEYBOARD_CONSOLE_IN_EX_NOTIFY;
+
+#define KEYBOARD_SCAN_CODE_MAX_COUNT 32
+typedef struct {
+ UINT8 Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];
+ UINTN Head;
+ UINTN Tail;
+} SCAN_CODE_QUEUE;
+
+#define KEYBOARD_EFI_KEY_MAX_COUNT 256
+typedef struct {
+ EFI_KEY_DATA Buffer[KEYBOARD_EFI_KEY_MAX_COUNT];
+ UINTN Head;
+ UINTN Tail;
+} EFI_KEY_QUEUE;
+
+typedef struct {
+ UINTN Signature;
+
+ EFI_HANDLE Handle;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL ConIn;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL ConInEx;
+
+ EFI_EVENT TimerEvent;
+
+ UINT32 DataRegisterAddress;
+ UINT32 StatusRegisterAddress;
+ UINT32 CommandRegisterAddress;
+
+ BOOLEAN LeftCtrl;
+ BOOLEAN RightCtrl;
+ BOOLEAN LeftAlt;
+ BOOLEAN RightAlt;
+ BOOLEAN LeftShift;
+ BOOLEAN RightShift;
+ BOOLEAN LeftLogo;
+ BOOLEAN RightLogo;
+ BOOLEAN Menu;
+ BOOLEAN SysReq;
+
+ BOOLEAN CapsLock;
+ BOOLEAN NumLock;
+ BOOLEAN ScrollLock;
+
+ BOOLEAN IsSupportPartialKey;
+ //
+ // Queue storing key scancodes
+ //
+ SCAN_CODE_QUEUE ScancodeQueue;
+ EFI_KEY_QUEUE EfiKeyQueue;
+ EFI_KEY_QUEUE EfiKeyQueueForNotify;
+
+ //
+ // Error state
+ //
+ BOOLEAN KeyboardErr;
+
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ //
+ // Notification Function List
+ //
+ LIST_ENTRY NotifyList;
+ EFI_EVENT KeyNotifyProcessEvent;
+} KEYBOARD_CONSOLE_IN_DEV;
+
+#define KEYBOARD_CONSOLE_IN_DEV_FROM_THIS(a) CR (a, KEYBOARD_CONSOLE_IN_DEV, ConIn, KEYBOARD_CONSOLE_IN_DEV_SIGNATURE)
+#define TEXT_INPUT_EX_KEYBOARD_CONSOLE_IN_DEV_FROM_THIS(a) \
+ CR (a, \
+ KEYBOARD_CONSOLE_IN_DEV, \
+ ConInEx, \
+ KEYBOARD_CONSOLE_IN_DEV_SIGNATURE \
+ )
+
+#define TABLE_END 0x0
+
+//
+// Driver entry point
+//
+
+/**
+ The user Entry Point for module Ps2Keyboard. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPs2KeyboardDriver (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#define KEYBOARD_8042_DATA_REGISTER 0x60
+#define KEYBOARD_8042_STATUS_REGISTER 0x64
+#define KEYBOARD_8042_COMMAND_REGISTER 0x64
+
+#define KEYBOARD_KBEN 0xF4
+#define KEYBOARD_CMDECHO_ACK 0xFA
+
+#define KEYBOARD_MAX_TRY 256 // 256
+#define KEYBOARD_TIMEOUT 65536 // 0.07s
+#define KEYBOARD_WAITFORVALUE_TIMEOUT 1000000 // 1s
+#define KEYBOARD_BAT_TIMEOUT 4000000 // 4s
+#define KEYBOARD_TIMER_INTERVAL 200000 // 0.02s
+#define SCANCODE_EXTENDED0 0xE0
+#define SCANCODE_EXTENDED1 0xE1
+#define SCANCODE_CTRL_MAKE 0x1D
+#define SCANCODE_CTRL_BREAK 0x9D
+#define SCANCODE_ALT_MAKE 0x38
+#define SCANCODE_ALT_BREAK 0xB8
+#define SCANCODE_LEFT_SHIFT_MAKE 0x2A
+#define SCANCODE_LEFT_SHIFT_BREAK 0xAA
+#define SCANCODE_RIGHT_SHIFT_MAKE 0x36
+#define SCANCODE_RIGHT_SHIFT_BREAK 0xB6
+#define SCANCODE_CAPS_LOCK_MAKE 0x3A
+#define SCANCODE_NUM_LOCK_MAKE 0x45
+#define SCANCODE_SCROLL_LOCK_MAKE 0x46
+#define SCANCODE_DELETE_MAKE 0x53
+#define SCANCODE_LEFT_LOGO_MAKE 0x5B// GUI key defined in Keyboard scan code
+#define SCANCODE_LEFT_LOGO_BREAK 0xDB
+#define SCANCODE_RIGHT_LOGO_MAKE 0x5C
+#define SCANCODE_RIGHT_LOGO_BREAK 0xDC
+#define SCANCODE_MENU_MAKE 0x5D// APPS key defined in Keyboard scan code
+#define SCANCODE_MENU_BREAK 0xDD
+#define SCANCODE_SYS_REQ_MAKE 0x37
+#define SCANCODE_SYS_REQ_BREAK 0xB7
+#define SCANCODE_SYS_REQ_MAKE_WITH_ALT 0x54
+#define SCANCODE_SYS_REQ_BREAK_WITH_ALT 0xD4
+
+#define SCANCODE_MAX_MAKE 0x60
+
+#define KEYBOARD_STATUS_REGISTER_HAS_OUTPUT_DATA BIT0 ///< 0 - Output register has no data; 1 - Output register has data
+#define KEYBOARD_STATUS_REGISTER_HAS_INPUT_DATA BIT1 ///< 0 - Input register has no data; 1 - Input register has data
+#define KEYBOARD_STATUS_REGISTER_SYSTEM_FLAG BIT2 ///< Set to 0 after power on reset
+#define KEYBOARD_STATUS_REGISTER_INPUT_DATA_TYPE BIT3 ///< 0 - Data in input register is data; 1 - Data in input register is command
+#define KEYBOARD_STATUS_REGISTER_ENABLE_FLAG BIT4 ///< 0 - Keyboard is disable; 1 - Keyboard is enable
+#define KEYBOARD_STATUS_REGISTER_TRANSMIT_TIMEOUT BIT5 ///< 0 - Transmit is complete without timeout; 1 - Transmit is timeout without complete
+#define KEYBOARD_STATUS_REGISTER_RECEIVE_TIMEOUT BIT6 ///< 0 - Receive is complete without timeout; 1 - Receive is timeout without complete
+#define KEYBOARD_STATUS_REGISTER_PARITY BIT7 ///< 0 - Odd parity; 1 - Even parity
+
+#define KEYBOARD_8042_COMMAND_READ 0x20
+#define KEYBOARD_8042_COMMAND_WRITE 0x60
+#define KEYBOARD_8042_COMMAND_DISABLE_MOUSE_INTERFACE 0xA7
+#define KEYBOARD_8042_COMMAND_ENABLE_MOUSE_INTERFACE 0xA8
+#define KEYBOARD_8042_COMMAND_CONTROLLER_SELF_TEST 0xAA
+#define KEYBOARD_8042_COMMAND_KEYBOARD_INTERFACE_SELF_TEST 0xAB
+#define KEYBOARD_8042_COMMAND_DISABLE_KEYBOARD_INTERFACE 0xAD
+
+#define KEYBOARD_8048_COMMAND_CLEAR_OUTPUT_DATA 0xF4
+#define KEYBOARD_8048_COMMAND_RESET 0xFF
+#define KEYBOARD_8048_COMMAND_SELECT_SCAN_CODE_SET 0xF0
+
+#define KEYBOARD_8048_RETURN_8042_BAT_SUCCESS 0xAA
+#define KEYBOARD_8048_RETURN_8042_BAT_ERROR 0xFC
+#define KEYBOARD_8048_RETURN_8042_ACK 0xFA
+
+//
+// Keyboard Controller Status
+//
+#define KBC_PARE 0x80 // Parity Error
+#define KBC_TIM 0x40 // General Time Out
+
+//
+// Other functions that are used among .c files
+//
+
+/**
+ Show keyboard status lights according to
+ indicators in ConsoleIn.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+
+ @return status
+
+**/
+EFI_STATUS
+UpdateStatusLights (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ );
+
+/**
+ write key to keyboard.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+ @param Data value wanted to be written
+
+ @retval EFI_TIMEOUT - GC_TODO: Add description for return value
+ @retval EFI_SUCCESS - GC_TODO: Add description for return value
+
+**/
+EFI_STATUS
+KeyboardRead (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ OUT UINT8 *Data
+ );
+
+/**
+ Get scancode from scancode buffer and translate into EFI-scancode and unicode defined by EFI spec.
+
+ The function is always called in TPL_NOTIFY.
+
+ @param ConsoleIn KEYBOARD_CONSOLE_IN_DEV instance pointer
+
+**/
+VOID
+KeyGetchar (
+ IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ );
+
+/**
+ Process key notify.
+
+ @param Event Indicates the event that invoke this function.
+ @param Context Indicates the calling context.
+**/
+VOID
+EFIAPI
+KeyNotifyProcessHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Perform 8042 controller and keyboard Initialization.
+ If ExtendedVerification is TRUE, do additional test for
+ the keyboard interface
+
+ @param ConsoleIn - KEYBOARD_CONSOLE_IN_DEV instance pointer
+ @param ExtendedVerification - indicates a thorough initialization
+
+ @retval EFI_DEVICE_ERROR Fail to init keyboard
+ @retval EFI_SUCCESS Success to init keyboard
+**/
+EFI_STATUS
+InitKeyboard (
+ IN OUT KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Timer event handler: read a series of scancodes from 8042
+ and put them into memory scancode buffer.
+ it read as much scancodes to either fill
+ the memory buffer or empty the keyboard buffer.
+ It is registered as running under TPL_NOTIFY
+
+ @param Event - The timer event
+ @param Context - A KEYBOARD_CONSOLE_IN_DEV pointer
+
+**/
+VOID
+EFIAPI
+KeyboardTimerHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ logic reset keyboard
+ Implement SIMPLE_TEXT_IN.Reset()
+ Perform 8042 controller and keyboard initialization
+
+ @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+ @param ExtendedVerification Indicate that the driver may perform a more
+ exhaustive verification operation of the device during
+ reset, now this par is ignored in this driver
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardEfiReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Implement SIMPLE_TEXT_IN.ReadKeyStroke().
+ Retrieve key values for driver user.
+
+ @param This Pointer to instance of EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+ @param Key The output buffer for key value
+
+ @retval EFI_SUCCESS success to read key stroke
+ @retval EFI_UNSUPPORTED The device does not support the ability to read keystroke data.
+**/
+EFI_STATUS
+EFIAPI
+KeyboardReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+/**
+ Event notification function for SIMPLE_TEXT_IN.WaitForKey event
+ Signal the event if there is key available
+
+ @param Event the event object
+ @param Context waiting context
+
+**/
+VOID
+EFIAPI
+KeyboardWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Read status register.
+
+ @param ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+
+ @return value in status register
+
+**/
+UINT8
+KeyReadStatusRegister (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ );
+
+/**
+ Check whether there is Ps/2 Keyboard device in system by 0xF4 Keyboard Command
+ If Keyboard receives 0xF4, it will respond with 'ACK'. If it doesn't respond, the device
+ should not be in system.
+
+ @param[in] ConsoleIn Pointer to instance of KEYBOARD_CONSOLE_IN_DEV
+
+ @retval TRUE Keyboard in System.
+ @retval FALSE Keyboard not in System.
+**/
+BOOLEAN
+EFIAPI
+CheckKeyboardConnect (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn
+ );
+
+/**
+ Event notification function for SIMPLE_TEXT_INPUT_EX_PROTOCOL.WaitForKeyEx event
+ Signal the event if there is key available
+
+ @param Event event object
+ @param Context waiting context
+
+**/
+VOID
+EFIAPI
+KeyboardWaitForKeyEx (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+//
+// Simple Text Input Ex protocol function prototypes
+//
+
+/**
+ Reset the input device and optionally run diagnostics
+
+ @param This - Protocol instance pointer.
+ @param ExtendedVerification - Driver may perform diagnostics on reset.
+
+ @retval EFI_SUCCESS - The device was reset.
+ @retval EFI_DEVICE_ERROR - The device is not functioning properly and could
+ not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardEfiResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Reads the next keystroke from the input device. The WaitForKey Event can
+ be used to test for existence of a keystroke via WaitForEvent () call.
+
+
+ @param This - Protocol instance pointer.
+ @param KeyData - A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval EFI_SUCCESS - The keystroke information was returned.
+ @retval EFI_NOT_READY - There was no keystroke data available.
+ @retval EFI_DEVICE_ERROR - The keystroke information was not returned due to
+ hardware errors.
+ @retval EFI_INVALID_PARAMETER - KeyData is NULL.
+ @retval EFI_UNSUPPORTED - The device does not support the ability to read
+ keystroke data.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ );
+
+/**
+ Set certain state for the input device.
+
+ @param This - Protocol instance pointer.
+ @param KeyToggleState - A pointer to the EFI_KEY_TOGGLE_STATE to set the
+ state for the input device.
+
+ @retval EFI_SUCCESS - The device state was set successfully.
+ @retval EFI_DEVICE_ERROR - The device is not functioning correctly and could
+ not have the setting adjusted.
+ @retval EFI_UNSUPPORTED - The device does not have the ability to set its state.
+ @retval EFI_INVALID_PARAMETER - KeyToggleState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+ );
+
+/**
+ Register a notification function for a particular keystroke for the input device.
+
+ @param This - Protocol instance pointer.
+ @param KeyData - A pointer to a buffer that is filled in with the keystroke
+ information data for the key that was pressed. If KeyData.Key,
+ KeyData.KeyState.KeyToggleState and KeyData.KeyState.KeyShiftState are 0,
+ then any incomplete keystroke will trigger a notification of the KeyNotificationFunction.
+ @param KeyNotificationFunction - Points to the function to be called when the key
+ sequence is typed specified by KeyData. This notification function
+ should be called at <=TPL_CALLBACK.
+ @param NotifyHandle - Points to the unique handle assigned to the registered notification.
+
+ @retval EFI_SUCCESS - The notification function was registered successfully.
+ @retval EFI_OUT_OF_RESOURCES - Unable to allocate resources for necessary data structures.
+ @retval EFI_INVALID_PARAMETER - KeyData or NotifyHandle is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT VOID **NotifyHandle
+ );
+
+/**
+ Remove a registered notification function from a particular keystroke.
+
+ @param This - Protocol instance pointer.
+ @param NotificationHandle - The handle of the notification function being unregistered.
+
+
+ @retval EFI_SUCCESS - The notification function was unregistered successfully.
+ @retval EFI_INVALID_PARAMETER - The NotificationHandle is invalid.
+ @retval EFI_NOT_FOUND - Can not find the matching entry in database.
+
+**/
+EFI_STATUS
+EFIAPI
+KeyboardUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN VOID *NotificationHandle
+ );
+
+/**
+ Push one key data to the EFI key buffer.
+
+ @param Queue Pointer to instance of EFI_KEY_QUEUE.
+ @param KeyData The key data to push.
+**/
+VOID
+PushEfikeyBufTail (
+ IN EFI_KEY_QUEUE *Queue,
+ IN EFI_KEY_DATA *KeyData
+ );
+
+/**
+ Judge whether is a registered key
+
+ @param RegsiteredData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was registered.
+ @param InputData A pointer to a buffer that is filled in with the keystroke
+ state data for the key that was pressed.
+
+ @retval TRUE Key be pressed matches a registered key.
+ @retval FALSE Match failed.
+
+**/
+BOOLEAN
+IsKeyRegistered (
+ IN EFI_KEY_DATA *RegsiteredData,
+ IN EFI_KEY_DATA *InputData
+ );
+
+/**
+ Initialize the key state.
+
+ @param ConsoleIn The KEYBOARD_CONSOLE_IN_DEV instance.
+ @param KeyState A pointer to receive the key state information.
+**/
+VOID
+InitializeKeyState (
+ IN KEYBOARD_CONSOLE_IN_DEV *ConsoleIn,
+ OUT EFI_KEY_STATE *KeyState
+ );
+
+#endif
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
index d551c53fa4..360054b22a 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf
@@ -1,78 +1,78 @@
-## @file
-# Ps2 Keyboard Driver.
-#
-# Ps2 Keyboard Driver for UEFI. The keyboard type implemented follows IBM
-# compatible PS2 protocol using Scan Code Set 1.
-#
-# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = Ps2KeyboardDxe
- MODULE_UNI_FILE = Ps2KeyboardDxe.uni
- FILE_GUID = C4D1F932-821F-4744-BF06-6D30F7730F8D
- MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = InitializePs2Keyboard
-
-#
-# VALID_ARCHITECTURES = IA32 X64 EBC
-# DRIVER_BINDING = gKeyboardControllerDriver;
-# COMPONENT_NAME = gPs2KeyboardComponentName;
-# COMPONENT_NAME2 = gPs2KeyboardComponentName2;
-#
-
-[Sources]
- ComponentName.c
- Ps2Keyboard.h
- Ps2KbdCtrller.c
- Ps2KbdTextIn.c
- Ps2Keyboard.c
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- MemoryAllocationLib
- UefiRuntimeServicesTableLib
- DebugLib
- ReportStatusCodeLib
- UefiBootServicesTableLib
- UefiLib
- UefiDriverEntryPoint
- BaseLib
- BaseMemoryLib
- TimerLib
- PcdLib
- IoLib
-
-[Protocols]
- gEfiSimpleTextInProtocolGuid ## BY_START
- gEfiSimpleTextInputExProtocolGuid ## BY_START
- gEfiPs2PolicyProtocolGuid ## SOMETIMES_CONSUMES
- gEfiSioProtocolGuid ## TO_START
- gEfiDevicePathProtocolGuid ## TO_START
-
-[FeaturePcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification ## CONSUMES
-
-[Pcd]
- gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection ## SOMETIMES_CONSUMES
-
-#
-# [Event]
-#
-# ##
-# # Timer event used to read key strokes at a regular interval.
-# #
-# EVENT_TYPE_PERIODIC_TIMER ## CONSUMES
-#
-
-[UserExtensions.TianoCore."ExtraFiles"]
- Ps2KeyboardDxeExtra.uni
+## @file
+# Ps2 Keyboard Driver.
+#
+# Ps2 Keyboard Driver for UEFI. The keyboard type implemented follows IBM
+# compatible PS2 protocol using Scan Code Set 1.
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = Ps2KeyboardDxe
+ MODULE_UNI_FILE = Ps2KeyboardDxe.uni
+ FILE_GUID = C4D1F932-821F-4744-BF06-6D30F7730F8D
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializePs2Keyboard
+
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+# DRIVER_BINDING = gKeyboardControllerDriver;
+# COMPONENT_NAME = gPs2KeyboardComponentName;
+# COMPONENT_NAME2 = gPs2KeyboardComponentName2;
+#
+
+[Sources]
+ ComponentName.c
+ Ps2Keyboard.h
+ Ps2KbdCtrller.c
+ Ps2KbdTextIn.c
+ Ps2Keyboard.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiRuntimeServicesTableLib
+ DebugLib
+ ReportStatusCodeLib
+ UefiBootServicesTableLib
+ UefiLib
+ UefiDriverEntryPoint
+ BaseLib
+ BaseMemoryLib
+ TimerLib
+ PcdLib
+ IoLib
+
+[Protocols]
+ gEfiSimpleTextInProtocolGuid ## BY_START
+ gEfiSimpleTextInputExProtocolGuid ## BY_START
+ gEfiPs2PolicyProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiSioProtocolGuid ## TO_START
+ gEfiDevicePathProtocolGuid ## TO_START
+
+[FeaturePcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPs2KbdExtendedVerification ## CONSUMES
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdFastPS2Detection ## SOMETIMES_CONSUMES
+
+#
+# [Event]
+#
+# ##
+# # Timer event used to read key strokes at a regular interval.
+# #
+# EVENT_TYPE_PERIODIC_TIMER ## CONSUMES
+#
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ Ps2KeyboardDxeExtra.uni
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.uni b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.uni
index f1d383efe0..16aa2d0025 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.uni
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.uni
@@ -1,17 +1,17 @@
-// /** @file
-// Ps2 Keyboard Driver.
-//
-// Ps2 Keyboard Driver for UEFI. The keyboard type implemented follows IBM
-// compatible PS2 protocol using Scan Code Set 1.
-//
-// Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "Ps2 Keyboard Driver"
-
-#string STR_MODULE_DESCRIPTION #language en-US "Ps2 Keyboard Driver for UEFI. The keyboard type implemented follows IBM compatible PS2 protocol using Scan Code Set 1."
-
+// /** @file
+// Ps2 Keyboard Driver.
+//
+// Ps2 Keyboard Driver for UEFI. The keyboard type implemented follows IBM
+// compatible PS2 protocol using Scan Code Set 1.
+//
+// Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Ps2 Keyboard Driver"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Ps2 Keyboard Driver for UEFI. The keyboard type implemented follows IBM compatible PS2 protocol using Scan Code Set 1."
+
diff --git a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxeExtra.uni b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxeExtra.uni
index 6c1ccb44a0..b43379a5d8 100644
--- a/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxeExtra.uni
+++ b/MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxeExtra.uni
@@ -1,14 +1,14 @@
-// /** @file
-// Ps2KeyboardDxe Localized Strings and Content
-//
-// Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"PS2 Keyboard DXE Driver"
-
-
+// /** @file
+// Ps2KeyboardDxe Localized Strings and Content
+//
+// Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"PS2 Keyboard DXE Driver"
+
+