public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Leif Lindholm <leif.lindholm@linaro.org>
To: Haojian Zhuang <haojian.zhuang@linaro.org>
Cc: ard.biesheuvel@linaro.org, linaro-uefi@lists.linaro.org,
	edk2-devel@lists.01.org
Subject: Re: [PATCH] EmbeddedPkg/Drivers: add virtual keyboard driver
Date: Tue, 27 Feb 2018 12:28:47 +0000	[thread overview]
Message-ID: <20180227122847.fr2zq6nurtrlstqh@bivouac.eciton.net> (raw)
In-Reply-To: <1519635156-21954-1-git-send-email-haojian.zhuang@linaro.org>

On Mon, Feb 26, 2018 at 04:52:36PM +0800, Haojian Zhuang wrote:
> The virtual keyboard could simulate a keyboard. User could simulate
> a key value when pattern is matched.

How? This is over 2000 lines of new code, please give a little bit
more description of what it does and how it is intended to be used.

(It sounds like is could be a useful feature, but I can only find out
what it is intended to do by reading the code, which isn't what review
is supposed to be.)

> Contributed-under: TianoCore Contribution Agreement 1.1
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  .../Drivers/VirtualKeyboardDxe/ComponentName.c     |  184 ++++
>  .../Drivers/VirtualKeyboardDxe/ComponentName.h     |  154 +++
>  .../Drivers/VirtualKeyboardDxe/VirtualKeyboard.c   | 1117 ++++++++++++++++++++
>  .../Drivers/VirtualKeyboardDxe/VirtualKeyboard.h   |  544 ++++++++++
>  .../VirtualKeyboardDxe/VirtualKeyboardDxe.dec      |   39 +
>  .../VirtualKeyboardDxe/VirtualKeyboardDxe.inf      |   61 ++
>  .../Include/Protocol/PlatformVirtualKeyboard.h     |   65 ++

Please generate patches with
--stat=1000 --stat-graph-width=20 
and
--subject-prefix="PATCH edk2-platforms"

(In general following the guide at)
https://github.com/tianocore/tianocore.github.io/wiki/Laszlo's-unkempt-git-guide-for-edk2-contributors-and-maintainers

>  7 files changed, 2164 insertions(+)
>  create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c
>  create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h
>  create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c
>  create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h
>  create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
>  create mode 100644 EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
>  create mode 100644 EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h
> 
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c
> new file mode 100644
> index 0000000..2935307
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.c
> @@ -0,0 +1,184 @@
> +/** @file
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions
> +of the BSD License which accompanies this distribution.  The
> +full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "VirtualKeyboard.h"
> +
> +//
> +// EFI Component Name Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gVirtualKeyboardComponentName = {
> +  VirtualKeyboardComponentNameGetDriverName,
> +  VirtualKeyboardComponentNameGetControllerName,
> +  "eng"
> +};
> +
> +//
> +// EFI Component Name 2 Protocol
> +//
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2 = {
> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) VirtualKeyboardComponentNameGetDriverName,
> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) VirtualKeyboardComponentNameGetControllerName,
> +  "en"
> +};
> +
> +
> +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mVirtualKeyboardDriverNameTable[] = {
> +  {
> +    "eng;en",
> +    L"RAM Keyboard Driver"

What is a RAM Keyboard Driver?

> +  },

Any chance of a "zh-chs" entry?

> +  {
> +    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
> +VirtualKeyboardComponentNameGetDriverName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> +  IN  CHAR8                        *Language,
> +  OUT CHAR16                       **DriverName
> +  )
> +{
> +  return LookupUnicodeString2 (
> +           Language,
> +           This->SupportedLanguages,
> +           mVirtualKeyboardDriverNameTable,
> +           DriverName,
> +           (BOOLEAN)(This == &gVirtualKeyboardComponentName)
> +           );
> +}
> +
> +/**
> +  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
> +VirtualKeyboardComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h
> new file mode 100644
> index 0000000..94bef28
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/ComponentName.h
> @@ -0,0 +1,154 @@
> +/** @file
> +
> +Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions
> +of the BSD License which accompanies this distribution.  The
> +full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_
> +#define _VIRTUAL_KEYBOARD_COMPONENT_NAME_H_
> +
> +
> +extern EFI_COMPONENT_NAME_PROTOCOL   gVirtualKeyboardComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL  gVirtualKeyboardComponentName2;
> +
> +//
> +// 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
> +VirtualKeyboardComponentNameGetDriverName (
> +  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
> +VirtualKeyboardComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> +  IN  EFI_HANDLE                                      ControllerHandle,
> +  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
> +  IN  CHAR8                                           *Language,
> +  OUT CHAR16                                          **ControllerName
> +  );
> +
> +
> +#endif
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c
> new file mode 100644
> index 0000000..b2c84ba
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.c
> @@ -0,0 +1,1117 @@
> +/** @file
> +  VirtualKeyboard driver
> +
> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions
> +of the BSD License which accompanies this distribution.  The
> +full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "VirtualKeyboard.h"
> +
> +//
> +// RAM Keyboard Driver Binding Protocol Instance
> +//
> +EFI_DRIVER_BINDING_PROTOCOL gVirtualKeyboardDriverBinding = {
> +  VirtualKeyboardDriverBindingSupported,
> +  VirtualKeyboardDriverBindingStart,
> +  VirtualKeyboardDriverBindingStop,
> +  0x10,
> +  NULL,
> +  NULL
> +};
> +
> +//
> +// EFI Driver Binding Protocol Functions
> +//
> +
> +/**
> +  Check whether the driver supports this device.
> +
> +  @param  This                   The Udriver binding protocol.
> +  @param  Controller             The controller handle to check.
> +  @param  RemainingDevicePath    The remaining device path.
> +
> +  @retval EFI_SUCCESS            The driver supports this controller.
> +  @retval other                  This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  PLATFORM_VIRTUAL_KBD_PROTOCOL  *PlatformVirtual;
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gPlatformVirtualKeyboardProtocolGuid,
> +                  (VOID **) &PlatformVirtual,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gPlatformVirtualKeyboardProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +  return Status;
> +}
> +
> +/**
> +  Starts the device with this driver.
> +
> +  @param  This                   The driver binding instance.
> +  @param  Controller             Handle of device to bind driver to.
> +  @param  RemainingDevicePath    Optional parameter use to pick a specific child
> +                                 device to start.
> +
> +  @retval EFI_SUCCESS            The controller is controlled by the driver.
> +  @retval Other                  This controller cannot be started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  )
> +{
> +  EFI_STATUS                                Status;
> +  VIRTUAL_KEYBOARD_DEV                      *VirtualKeyboardPrivate;
> +  PLATFORM_VIRTUAL_KBD_PROTOCOL             *PlatformVirtual;
> +
> +  Status = gBS->OpenProtocol (
> +                  Controller,
> +                  &gPlatformVirtualKeyboardProtocolGuid,
> +                  (VOID **) &PlatformVirtual,
> +                  This->DriverBindingHandle,
> +                  Controller,
> +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Allocate the private device structure
> +  //
> +  VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *) AllocateZeroPool (sizeof (VIRTUAL_KEYBOARD_DEV));
> +  if (NULL == VirtualKeyboardPrivate) {

No jeopardy-comparisons please. if (VirtualKeyboardPrivate == NULL) {

> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Done;
> +  }
> +
> +  //
> +  // Initialize the private device structure
> +  //
> +  VirtualKeyboardPrivate->Signature                  = VIRTUAL_KEYBOARD_DEV_SIGNATURE;
> +  VirtualKeyboardPrivate->Handle                     = Controller;
> +  VirtualKeyboardPrivate->PlatformVirtual            = PlatformVirtual;
> +  VirtualKeyboardPrivate->Queue.Front                = 0;
> +  VirtualKeyboardPrivate->Queue.Rear                 = 0;
> +  VirtualKeyboardPrivate->QueueForNotify.Front       = 0;
> +  VirtualKeyboardPrivate->QueueForNotify.Rear        = 0;
> +
> +  VirtualKeyboardPrivate->SimpleTextIn.Reset         = VirtualKeyboardReset;
> +  VirtualKeyboardPrivate->SimpleTextIn.ReadKeyStroke = VirtualKeyboardReadKeyStroke;
> +
> +  VirtualKeyboardPrivate->SimpleTextInputEx.Reset               = VirtualKeyboardResetEx;
> +  VirtualKeyboardPrivate->SimpleTextInputEx.ReadKeyStrokeEx     = VirtualKeyboardReadKeyStrokeEx;
> +  VirtualKeyboardPrivate->SimpleTextInputEx.SetState            = VirtualKeyboardSetState;
> +
> +  VirtualKeyboardPrivate->SimpleTextInputEx.RegisterKeyNotify   = VirtualKeyboardRegisterKeyNotify;
> +  VirtualKeyboardPrivate->SimpleTextInputEx.UnregisterKeyNotify = VirtualKeyboardUnregisterKeyNotify;
> +  InitializeListHead (&VirtualKeyboardPrivate->NotifyList);
> +
> +  Status = PlatformVirtual->Register ();
> +  if (EFI_ERROR (Status)) {
> +    goto Done;
> +  }
> +
> +  //
> +  // Report that the keyboard is being enabled
> +  //
> +  REPORT_STATUS_CODE (
> +    EFI_PROGRESS_CODE,
> +    EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_ENABLE
> +    );
> +
> +  //
> +  // Setup the WaitForKey event
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_WAIT,
> +                  TPL_NOTIFY,
> +                  VirtualKeyboardWaitForKey,
> +                  &(VirtualKeyboardPrivate->SimpleTextIn),
> +                  &((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey)
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    (VirtualKeyboardPrivate->SimpleTextIn).WaitForKey = NULL;
> +    goto Done;
> +  }
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_WAIT,
> +                  TPL_NOTIFY,
> +                  VirtualKeyboardWaitForKeyEx,
> +                  &(VirtualKeyboardPrivate->SimpleTextInputEx),
> +                  &(VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx)
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    VirtualKeyboardPrivate->SimpleTextInputEx.WaitForKeyEx = NULL;
> +    goto Done;
> +  }
> +
> +  //
> +  // Setup a periodic timer, used for reading keystrokes at a fixed interval
> +  //
> +  Status = gBS->CreateEvent (
> +                  EVT_TIMER | EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  VirtualKeyboardTimerHandler,
> +                  VirtualKeyboardPrivate,
> +                  &VirtualKeyboardPrivate->TimerEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    Status      = EFI_OUT_OF_RESOURCES;

The whitespace before = does not look quite right.
Please address throughout.

> +    goto Done;
> +  }
> +
> +  Status = gBS->SetTimer (
> +                  VirtualKeyboardPrivate->TimerEvent,
> +                  TimerPeriodic,
> +                  KEYBOARD_TIMER_INTERVAL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    Status      = EFI_OUT_OF_RESOURCES;
> +    goto Done;
> +  }
> +
> +  Status = gBS->CreateEvent (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  KeyNotifyProcessHandler,
> +                  VirtualKeyboardPrivate,
> +                  &VirtualKeyboardPrivate->KeyNotifyProcessEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    Status      = EFI_OUT_OF_RESOURCES;
> +    goto Done;
> +  }
> +
> +  //
> +  // Reset the keyboard device
> +  //
> +  Status = VirtualKeyboardPrivate->SimpleTextInputEx.Reset (
> +                                                    &VirtualKeyboardPrivate->SimpleTextInputEx,

Funky indentation.
According to coding style, it's missing 3 spaces.

> +                                                    FALSE
> +                                                    );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((EFI_D_ERROR, "[KBD]Reset Failed. Status - %r\n", Status));

Use DEBUG_ERROR (PatchCheck.py warns about this).

> +    goto Done;
> +  }
> +  //
> +  // Install protocol interfaces for the keyboard device.
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Controller,
> +                  &gEfiSimpleTextInProtocolGuid,
> +                  &VirtualKeyboardPrivate->SimpleTextIn,
> +                  &gEfiSimpleTextInputExProtocolGuid,
> +                  &VirtualKeyboardPrivate->SimpleTextInputEx,
> +                  NULL
> +                  );
> +
> +Done:
> +  if (EFI_ERROR (Status)) {
> +    if (VirtualKeyboardPrivate != NULL) {
> +      if ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey != NULL) {
> +        gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextIn).WaitForKey);
> +      }
> +
> +      if ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx != NULL) {
> +        gBS->CloseEvent ((VirtualKeyboardPrivate->SimpleTextInputEx).WaitForKeyEx);
> +      }
> +
> +      if (VirtualKeyboardPrivate->KeyNotifyProcessEvent != NULL) {
> +        gBS->CloseEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);
> +      }
> +
> +      VirtualKeyboardFreeNotifyList (&VirtualKeyboardPrivate->NotifyList);
> +
> +      if (VirtualKeyboardPrivate->TimerEvent != NULL) {
> +        gBS->CloseEvent (VirtualKeyboardPrivate->TimerEvent);
> +      }
> +      FreePool (VirtualKeyboardPrivate);
> +    }
> +  }
> +
> +  gBS->CloseProtocol (
> +         Controller,
> +         &gPlatformVirtualKeyboardProtocolGuid,
> +         This->DriverBindingHandle,
> +         Controller
> +         );
> +
> +  return Status;
> +}
> +
> +/**
> +  Stop the device handled by this driver.
> +
> +  @param  This                   The driver binding protocol.
> +  @param  Controller             The controller to release.
> +  @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
> +  @param  ChildHandleBuffer      The array of child handle.
> +
> +  @retval EFI_SUCCESS            The device was stopped.
> +  @retval EFI_DEVICE_ERROR       The device could not be stopped due to a device error.
> +  @retval Others                 Fail to uninstall protocols attached on the device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN  EFI_HANDLE                   Controller,
> +  IN  UINTN                        NumberOfChildren,
> +  IN  EFI_HANDLE                   *ChildHandleBuffer
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  Enqueue the key.
> +
> +  @param  Queue                 The queue to be enqueued.
> +  @param  KeyData               The key data to be enqueued.
> +
> +  @retval EFI_NOT_READY         The queue is full.
> +  @retval EFI_SUCCESS           Successfully enqueued the key data.
> +
> +**/
> +EFI_STATUS
> +Enqueue (
> +  IN SIMPLE_QUEUE         *Queue,
> +  IN EFI_KEY_DATA         *KeyData
> +  )
> +{
> +  if ((Queue->Rear + 1) % QUEUE_MAX_COUNT == Queue->Front) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  CopyMem (&Queue->Buffer[Queue->Rear], KeyData, sizeof (EFI_KEY_DATA));
> +  Queue->Rear = (Queue->Rear + 1) % QUEUE_MAX_COUNT;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Dequeue the key.
> +
> +  @param  Queue                 The queue to be dequeued.
> +  @param  KeyData               The key data to be dequeued.
> +
> +  @retval EFI_NOT_READY         The queue is empty.
> +  @retval EFI_SUCCESS           Successfully dequeued the key data.
> +
> +**/
> +EFI_STATUS
> +Dequeue (
> +  IN SIMPLE_QUEUE         *Queue,
> +  IN EFI_KEY_DATA         *KeyData
> +  )
> +{
> +  if (Queue->Front == Queue->Rear) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  CopyMem (KeyData, &Queue->Buffer[Queue->Front], sizeof (EFI_KEY_DATA));
> +  Queue->Front  = (Queue->Front + 1) % QUEUE_MAX_COUNT;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check whether the queue is empty.
> +
> +  @param  Queue                 The queue to be checked.
> +
> +  @retval EFI_NOT_READY         The queue is empty.
> +  @retval EFI_SUCCESS           The queue is not empty.
> +
> +**/
> +EFI_STATUS
> +CheckQueue (
> +  IN SIMPLE_QUEUE         *Queue
> +  )
> +{
> +  if (Queue->Front == Queue->Rear) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Check key buffer to get the key stroke status.
> +
> +  @param  This         Pointer of the protocol EFI_SIMPLE_TEXT_IN_PROTOCOL.
> +
> +  @retval EFI_SUCCESS  A key is being pressed now.
> +  @retval Other        No key is now pressed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardCheckForKey (
> +  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This
> +  )
> +{
> +  VIRTUAL_KEYBOARD_DEV     *VirtualKeyboardPrivate;
> +
> +  VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> +  return CheckQueue (&VirtualKeyboardPrivate->Queue);
> +}
> +
> +/**
> +  Free keyboard notify list.
> +
> +  @param  ListHead   The list head
> +
> +  @retval EFI_SUCCESS           Free the notify list successfully
> +  @retval EFI_INVALID_PARAMETER ListHead is invalid.
> +
> +**/
> +EFI_STATUS
> +VirtualKeyboardFreeNotifyList (
> +  IN OUT LIST_ENTRY           *ListHead
> +  )
> +{
> +  VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *NotifyNode;
> +
> +  if (ListHead == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  while (!IsListEmpty (ListHead)) {
> +    NotifyNode = CR (
> +                   ListHead->ForwardLink,
> +                   VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> +                   NotifyEntry,
> +                   VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
> +                   );
> +    RemoveEntryList (ListHead->ForwardLink);
> +    gBS->FreePool (NotifyNode);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Judge whether is a registed 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 FLASE               Match failed.
> +
> +**/
> +BOOLEAN
> +IsKeyRegistered (
> +  IN EFI_KEY_DATA  *RegsiteredData,
> +  IN EFI_KEY_DATA  *InputData
> +  )
> +
> +{
> +  ASSERT (RegsiteredData != NULL && InputData != NULL);
> +
> +  if ((RegsiteredData->Key.ScanCode    != InputData->Key.ScanCode) ||
> +      (RegsiteredData->Key.UnicodeChar != InputData->Key.UnicodeChar)) {
> +    return FALSE;
> +  }
> +
> +  //
> +  // Assume KeyShiftState/KeyToggleState = 0 in Registered key data means these state could be ignored.
> +  //
> +  if (RegsiteredData->KeyState.KeyShiftState != 0 &&
> +      RegsiteredData->KeyState.KeyShiftState != InputData->KeyState.KeyShiftState) {
> +    return FALSE;
> +  }
> +  if (RegsiteredData->KeyState.KeyToggleState != 0 &&
> +      RegsiteredData->KeyState.KeyToggleState != InputData->KeyState.KeyToggleState) {
> +    return FALSE;
> +  }
> +
> +  return TRUE;
> +
> +}
> +
> +/**
> +  Event notification function for SIMPLE_TEXT_IN.WaitForKey event
> +  Signal the event if there is key available
> +
> +  @param Event    the event object
> +  @param Context  waitting context
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardWaitForKey (
> +  IN  EFI_EVENT               Event,
> +  IN  VOID                    *Context
> +  )
> +{
> +  //
> +  // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
> +  // Csm will be used to check whether there is a key pending, but the csm will disable all

Well, this makes it clear this driver is based on
IntelFrameworkModulePkg/Csm/BiosThunk/KeyboardDxe/.
I cannot really comment on whether that was the best starting point,
but please delete all and any references to CSM and eficompatibility -
these are fundamentally irrelevant for any non-x86 platforms.

> +  // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
> +  // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
> +  // e.g. UI setup or Shell, other drivers which are driven by timer event will have a bad performance during this period,
> +  // e.g. usb keyboard driver.
> +  // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
> +  // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
> +  //
> +  gBS->Stall (1000);
> +  //
> +  // Use TimerEvent callback function to check whether there's any key pressed
> +  //
> +  VirtualKeyboardTimerHandler (NULL, VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context));
> +
> +  if (!EFI_ERROR (VirtualKeyboardCheckForKey (Context))) {
> +    gBS->SignalEvent (Event);
> +  }
> +}
> +
> +/**
> +  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
> +VirtualKeyboardWaitForKeyEx (
> +  IN  EFI_EVENT               Event,
> +  IN  VOID                    *Context
> +  )
> +
> +{
> +  VIRTUAL_KEYBOARD_DEV                     *VirtualKeyboardPrivate;
> +
> +  VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (Context);
> +  VirtualKeyboardWaitForKey (Event, &VirtualKeyboardPrivate->SimpleTextIn);
> +
> +}
> +
> +//
> +// EFI Simple Text In Protocol Functions
> +//
> +/**
> +  Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.

There are a few really long lines in this patch. Please try to keep
to no more than 80 characters were feasible. Applies throughout.

> +
> +  @param  This                  Pointer of simple text Protocol.
> +  @param  ExtendedVerification  Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
> +
> +  @retval EFI_SUCCESS           The command byte is written successfully.
> +  @retval EFI_DEVICE_ERROR      Errors occurred during resetting keyboard.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReset (
> +  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
> +  IN  BOOLEAN                         ExtendedVerification
> +  )
> +{
> +  VIRTUAL_KEYBOARD_DEV *VirtualKeyboardPrivate;
> +  EFI_STATUS           Status;
> +  EFI_TPL              OldTpl;
> +
> +  VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> +  //
> +  // Raise TPL to avoid mouse operation impact
> +  //
> +  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  if (VirtualKeyboardPrivate->PlatformVirtual && VirtualKeyboardPrivate->PlatformVirtual->Reset) {

  if (VirtualKeyboardPrivate->PlatformVirtual &&
      VirtualKeyboardPrivate->PlatformVirtual->Reset) {

And so on.

> +    Status = VirtualKeyboardPrivate->PlatformVirtual->Reset ();
> +  } else {
> +    Status = EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // resume priority of task level
> +  //
> +  gBS->RestoreTPL (OldTpl);
> +
> +  return Status;
> +}
> +
> +/**
> +  Reset the input device and optionaly run diagnostics
> +
> +  @param  This                  Protocol instance pointer.
> +  @param  ExtendedVerification  Driver may perform diagnostics on reset.
> +
> +  @retval EFI_SUCCESS           The device was reset.
> +  @retval EFI_DEVICE_ERROR      The device is not functioning properly and could-
> +                                not be reset.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardResetEx (
> +  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
> +  IN BOOLEAN                            ExtendedVerification
> +  )
> +{
> +  VIRTUAL_KEYBOARD_DEV                     *VirtualKeyboardPrivate;

Spacing does not match subsequent lines.

> +  EFI_STATUS                            Status;
> +  EFI_TPL                               OldTpl;
> +
> +  VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> +  Status = VirtualKeyboardPrivate->SimpleTextIn.Reset (
> +                                               &VirtualKeyboardPrivate->SimpleTextIn,

Funky indentation.

> +                                               ExtendedVerification
> +                                               );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  gBS->RestoreTPL (OldTpl);
> +
> +  return EFI_SUCCESS;
> +
> +}
> +
> +/**
> +  Reads the next keystroke from the input device. The WaitForKey Event can
> +  be used to test for existance of a keystroke via WaitForEvent () call.
> +
> +  @param  VirtualKeyboardPrivate   Virtualkeyboard driver private structure.
> +  @param  KeyData               A pointer to a buffer that is filled in with the keystroke
> +                                state data for the key that was pressed.
> +
> +  @retval EFI_SUCCESS           The keystroke information was returned.
> +  @retval EFI_NOT_READY         There was no keystroke data availiable.
> +  @retval EFI_DEVICE_ERROR      The keystroke information was not returned due to
> +                                hardware errors.
> +  @retval EFI_INVALID_PARAMETER KeyData is NULL.
> +
> +**/
> +EFI_STATUS
> +KeyboardReadKeyStrokeWorker (
> +  IN VIRTUAL_KEYBOARD_DEV  *VirtualKeyboardPrivate,
> +  OUT EFI_KEY_DATA      *KeyData
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  EFI_TPL                               OldTpl;
> +  if (KeyData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Use TimerEvent callback function to check whether there's any key pressed
> +  //
> +
> +  //
> +  // Stall 1ms to give a chance to let other driver interrupt this routine for their timer event.
> +  // Csm will be used to check whether there is a key pending, but the csm will disable all
> +  // interrupt before switch to compatibility16, which mean all the efiCompatibility timer
> +  // event will stop work during the compatibility16. And If a caller recursivly invoke this function,
> +  // e.g. OS loader, other drivers which are driven by timer event will have a bad performance during this period,
> +  // e.g. usb keyboard driver.
> +  // Add a stall period can greatly increate other driver performance during the WaitForKey is recursivly invoked.
> +  // 1ms delay will make little impact to the thunk keyboard driver, and user can not feel the delay at all when input.
> +  //
> +  gBS->Stall (1000);
> +
> +  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  VirtualKeyboardTimerHandler (NULL, VirtualKeyboardPrivate);
> +  //
> +  // If there's no key, just return
> +  //
> +  Status = CheckQueue (&VirtualKeyboardPrivate->Queue);
> +  if (EFI_ERROR (Status)) {
> +    gBS->RestoreTPL (OldTpl);
> +    return EFI_NOT_READY;
> +  }
> +
> +  Status = Dequeue (&VirtualKeyboardPrivate->Queue, KeyData);
> +
> +  gBS->RestoreTPL (OldTpl);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Read out the scan code of the key that has just been stroked.
> +
> +  @param  This        Pointer of simple text Protocol.
> +  @param  Key         Pointer for store the key that read out.
> +
> +  @retval EFI_SUCCESS The key is read out successfully.
> +  @retval other       The key reading failed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStroke (
> +  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
> +  OUT EFI_INPUT_KEY                   *Key
> +  )
> +{
> +  VIRTUAL_KEYBOARD_DEV     *VirtualKeyboardPrivate;
> +  EFI_STATUS            Status;
> +  EFI_KEY_DATA          KeyData;
> +
> +  VirtualKeyboardPrivate = VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> +  Status = KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, &KeyData);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Convert the Ctrl+[a-z] to Ctrl+[1-26]
> +  //
> +  if ((KeyData.KeyState.KeyShiftState & (EFI_LEFT_CONTROL_PRESSED | EFI_RIGHT_CONTROL_PRESSED)) != 0) {
> +    if (KeyData.Key.UnicodeChar >= L'a' && KeyData.Key.UnicodeChar <= L'z') {
> +      KeyData.Key.UnicodeChar = (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;
> +}
> +
> +/**
> +  Reads the next keystroke from the input device. The WaitForKey Event can
> +  be used to test for existance of a keystroke via WaitForEvent () call.
> +
> +  @param  This         Protocol instance pointer.
> +  @param  KeyData      A pointer to a buffer that is filled in with the keystroke
> +                       state data for the key that was pressed.
> +
> +  @retval  EFI_SUCCESS           The keystroke information was returned.
> +  @retval  EFI_NOT_READY         There was no keystroke data availiable.
> +  @retval  EFI_DEVICE_ERROR      The keystroke information was not returned due to
> +                                 hardware errors.
> +  @retval  EFI_INVALID_PARAMETER KeyData is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStrokeEx (
> +  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> +  OUT EFI_KEY_DATA                      *KeyData
> +  )
> +{
> +  VIRTUAL_KEYBOARD_DEV                     *VirtualKeyboardPrivate;
> +
> +  if (KeyData == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> +  return KeyboardReadKeyStrokeWorker (VirtualKeyboardPrivate, 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
> +VirtualKeyboardSetState (
> +  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
> +  IN EFI_KEY_TOGGLE_STATE               *KeyToggleState
> +  )
> +{
> +  if (KeyToggleState == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Thunk keyboard driver doesn't support partial keystroke.
> +  //
> +  if ((*KeyToggleState & EFI_TOGGLE_STATE_VALID) != EFI_TOGGLE_STATE_VALID ||
> +      (*KeyToggleState & EFI_KEY_STATE_EXPOSED) == EFI_KEY_STATE_EXPOSED
> +      ) {
> +    return EFI_UNSUPPORTED;
> +  }
> +

This function has no side effects, and it's an emulated keyboard (how
could a partial keystroke happen?). Why does it do anything other than
return SUCCESS?

> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Register a notification function for a particular keystroke for the input device.
> +
> +  @param  This                    Protocol instance pointer.
> +  @param  KeyData                 A pointer to a buffer that is filled in with the keystroke
> +                                  information data for the key that was pressed.
> +  @param  KeyNotificationFunction Points to the function to be called when the key
> +                                  sequence is typed specified by KeyData.
> +  @param  NotifyHandle            Points to the unique handle assigned to the registered notification.
> +
> +
> +  @retval EFI_SUCCESS             The notification function was registered successfully.
> +  @retval EFI_OUT_OF_RESOURCES    Unable to allocate resources for necesssary data structures.
> +  @retval EFI_INVALID_PARAMETER   KeyData or NotifyHandle is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardRegisterKeyNotify (
> +  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;
> +  VIRTUAL_KEYBOARD_DEV                     *VirtualKeyboardPrivate;
> +  EFI_TPL                               OldTpl;
> +  VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *NewNotify;
> +  LIST_ENTRY                            *Link;
> +  VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *CurrentNotify;
> +
> +  if (KeyData == NULL || NotifyHandle == NULL || KeyNotificationFunction == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> +  //
> +  // Enter critical section
> +  //
> +  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  //
> +  // Return EFI_SUCCESS if the (KeyData, NotificationFunction) is already registered.
> +  //
> +  for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != &VirtualKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
> +    CurrentNotify = CR (
> +                      Link,
> +                      VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> +                      NotifyEntry,
> +                      VIRTUAL_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 = (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) AllocateZeroPool (sizeof (VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY));
> +  if (NewNotify == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  NewNotify->Signature         = VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE;
> +  NewNotify->KeyNotificationFn = KeyNotificationFunction;
> +  CopyMem (&NewNotify->KeyData, KeyData, sizeof (EFI_KEY_DATA));
> +  InsertTailList (&VirtualKeyboardPrivate->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
> +VirtualKeyboardUnregisterKeyNotify (
> +  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
> +  IN VOID                               *NotificationHandle
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  VIRTUAL_KEYBOARD_DEV                     *VirtualKeyboardPrivate;
> +  EFI_TPL                               OldTpl;
> +  LIST_ENTRY                            *Link;
> +  VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *CurrentNotify;
> +
> +  //
> +  // Check incoming notification handle
> +  //
> +  if (NotificationHandle == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (((VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY *) NotificationHandle)->Signature != VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  VirtualKeyboardPrivate = TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS (This);
> +
> +  //
> +  // Enter critical section
> +  //
> +  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != &VirtualKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
> +    CurrentNotify = CR (
> +                      Link,
> +                      VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> +                      NotifyEntry,
> +                      VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE
> +                      );
> +    if (CurrentNotify == NotificationHandle) {
> +      //
> +      // Remove the notification function from NotifyList and free resources
> +      //
> +      RemoveEntryList (&CurrentNotify->NotifyEntry);
> +
> +      Status = EFI_SUCCESS;
> +      goto Exit;
> +    }
> +  }
> +
> +  //
> +  // Can not find the specified Notification Handle
> +  //
> +  Status = EFI_INVALID_PARAMETER;
> +
> +Exit:
> +  //
> +  // Leave critical section and return
> +  //
> +  gBS->RestoreTPL (OldTpl);
> +  return Status;
> +}
> +
> +/**
> +  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
> +VirtualKeyboardTimerHandler (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  )
> +{
> +  EFI_TPL                            OldTpl;
> +  LIST_ENTRY                         *Link;
> +  EFI_KEY_DATA                       KeyData;

Please make these variable names line up with the ones below.

> +  VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY  *CurrentNotify;
> +  VIRTUAL_KEYBOARD_DEV                   *VirtualKeyboardPrivate;
> +  VIRTUAL_KBD_KEY                        VirtualKey;
> +
> +  VirtualKeyboardPrivate = Context;
> +
> +  //
> +  // Enter critical section
> +  //
> +  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +
> +  if (VirtualKeyboardPrivate->PlatformVirtual &&
> +      VirtualKeyboardPrivate->PlatformVirtual->Query) {
> +    if (VirtualKeyboardPrivate->PlatformVirtual->Query (&VirtualKey) == FALSE) {
> +      goto Exit;
> +    }
> +    // Found key
> +    KeyData.Key.ScanCode = VirtualKey.Key.ScanCode;
> +    KeyData.Key.UnicodeChar = VirtualKey.Key.UnicodeChar;
> +    KeyData.KeyState.KeyShiftState  = EFI_SHIFT_STATE_VALID;
> +    KeyData.KeyState.KeyToggleState = EFI_TOGGLE_STATE_VALID;
> +    if (VirtualKeyboardPrivate->PlatformVirtual->Clear) {
> +      VirtualKeyboardPrivate->PlatformVirtual->Clear (&VirtualKey);
> +    }
> +  } else {
> +    goto Exit;
> +  }
> +
> +  //
> +  // Signal KeyNotify process event if this key pressed matches any key registered.
> +  //
> +  for (Link = VirtualKeyboardPrivate->NotifyList.ForwardLink; Link != &VirtualKeyboardPrivate->NotifyList; Link = Link->ForwardLink) {
> +    CurrentNotify = CR (
> +                      Link,
> +                      VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY,
> +                      NotifyEntry,
> +                      VIRTUAL_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.
> +      //
> +      Enqueue (&VirtualKeyboardPrivate->QueueForNotify, &KeyData);
> +      gBS->SignalEvent (VirtualKeyboardPrivate->KeyNotifyProcessEvent);
> +    }
> +  }
> +
> +  Enqueue (&VirtualKeyboardPrivate->Queue, &KeyData);
> +
> +Exit:
> +  //
> +  // Leave critical section and return
> +  //
> +  gBS->RestoreTPL (OldTpl);
> +}
> +
> +/**
> +  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;
> +  VIRTUAL_KEYBOARD_DEV                     *VirtualKeyboardPrivate;
> +  EFI_KEY_DATA                          KeyData;
> +  LIST_ENTRY                            *Link;
> +  LIST_ENTRY                            *NotifyList;
> +  VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY    *CurrentNotify;
> +  EFI_TPL                               OldTpl;

Please make variable names line up.

> +
> +  VirtualKeyboardPrivate = (VIRTUAL_KEYBOARD_DEV *) Context;
> +
> +  //
> +  // Invoke notification functions.
> +  //
> +  NotifyList = &VirtualKeyboardPrivate->NotifyList;
> +  while (TRUE) {
> +    //
> +    // Enter critical section
> +    //
> +    OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
> +    Status = Dequeue (&VirtualKeyboardPrivate->QueueForNotify, &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, VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY, NotifyEntry, VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE);
> +      if (IsKeyRegistered (&CurrentNotify->KeyData, &KeyData)) {
> +        CurrentNotify->KeyNotificationFn (&KeyData);
> +      }
> +    }
> +  }
> +}
> +
> +/**
> +  The user Entry Point for module VirtualKeyboard. 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
> +InitializeVirtualKeyboard(
> +  IN EFI_HANDLE           ImageHandle,
> +  IN EFI_SYSTEM_TABLE     *SystemTable
> +  )
> +{
> +  EFI_STATUS              Status;
> +
> +  //
> +  // Install driver model protocol(s).
> +  //
> +  Status = EfiLibInstallDriverBindingComponentName2 (
> +             ImageHandle,
> +             SystemTable,
> +             &gVirtualKeyboardDriverBinding,
> +             ImageHandle,
> +             &gVirtualKeyboardComponentName,
> +             &gVirtualKeyboardComponentName2
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h
> new file mode 100644
> index 0000000..c8e256d
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboard.h
> @@ -0,0 +1,544 @@
> +/** @file
> +
> +Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
> +Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions
> +of the BSD License which accompanies this distribution.  The
> +full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef _VIRTUAL_KEYBOARD_H_
> +#define _VIRTUAL_KEYBOARD_H_
> +
> +
> +#include <Guid/StatusCodeDataTypeId.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/PlatformVirtualKeyboard.h>
> +#include <Protocol/SimpleTextIn.h>
> +#include <Protocol/SimpleTextInEx.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/ReportStatusCodeLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +
> +//
> +// Driver Binding Externs
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL  gVirtualKeyboardDriverBinding;
> +extern EFI_COMPONENT_NAME_PROTOCOL  gVirtualKeyboardComponentName;
> +extern EFI_COMPONENT_NAME2_PROTOCOL gVirtualKeyboardComponentName2;
> +
> +
> +//
> +// VIRTUAL Keyboard Defines
> +//
> +#define CHAR_SCANCODE                        0xe0
> +#define CHAR_ESC                             0x1b
> +
> +#define KEYBOARD_TIMEOUT                     65536   // 0.07s
> +#define KEYBOARD_WAITFORVALUE_TIMEOUT        1000000 // 1s
> +#define KEYBOARD_BAT_TIMEOUT                 4000000 // 4s
> +#define KEYBOARD_TIMER_INTERVAL              500000  // 0.5s
> +
> +#define QUEUE_MAX_COUNT                      32
> +
> +#define KEYBOARD_SCAN_CODE_MAX_COUNT         32
> +
> +//
> +// VIRTUAL Keyboard Device Structure
> +//
> +#define VIRTUAL_KEYBOARD_DEV_SIGNATURE SIGNATURE_32 ('V', 'K', 'B', 'D')
> +#define VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY_SIGNATURE SIGNATURE_32 ('v', 'k', 'c', 'n')
> +
> +typedef struct _VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY {
> +  UINTN                                      Signature;
> +  EFI_KEY_DATA                               KeyData;
> +  EFI_KEY_NOTIFY_FUNCTION                    KeyNotificationFn;
> +  LIST_ENTRY                                 NotifyEntry;
> +} VIRTUAL_KEYBOARD_CONSOLE_IN_EX_NOTIFY;
> +
> +typedef struct {
> +  UINTN                                      Front;
> +  UINTN                                      Rear;
> +  EFI_KEY_DATA                               Buffer[QUEUE_MAX_COUNT];
> +} SIMPLE_QUEUE;
> +
> +typedef struct {
> +  UINT8                                      Buffer[KEYBOARD_SCAN_CODE_MAX_COUNT];
> +  UINTN                                      Head;
> +  UINTN                                      Tail;
> +} SCAN_CODE_QUEUE;
> +
> +typedef struct {
> +  UINTN                                      Signature;
> +  EFI_HANDLE                                 Handle;
> +  PLATFORM_VIRTUAL_KBD_PROTOCOL              *PlatformVirtual;
> +  EFI_SIMPLE_TEXT_INPUT_PROTOCOL             SimpleTextIn;
> +  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL          SimpleTextInputEx;
> +
> +  //
> +  // Buffer storing EFI_KEY_DATA
> +  //
> +  SIMPLE_QUEUE                               Queue;
> +  SIMPLE_QUEUE                               QueueForNotify;
> +
> +  //
> +  // Notification Function List
> +  //
> +  LIST_ENTRY                                 NotifyList;
> +  EFI_EVENT                                  KeyNotifyProcessEvent;
> +  EFI_EVENT                                  TimerEvent;
> +} VIRTUAL_KEYBOARD_DEV;
> +
> +#define VIRTUAL_KEYBOARD_DEV_FROM_THIS(a)  CR (a, VIRTUAL_KEYBOARD_DEV, SimpleTextIn, VIRTUAL_KEYBOARD_DEV_SIGNATURE)
> +#define TEXT_INPUT_EX_VIRTUAL_KEYBOARD_DEV_FROM_THIS(a) \
> +  CR (a, \
> +      VIRTUAL_KEYBOARD_DEV, \
> +      SimpleTextInputEx, \
> +      VIRTUAL_KEYBOARD_DEV_SIGNATURE \
> +      )
> +
> +//
> +// Global Variables
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL   gVirtualKeyboardDriverBinding;
> +
> +//
> +// Driver Binding Protocol functions
> +//
> +
> +/**
> +  Check whether the driver supports this device.
> +
> +  @param  This                   The Udriver binding protocol.
> +  @param  Controller             The controller handle to check.
> +  @param  RemainingDevicePath    The remaining device path.
> +
> +  @retval EFI_SUCCESS            The driver supports this controller.
> +  @retval other                  This device isn't supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Starts the device with this driver.
> +
> +  @param  This                   The driver binding instance.
> +  @param  Controller             Handle of device to bind driver to.
> +  @param  RemainingDevicePath    Optional parameter use to pick a specific child
> +                                 device to start.
> +
> +  @retval EFI_SUCCESS            The controller is controlled by the driver.
> +  @retval Other                  This controller cannot be started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   Controller,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> +  );
> +
> +/**
> +  Stop the device handled by this driver.
> +
> +  @param  This                   The driver binding protocol.
> +  @param  Controller             The controller to release.
> +  @param  NumberOfChildren       The number of handles in ChildHandleBuffer.
> +  @param  ChildHandleBuffer      The array of child handle.
> +
> +  @retval EFI_SUCCESS            The device was stopped.
> +  @retval EFI_DEVICE_ERROR       The device could not be stopped due to a device error.
> +  @retval Others                 Fail to uninstall protocols attached on the device.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN  EFI_HANDLE                   Controller,
> +  IN  UINTN                        NumberOfChildren,
> +  IN  EFI_HANDLE                   *ChildHandleBuffer
> +  );
> +
> +/**
> +  Retrieves a Unicode string that is the user readable name of the driver.
> +
> +  This function retrieves the user readable name of a driver in the form of a
> +  Unicode string. If the driver specified by This has a user readable name in
> +  the language specified by Language, then a pointer to the driver name is
> +  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
> +  by This does not support the language specified by Language,
> +  then EFI_UNSUPPORTED is returned.
> +
> +  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
> +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> +
> +  @param  Language[in]          A pointer to a Null-terminated ASCII string
> +                                array indicating the language. This is the
> +                                language of the driver name that the caller is
> +                                requesting, and it must match one of the
> +                                languages specified in SupportedLanguages. The
> +                                number of languages supported by a driver is up
> +                                to the driver writer. Language is specified
> +                                in RFC 4646 or ISO 639-2 language code format.
> +
> +  @param  DriverName[out]       A pointer to the Unicode string to return.
> +                                This Unicode string is the name of the
> +                                driver specified by This in the language
> +                                specified by Language.
> +
> +  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
> +                                This and the language specified by Language was
> +                                returned in DriverName.
> +
> +  @retval EFI_INVALID_PAVIRTUALETER Language is NULL.
> +
> +  @retval EFI_INVALID_PAVIRTUALETER DriverName is NULL.
> +
> +  @retval EFI_UNSUPPORTED       The driver specified by This does not support
> +                                the language specified by Language.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardComponentNameGetDriverName (
> +  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_PAVIRTUALETER ControllerHandle is NULL.
> +
> +  @retval EFI_INVALID_PAVIRTUALETER ChildHandle is not NULL and it is not a valid
> +                                EFI_HANDLE.
> +
> +  @retval EFI_INVALID_PAVIRTUALETER Language is NULL.
> +
> +  @retval EFI_INVALID_PAVIRTUALETER 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
> +VirtualKeyboardComponentNameGetControllerName (
> +  IN  EFI_COMPONENT_NAME_PROTOCOL      *This,
> +  IN  EFI_HANDLE                       ControllerHandle,
> +  IN  EFI_HANDLE                       ChildHandle        OPTIONAL,
> +  IN  CHAR8                            *Language,
> +  OUT CHAR16                           **ControllerName
> +  );
> +
> +
> +//
> +// Simple Text Input Protocol functions
> +//
> +/**
> +  Reset the Keyboard and do BAT test for it, if (ExtendedVerification == TRUE) then do some extra keyboard validations.
> +
> +  @param  This                  Pointer of simple text Protocol.
> +  @param  ExtendedVerification  Whether perform the extra validation of keyboard. True: perform; FALSE: skip.
> +
> +  @retval EFI_SUCCESS           The command byte is written successfully.
> +  @retval EFI_DEVICE_ERROR      Errors occurred during resetting keyboard.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReset (
> +  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
> +  IN  BOOLEAN                         ExtendedVerification
> +  );
> +
> +/**
> +  Reset the input device and optionaly run diagnostics
> +
> +  @param  This                  Protocol instance pointer.
> +  @param  ExtendedVerification  Driver may perform diagnostics on reset.
> +
> +  @retval EFI_SUCCESS           The device was reset.
> +  @retval EFI_DEVICE_ERROR      The device is not functioning properly and could 

Trailing whitespace. (PatchCheck.py warns about this.)

> +                                not be reset.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardResetEx (
> +  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
> +  IN BOOLEAN                            ExtendedVerification
> +  );
> +
> +/**
> +  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_PAVIRTUALETER KeyToggleState is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardSetState (
> +  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
> +  IN EFI_KEY_TOGGLE_STATE               *KeyToggleState
> +  );
> +
> +/**
> +  Register a notification function for a particular keystroke for the input device.
> +
> +  @param  This                    Protocol instance pointer.
> +  @param  KeyData                 A pointer to a buffer that is filled in with the keystroke
> +                                  information data for the key that was pressed.
> +  @param  KeyNotificationFunction Points to the function to be called when the key
> +                                  sequence is typed specified by KeyData.
> +  @param  NotifyHandle            Points to the unique handle assigned to the registered notification.
> +
> +
> +  @retval EFI_SUCCESS             The notification function was registered successfully.
> +  @retval EFI_OUT_OF_RESOURCES    Unable to allocate resources for necesssary data structures.
> +  @retval EFI_INVALID_PAVIRTUALETER   KeyData or NotifyHandle is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardRegisterKeyNotify (
> +  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_PAVIRTUALETER   The NotificationHandle is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardUnregisterKeyNotify (
> +  IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL  *This,
> +  IN VOID                               *NotificationHandle
> +  );
> +
> +//
> +// Private worker functions
> +//
> +/**
> +  Free keyboard notify list.
> +
> +  @param  ListHead   The list head
> +
> +  @retval EFI_SUCCESS           Free the notify list successfully
> +  @retval EFI_INVALID_PAVIRTUALETER ListHead is invalid.
> +
> +**/
> +EFI_STATUS
> +VirtualKeyboardFreeNotifyList (
> +  IN OUT LIST_ENTRY           *ListHead
> +  );
> +
> +/**
> +  Check if key is registered.
> +
> +  @param  RegsiteredData    A pointer to a buffer that is filled in with the keystroke
> +                            state data for the key that was registered.
> +  @param  InputData         A pointer to a buffer that is filled in with the keystroke
> +                            state data for the key that was pressed.
> +
> +  @retval TRUE              Key be pressed matches a registered key.
> +  @retval FLASE             Match failed.
> +
> +**/
> +BOOLEAN
> +IsKeyRegistered (
> +  IN EFI_KEY_DATA  *RegsiteredData,
> +  IN EFI_KEY_DATA  *InputData
> +  );
> +
> +/**
> +  Waiting on the keyboard event, if there's any key pressed by the user, signal the event
> +
> +  @param  Event       The event that be siganlled when any key has been stroked.
> +  @param  Context     Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_PROTOCOL.
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardWaitForKey (
> +  IN  EFI_EVENT  Event,
> +  IN  VOID       *Context
> +  );
> +
> +/**
> +  Waiting on the keyboard event, if there's any key pressed by the user, signal the event
> +
> +  @param  Event    The event that be siganlled when any key has been stroked.
> +  @param  Context  Pointer of the protocol EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardWaitForKeyEx (
> +  IN  EFI_EVENT  Event,
> +  IN  VOID       *Context
> +  );
> +
> +/**
> +  Timer event handler: read a series of key stroke from 8042
> +  and put them into memory key buffer.
> +  It is registered as running under TPL_NOTIFY
> +
> +  @param  Event   The timer event
> +  @param  Context A VIRTUAL_KEYBOARD_DEV pointer
> +
> +**/
> +VOID
> +EFIAPI
> +VirtualKeyboardTimerHandler (
> +  IN EFI_EVENT    Event,
> +  IN VOID         *Context
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  Read out the scan code of the key that has just been stroked.
> +
> +  @param  This        Pointer of simple text Protocol.
> +  @param  Key         Pointer for store the key that read out.
> +
> +  @retval EFI_SUCCESS The key is read out successfully.
> +  @retval other       The key reading failed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStroke (
> +  IN  EFI_SIMPLE_TEXT_INPUT_PROTOCOL  *This,
> +  OUT EFI_INPUT_KEY                   *Key
> +  );
> +
> +/**
> +  Reads the next keystroke from the input device. The WaitForKey Event can
> +  be used to test for existance of a keystroke via WaitForEvent () call.
> +
> +  @param  This         Protocol instance pointer.
> +  @param  KeyData      A pointer to a buffer that is filled in with the keystroke
> +                       state data for the key that was pressed.
> +
> +  @retval  EFI_SUCCESS           The keystroke information was returned.
> +  @retval  EFI_NOT_READY         There was no keystroke data availiable.
> +  @retval  EFI_DEVICE_ERROR      The keystroke information was not returned due to
> +                                 hardware errors.
> +  @retval  EFI_INVALID_PAVIRTUALETER KeyData is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +VirtualKeyboardReadKeyStrokeEx (
> +  IN  EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
> +  OUT EFI_KEY_DATA                      *KeyData
> +  );
> +
> +#endif /* _VIRTUAL_KEYBOARD_H_ */
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
> new file mode 100644
> index 0000000..065f4f2
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec

Could you add the two guids to EmbeddededPkg instead?
Or just gPlatformVirtualKeyboardProtocolGuid, I don't see any use of
gVirtualKeyboardDxeTokenSpaceGuid.

> @@ -0,0 +1,39 @@
> +#/** @file
> +# Framework Module Development Environment Industry Standards
> +#
> +# This Package provides headers and libraries that conform to EFI/PI Industry standards.
> +# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2012-2014, ARM Ltd. All rights reserved.<BR>
> +# Copyright (c) 2018, Linaro. All rights reserved.<BR>
> +#
> +#    This program and the accompanying materials are licensed and made available under
> +#    the terms and conditions of the BSD License which accompanies this distribution.
> +#    The full text of the license may be found at
> +#    http://opensource.org/licenses/bsd-license.php
> +#
> +#    THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +#    WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +#**/
> +
> +[Defines]
> +  DEC_SPECIFICATION              = 0x00010019
> +  PACKAGE_NAME                   = VirtualKeyboardDxePkg
> +  PACKAGE_GUID                   = 774326bc-20d0-4203-97e4-10dc17f7dc1a
> +  PACKAGE_VERSION                = 0.1
> +
> +################################################################################
> +#
> +# Include Section - list of Include Paths that are provided by this package.
> +#                   Comments are used for Keywords and Module Types.
> +#
> +# Supported Module Types:
> +#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
> +#
> +################################################################################
> +
> +[Guids.common]
> +  gVirtualKeyboardDxeTokenSpaceGuid    = { 0x80caf901, 0x0cf6, 0x4c09, { 0x89, 0x84, 0x61, 0xd1, 0xf3, 0xd2, 0x54, 0x39 }}
> +
> +[Protocols.common]
> +  gPlatformVirtualKeyboardProtocolGuid = { 0x0e3606d2, 0x1dc3, 0x4e6f, { 0xbe, 0x65, 0x39, 0x49, 0x82, 0xa2, 0x65, 0x47 }}
> diff --git a/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
> new file mode 100644
> index 0000000..a7e5bd0
> --- /dev/null
> +++ b/EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.inf
> @@ -0,0 +1,61 @@
> +## @file
> +# Virtual Keyboard driver.
> +#
> +# Copyright (c) 2018, Linaro Ltd. All rights reserved.<BR>
> +#
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions
> +# of the BSD License which accompanies this distribution.  The
> +# full text of the license may be found at
> +# http://opensource.org/licenses/bsd-license.php
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010019
> +  BASE_NAME                      = VirtualKeyboardDxe
> +  FILE_GUID                      = 88079b18-b42b-44aa-a6f2-b83911075e89
> +  MODULE_TYPE                    = UEFI_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializeVirtualKeyboard
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = AARCH64

Well, it's emulated, so I would hope it's valid for all architectures?

/
    Leif

> +#
> +#  DRIVER_BINDING                = gVirtualKeyboardDriverBinding
> +#  COMPONENT_NAME                = gVirtualKeyboardComponentName
> +#
> +
> +[Sources.common]
> +  ComponentName.c
> +  VirtualKeyboard.c
> +
> +[Packages]
> +  EmbeddedPkg/Drivers/VirtualKeyboardDxe/VirtualKeyboardDxe.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  IoLib
> +  ReportStatusCodeLib
> +  UefiDriverEntryPoint
> +  UefiBootServicesTableLib
> +  UefiLib
> +
> +[Protocols]
> +  gEfiDriverBindingProtocolGuid
> +  gEfiSimpleTextInProtocolGuid
> +  gEfiSimpleTextInputExProtocolGuid
> +  gPlatformVirtualKeyboardProtocolGuid
> +
> +[Depex]
> +  TRUE
> diff --git a/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h b/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h
> new file mode 100644
> index 0000000..bea3128
> --- /dev/null
> +++ b/EmbeddedPkg/Include/Protocol/PlatformVirtualKeyboard.h
> @@ -0,0 +1,65 @@
> +/** @file
> +
> +  Copyright (c) 2018, Linaro. All rights reserved.
> +
> +  This program and the accompanying materials
> +  are licensed and made available under the terms and conditions of the BSD License
> +  which accompanies this distribution.  The full text of the license may be found at
> +  http://opensource.org/licenses/bsd-license.php
> +
> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
> +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __PLATFORM_VIRTUAL_KEYBOARD_H__
> +#define __PLATFORM_VIRTUAL_KEYBOARD_H__
> +
> +//
> +// Protocol interface structure
> +//
> +typedef struct _PLATFORM_VIRTUAL_KBD_PROTOCOL  PLATFORM_VIRTUAL_KBD_PROTOCOL;
> +
> +typedef struct _VIRTUAL_KBD_KEY                VIRTUAL_KBD_KEY;
> +
> +#define VIRTUAL_KEYBOARD_KEY_SIGNATURE         SIGNATURE_32 ('v', 'k', 'b', 'd')
> +
> +struct _VIRTUAL_KBD_KEY {
> +  UINTN                    Signature;
> +  EFI_INPUT_KEY            Key;
> +};
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_REGISTER) (
> +  IN VOID
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_RESET) (
> +  IN VOID
> +  );
> +
> +typedef
> +BOOLEAN
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_QUERY) (
> +  IN VIRTUAL_KBD_KEY                           *VirtualKey
> +  );
> +
> +typedef
> +EFI_STATUS
> +(EFIAPI *PLATFORM_VIRTUAL_KBD_CLEAR) (
> +  IN VIRTUAL_KBD_KEY                           *VirtualKey
> +  );
> +
> +struct _PLATFORM_VIRTUAL_KBD_PROTOCOL {
> +  PLATFORM_VIRTUAL_KBD_REGISTER                Register;
> +  PLATFORM_VIRTUAL_KBD_RESET                   Reset;
> +  PLATFORM_VIRTUAL_KBD_QUERY                   Query;
> +  PLATFORM_VIRTUAL_KBD_CLEAR                   Clear;
> +};
> +
> +extern EFI_GUID gPlatformVirtualKeyboardProtocolGuid;
> +
> +#endif /* __PLATFORM_VIRTUAL_KEYBOARD_H__ */
> -- 
> 2.7.4
> 


  reply	other threads:[~2018-02-27 12:22 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-26  8:52 [PATCH] EmbeddedPkg/Drivers: add virtual keyboard driver Haojian Zhuang
2018-02-27 12:28 ` Leif Lindholm [this message]
2018-02-28  1:03   ` Haojian Zhuang
2018-02-28 13:36     ` Leif Lindholm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180227122847.fr2zq6nurtrlstqh@bivouac.eciton.net \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox