summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe')
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/ComponentName.c218
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c275
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c999
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h465
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf66
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.uni25
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxeExtra.uni14
7 files changed, 2062 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/ComponentName.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/ComponentName.c
new file mode 100644
index 00000000..fff6fa69
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/ComponentName.c
@@ -0,0 +1,218 @@
+/** @file
+ UEFI Component Name(2) protocol implementation for USB Mouse driver.
+
+Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "UsbMouse.h"
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gUsbMouseComponentName = {
+ UsbMouseComponentNameGetDriverName,
+ UsbMouseComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gUsbMouseComponentName2 = {
+ (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UsbMouseComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UsbMouseComponentNameGetControllerName,
+ "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbMouseDriverNameTable[] = {
+ { "eng;en", L"Usb Mouse 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 A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language 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 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
+UsbMouseComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mUsbMouseDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This == &gUsbMouseComponentName)
+ );
+}
+
+/**
+ 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 A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+ @param ChildHandle The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+ @param Language 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 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
+UsbMouseComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ USB_MOUSE_DEV *UsbMouseDev;
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;
+ EFI_USB_IO_PROTOCOL *UsbIoProtocol;
+
+ //
+ // This is a device driver, so ChildHandle must be NULL.
+ //
+ if (ChildHandle != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Check Controller's handle
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIoProtocol,
+ gUsbMouseDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiUsbIoProtocolGuid,
+ gUsbMouseDriverBinding.DriverBindingHandle,
+ ControllerHandle
+ );
+
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Status != EFI_ALREADY_STARTED) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get the device context
+ //
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ (VOID **) &SimplePointerProtocol,
+ gUsbMouseDriverBinding.DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ UsbMouseDev = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol);
+
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ UsbMouseDev->ControllerNameTable,
+ ControllerName,
+ (BOOLEAN)(This == &gUsbMouseComponentName)
+ );
+
+}
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c
new file mode 100644
index 00000000..5b03879a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c
@@ -0,0 +1,275 @@
+/** @file
+ Helper functions to parse HID report descriptor and items.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UsbMouse.h"
+
+
+/**
+ Get next HID item from report descriptor.
+
+ This function retrieves next HID item from report descriptor, according to
+ the start position.
+ According to USB HID Specification, An item is piece of information
+ about the device. All items have a one-byte prefix that contains
+ the item tag, item type, and item size.
+ There are two basic types of items: short items and long items.
+ If the item is a short item, its optional data size may be 0, 1, 2, or 4 bytes.
+ Only short item is supported here.
+
+ @param StartPos Start position of the HID item to get.
+ @param EndPos End position of the range to get the next HID item.
+ @param HidItem Buffer for the HID Item to return.
+
+ @return Pointer to end of the HID item returned.
+ NULL if no HID item retrieved.
+
+**/
+UINT8 *
+GetNextHidItem (
+ IN UINT8 *StartPos,
+ IN UINT8 *EndPos,
+ OUT HID_ITEM *HidItem
+ )
+{
+ UINT8 Temp;
+
+ if (EndPos <= StartPos) {
+ return NULL;
+ }
+
+ Temp = *StartPos;
+ StartPos++;
+
+ //
+ // Bit format of prefix byte:
+ // Bits 0-1: Size
+ // Bits 2-3: Type
+ // Bits 4-7: Tag
+ //
+ HidItem->Type = BitFieldRead8 (Temp, 2, 3);
+ HidItem->Tag = BitFieldRead8 (Temp, 4, 7);
+
+ if (HidItem->Tag == HID_ITEM_TAG_LONG) {
+ //
+ // Long Items are not supported, although we try to parse it.
+ //
+ HidItem->Format = HID_ITEM_FORMAT_LONG;
+
+ if ((EndPos - StartPos) >= 2) {
+ HidItem->Size = *StartPos++;
+ HidItem->Tag = *StartPos++;
+
+ if ((EndPos - StartPos) >= HidItem->Size) {
+ HidItem->Data.LongData = StartPos;
+ StartPos += HidItem->Size;
+ return StartPos;
+ }
+ }
+ } else {
+ HidItem->Format = HID_ITEM_FORMAT_SHORT;
+ HidItem->Size = BitFieldRead8 (Temp, 0, 1);
+
+ switch (HidItem->Size) {
+ case 0:
+ //
+ // No data
+ //
+ return StartPos;
+
+ case 1:
+ //
+ // 1-byte data
+ //
+ if ((EndPos - StartPos) >= 1) {
+ HidItem->Data.Uint8 = *StartPos++;
+ return StartPos;
+ }
+
+ case 2:
+ //
+ // 2-byte data
+ //
+ if ((EndPos - StartPos) >= 2) {
+ CopyMem (&HidItem->Data.Uint16, StartPos, sizeof (UINT16));
+ StartPos += 2;
+ return StartPos;
+ }
+
+ case 3:
+ //
+ // 4-byte data, adjust size
+ //
+ HidItem->Size = 4;
+ if ((EndPos - StartPos) >= 4) {
+ CopyMem (&HidItem->Data.Uint32, StartPos, sizeof (UINT32));
+ StartPos += 4;
+ return StartPos;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ Get data from HID item.
+
+ This function retrieves data from HID item.
+ It only supports short items, which has 4 types of data:
+ 0, 1, 2, or 4 bytes.
+
+ @param HidItem Pointer to the HID item.
+
+ @return The data of HID item.
+
+**/
+UINT32
+GetItemData (
+ IN HID_ITEM *HidItem
+ )
+{
+ //
+ // Get data from HID item.
+ //
+ switch (HidItem->Size) {
+ case 1:
+ return HidItem->Data.Uint8;
+ case 2:
+ return HidItem->Data.Uint16;
+ case 4:
+ return HidItem->Data.Uint32;
+ }
+ return 0;
+}
+
+/**
+ Parse HID item from report descriptor.
+
+ There are three item types: Main, Global, and Local.
+ This function parses these types of HID items according
+ to tag info.
+
+ @param UsbMouse The instance of USB_MOUSE_DEV
+ @param HidItem The HID item to parse
+
+**/
+VOID
+ParseHidItem (
+ IN USB_MOUSE_DEV *UsbMouse,
+ IN HID_ITEM *HidItem
+ )
+{
+ UINT8 Data;
+
+ switch (HidItem->Type) {
+
+ case HID_ITEM_TYPE_MAIN:
+ //
+ // we don't care any main items, just skip
+ //
+ return;
+
+ case HID_ITEM_TYPE_GLOBAL:
+ //
+ // For global items, we only care Usage Page tag for Button Page here
+ //
+ if (HidItem->Tag == HID_GLOBAL_ITEM_TAG_USAGE_PAGE) {
+ Data = (UINT8) GetItemData (HidItem);
+ if (Data == 0x09) {
+ //
+ // Button Page
+ //
+ UsbMouse->PrivateData.ButtonDetected = TRUE;
+ }
+ }
+ return;
+
+ case HID_ITEM_TYPE_LOCAL:
+ if (HidItem->Size == 0) {
+ //
+ // No expected data for local item
+ //
+ return ;
+ }
+
+ Data = (UINT8) GetItemData (HidItem);
+
+ switch (HidItem->Tag) {
+ case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
+ if (UsbMouse->PrivateData.ButtonDetected) {
+ UsbMouse->PrivateData.ButtonMinIndex = Data;
+ }
+ return ;
+
+ case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
+ {
+ if (UsbMouse->PrivateData.ButtonDetected) {
+ UsbMouse->PrivateData.ButtonMaxIndex = Data;
+ }
+ return ;
+ }
+
+ default:
+ return;
+ }
+ }
+}
+
+
+/**
+ Parse Mouse Report Descriptor.
+
+ According to USB HID Specification, report descriptors are
+ composed of pieces of information. Each piece of information
+ is called an Item. This function retrieves each item from
+ the report descriptor and updates USB_MOUSE_DEV.
+
+ @param UsbMouse The instance of USB_MOUSE_DEV
+ @param ReportDescriptor Report descriptor to parse
+ @param ReportSize Report descriptor size
+
+ @retval EFI_SUCCESS Report descriptor successfully parsed.
+ @retval EFI_UNSUPPORTED Report descriptor contains long item.
+
+**/
+EFI_STATUS
+ParseMouseReportDescriptor (
+ OUT USB_MOUSE_DEV *UsbMouse,
+ IN UINT8 *ReportDescriptor,
+ IN UINTN ReportSize
+ )
+{
+ UINT8 *DescriptorEnd;
+ UINT8 *Ptr;
+ HID_ITEM HidItem;
+
+ DescriptorEnd = ReportDescriptor + ReportSize;
+
+ Ptr = GetNextHidItem (ReportDescriptor, DescriptorEnd, &HidItem);
+ while (Ptr != NULL) {
+ if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {
+ //
+ // Long Item is not supported at current HID revision
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ ParseHidItem (UsbMouse, &HidItem);
+
+ Ptr = GetNextHidItem (Ptr, DescriptorEnd, &HidItem);
+ }
+
+ UsbMouse->NumberOfButtons = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1);
+ UsbMouse->XLogicMax = 127;
+ UsbMouse->YLogicMax = 127;
+ UsbMouse->XLogicMin = -127;
+ UsbMouse->YLogicMin = -127;
+
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c
new file mode 100644
index 00000000..e8055107
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.c
@@ -0,0 +1,999 @@
+/** @file
+ USB Mouse Driver that manages USB mouse and produces Simple Pointer Protocol.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "UsbMouse.h"
+
+EFI_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding = {
+ USBMouseDriverBindingSupported,
+ USBMouseDriverBindingStart,
+ USBMouseDriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+/**
+ Entrypoint of USB Mouse Driver.
+
+ This function is the entrypoint of USB Mouse Driver. It installs Driver Binding
+ Protocols together with Component Name Protocols.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+USBMouseDriverBindingEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gUsbMouseDriverBinding,
+ ImageHandle,
+ &gUsbMouseComponentName,
+ &gUsbMouseComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Check whether USB mouse driver supports this device.
+
+ @param This The USB mouse driver 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
+USBMouseDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Use the USB I/O Protocol interface to check whether Controller is
+ // a mouse device that can be managed by this driver.
+ //
+ Status = EFI_SUCCESS;
+ if (!IsUsbMouse (UsbIo)) {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+
+/**
+ Starts the mouse device with this driver.
+
+ This function consumes USB I/O Protocol, initializes USB mouse device,
+ installs Simple Pointer Protocol, and submits Asynchronous Interrupt
+ Transfer to manage the USB mouse device.
+
+ @param This The USB mouse 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 This driver supports this device.
+ @retval EFI_UNSUPPORTED This driver does not support this device.
+ @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ALREADY_STARTED This driver has been started.
+
+**/
+EFI_STATUS
+EFIAPI
+USBMouseDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ USB_MOUSE_DEV *UsbMouseDevice;
+ UINT8 EndpointNumber;
+ EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+ UINT8 Index;
+ UINT8 EndpointAddr;
+ UINT8 PollingInterval;
+ UINT8 PacketSize;
+ BOOLEAN Found;
+ EFI_TPL OldTpl;
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+ //
+ // Open USB I/O Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ (VOID **) &UsbIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit1;
+ }
+
+ UsbMouseDevice = AllocateZeroPool (sizeof (USB_MOUSE_DEV));
+ ASSERT (UsbMouseDevice != NULL);
+
+ UsbMouseDevice->UsbIo = UsbIo;
+ UsbMouseDevice->Signature = USB_MOUSE_DEV_SIGNATURE;
+
+ //
+ // Get the Device Path Protocol on Controller's handle
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &UsbMouseDevice->DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ //
+ // Report Status Code here since USB mouse will be detected next.
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_PC_PRESENCE_DETECT),
+ UsbMouseDevice->DevicePath
+ );
+
+ //
+ // Get interface & endpoint descriptor
+ //
+ UsbIo->UsbGetInterfaceDescriptor (
+ UsbIo,
+ &UsbMouseDevice->InterfaceDescriptor
+ );
+
+ EndpointNumber = UsbMouseDevice->InterfaceDescriptor.NumEndpoints;
+
+ //
+ // Traverse endpoints to find interrupt endpoint IN
+ //
+ Found = FALSE;
+ for (Index = 0; Index < EndpointNumber; Index++) {
+ UsbIo->UsbGetEndpointDescriptor (
+ UsbIo,
+ Index,
+ &EndpointDescriptor
+ );
+
+ if (((EndpointDescriptor.Attributes & (BIT0 | BIT1)) == USB_ENDPOINT_INTERRUPT) &&
+ ((EndpointDescriptor.EndpointAddress & USB_ENDPOINT_DIR_IN) != 0)) {
+ //
+ // We only care interrupt endpoint here
+ //
+ CopyMem(&UsbMouseDevice->IntEndpointDescriptor, &EndpointDescriptor, sizeof(EndpointDescriptor));
+ Found = TRUE;
+ break;
+ }
+ }
+
+ if (!Found) {
+ //
+ // Report Status Code to indicate that there is no USB mouse
+ //
+ REPORT_STATUS_CODE (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_EC_NOT_DETECTED)
+ );
+ //
+ // No interrupt endpoint found, then return unsupported.
+ //
+ Status = EFI_UNSUPPORTED;
+ goto ErrorExit;
+ }
+
+ //
+ // Report Status Code here since USB mouse has be detected.
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DETECTED),
+ UsbMouseDevice->DevicePath
+ );
+
+ Status = InitializeUsbMouseDevice (UsbMouseDevice);
+ if (EFI_ERROR (Status)) {
+ //
+ // Fail to initialize USB mouse device.
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INTERFACE_ERROR),
+ UsbMouseDevice->DevicePath
+ );
+
+ goto ErrorExit;
+ }
+
+ //
+ // Initialize and install EFI Simple Pointer Protocol.
+ //
+ UsbMouseDevice->SimplePointerProtocol.GetState = GetMouseState;
+ UsbMouseDevice->SimplePointerProtocol.Reset = UsbMouseReset;
+ UsbMouseDevice->SimplePointerProtocol.Mode = &UsbMouseDevice->Mode;
+
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ UsbMouseWaitForInput,
+ UsbMouseDevice,
+ &((UsbMouseDevice->SimplePointerProtocol).WaitForInput)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &Controller,
+ &gEfiSimplePointerProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &UsbMouseDevice->SimplePointerProtocol
+ );
+
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ //
+ // The next step would be submitting Asynchronous Interrupt Transfer on this mouse device.
+ // After that we will be able to get key data from it. Thus this is deemed as
+ // the enable action of the mouse, so report status code accordingly.
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_PC_ENABLE),
+ UsbMouseDevice->DevicePath
+ );
+
+ //
+ // Submit Asynchronous Interrupt Transfer to manage this device.
+ //
+ EndpointAddr = UsbMouseDevice->IntEndpointDescriptor.EndpointAddress;
+ PollingInterval = UsbMouseDevice->IntEndpointDescriptor.Interval;
+ PacketSize = (UINT8) (UsbMouseDevice->IntEndpointDescriptor.MaxPacketSize);
+
+ Status = UsbIo->UsbAsyncInterruptTransfer (
+ UsbIo,
+ EndpointAddr,
+ TRUE,
+ PollingInterval,
+ PacketSize,
+ OnMouseInterruptComplete,
+ UsbMouseDevice
+ );
+
+ if (EFI_ERROR (Status)) {
+ //
+ // If submit error, uninstall that interface
+ //
+ gBS->UninstallProtocolInterface (
+ Controller,
+ &gEfiSimplePointerProtocolGuid,
+ &UsbMouseDevice->SimplePointerProtocol
+ );
+ goto ErrorExit;
+ }
+
+ UsbMouseDevice->ControllerNameTable = NULL;
+ AddUnicodeString2 (
+ "eng",
+ gUsbMouseComponentName.SupportedLanguages,
+ &UsbMouseDevice->ControllerNameTable,
+ L"Generic Usb Mouse",
+ TRUE
+ );
+ AddUnicodeString2 (
+ "en",
+ gUsbMouseComponentName2.SupportedLanguages,
+ &UsbMouseDevice->ControllerNameTable,
+ L"Generic Usb Mouse",
+ FALSE
+ );
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_SUCCESS;
+
+//
+// Error handler
+//
+ErrorExit:
+ if (EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ if (UsbMouseDevice != NULL) {
+ if ((UsbMouseDevice->SimplePointerProtocol).WaitForInput != NULL) {
+ gBS->CloseEvent ((UsbMouseDevice->SimplePointerProtocol).WaitForInput);
+ }
+
+ FreePool (UsbMouseDevice);
+ UsbMouseDevice = NULL;
+ }
+ }
+
+ErrorExit1:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+
+/**
+ Stop the USB mouse device handled by this driver.
+
+ @param This The USB mouse 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_UNSUPPORTED Simple Pointer Protocol is not installed on Controller.
+ @retval Others Fail to uninstall protocols attached on the device.
+
+**/
+EFI_STATUS
+EFIAPI
+USBMouseDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ USB_MOUSE_DEV *UsbMouseDevice;
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointerProtocol;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSimplePointerProtocolGuid,
+ (VOID **) &SimplePointerProtocol,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ UsbMouseDevice = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (SimplePointerProtocol);
+
+ UsbIo = UsbMouseDevice->UsbIo;
+
+ //
+ // The key data input from this device will be disabled.
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_PC_DISABLE),
+ UsbMouseDevice->DevicePath
+ );
+
+ //
+ // Delete the Asynchronous Interrupt Transfer from this device
+ //
+ UsbIo->UsbAsyncInterruptTransfer (
+ UsbIo,
+ UsbMouseDevice->IntEndpointDescriptor.EndpointAddress,
+ FALSE,
+ UsbMouseDevice->IntEndpointDescriptor.Interval,
+ 0,
+ NULL,
+ NULL
+ );
+
+ Status = gBS->UninstallProtocolInterface (
+ Controller,
+ &gEfiSimplePointerProtocolGuid,
+ &UsbMouseDevice->SimplePointerProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Free all resources.
+ //
+ gBS->CloseEvent (UsbMouseDevice->SimplePointerProtocol.WaitForInput);
+
+ if (UsbMouseDevice->DelayedRecoveryEvent != NULL) {
+ gBS->CloseEvent (UsbMouseDevice->DelayedRecoveryEvent);
+ UsbMouseDevice->DelayedRecoveryEvent = NULL;
+ }
+
+ if (UsbMouseDevice->ControllerNameTable != NULL) {
+ FreeUnicodeStringTable (UsbMouseDevice->ControllerNameTable);
+ }
+
+ FreePool (UsbMouseDevice);
+
+ return EFI_SUCCESS;
+
+}
+
+
+/**
+ Uses USB I/O to check whether the device is a USB mouse device.
+
+ @param UsbIo Pointer to a USB I/O protocol instance.
+
+ @retval TRUE Device is a USB mouse device.
+ @retval FALSE Device is a not USB mouse device.
+
+**/
+BOOLEAN
+IsUsbMouse (
+ IN EFI_USB_IO_PROTOCOL *UsbIo
+ )
+{
+ EFI_STATUS Status;
+ EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+
+ //
+ // Get the default interface descriptor
+ //
+ Status = UsbIo->UsbGetInterfaceDescriptor (
+ UsbIo,
+ &InterfaceDescriptor
+ );
+
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ if ((InterfaceDescriptor.InterfaceClass == CLASS_HID) &&
+ (InterfaceDescriptor.InterfaceSubClass == SUBCLASS_BOOT) &&
+ (InterfaceDescriptor.InterfaceProtocol == PROTOCOL_MOUSE)
+ ) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Initialize the USB mouse device.
+
+ This function retrieves and parses HID report descriptor, and
+ initializes state of USB_MOUSE_DEV. Then it sets indefinite idle
+ rate for the device. Finally it creates event for delayed recovery,
+ which deals with device error.
+
+ @param UsbMouseDev Device instance to be initialized.
+
+ @retval EFI_SUCCESS USB mouse device successfully initialized..
+ @retval EFI_UNSUPPORTED HID descriptor type is not report descriptor.
+ @retval Other USB mouse device was not initialized successfully.
+
+**/
+EFI_STATUS
+InitializeUsbMouseDevice (
+ IN OUT USB_MOUSE_DEV *UsbMouseDev
+ )
+{
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ UINT8 Protocol;
+ EFI_STATUS Status;
+ EFI_USB_HID_DESCRIPTOR *MouseHidDesc;
+ UINT8 *ReportDesc;
+ EFI_USB_CONFIG_DESCRIPTOR ConfigDesc;
+ VOID *Buf;
+ UINT32 TransferResult;
+ UINT16 Total;
+ USB_DESC_HEAD *Head;
+ BOOLEAN Start;
+
+ UsbIo = UsbMouseDev->UsbIo;
+
+ //
+ // Get the current configuration descriptor. Note that it doesn't include other descriptors.
+ //
+ Status = UsbIo->UsbGetConfigDescriptor (
+ UsbIo,
+ &ConfigDesc
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // By issuing Get_Descriptor(Configuration) request with total length, we get the Configuration descriptor,
+ // all Interface descriptors, all Endpoint descriptors, and the HID descriptor for each interface.
+ //
+ Buf = AllocateZeroPool (ConfigDesc.TotalLength);
+ if (Buf == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = UsbGetDescriptor (
+ UsbIo,
+ (UINT16)((USB_DESC_TYPE_CONFIG << 8) | (ConfigDesc.ConfigurationValue - 1)),
+ 0,
+ ConfigDesc.TotalLength,
+ Buf,
+ &TransferResult
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (Buf);
+ return Status;
+ }
+
+ Total = 0;
+ Start = FALSE;
+ Head = (USB_DESC_HEAD *)Buf;
+ MouseHidDesc = NULL;
+
+ //
+ // Get HID descriptor from the receipt of Get_Descriptor(Configuration) request.
+ // This algorithm is based on the fact that the HID descriptor shall be interleaved
+ // between the interface and endpoint descriptors for HID interfaces.
+ //
+ while (Total < ConfigDesc.TotalLength) {
+ if (Head->Type == USB_DESC_TYPE_INTERFACE) {
+ if ((((USB_INTERFACE_DESCRIPTOR *)Head)->InterfaceNumber == UsbMouseDev->InterfaceDescriptor.InterfaceNumber) &&
+ (((USB_INTERFACE_DESCRIPTOR *)Head)->AlternateSetting == UsbMouseDev->InterfaceDescriptor.AlternateSetting)) {
+ Start = TRUE;
+ }
+ }
+ if (Start && (Head->Type == USB_DESC_TYPE_ENDPOINT)) {
+ break;
+ }
+ if (Start && (Head->Type == USB_DESC_TYPE_HID)) {
+ MouseHidDesc = (EFI_USB_HID_DESCRIPTOR *)Head;
+ break;
+ }
+ Total = Total + (UINT16)Head->Len;
+ Head = (USB_DESC_HEAD*)((UINT8 *)Buf + Total);
+ }
+
+ if (MouseHidDesc == NULL) {
+ FreePool (Buf);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get report descriptor
+ //
+ if (MouseHidDesc->HidClassDesc[0].DescriptorType != USB_DESC_TYPE_REPORT) {
+ FreePool (Buf);
+ return EFI_UNSUPPORTED;
+ }
+
+ ReportDesc = AllocateZeroPool (MouseHidDesc->HidClassDesc[0].DescriptorLength);
+ ASSERT (ReportDesc != NULL);
+
+ Status = UsbGetReportDescriptor (
+ UsbIo,
+ UsbMouseDev->InterfaceDescriptor.InterfaceNumber,
+ MouseHidDesc->HidClassDesc[0].DescriptorLength,
+ ReportDesc
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (Buf);
+ FreePool (ReportDesc);
+ return Status;
+ }
+
+ //
+ // Parse report descriptor
+ //
+ Status = ParseMouseReportDescriptor (
+ UsbMouseDev,
+ ReportDesc,
+ MouseHidDesc->HidClassDesc[0].DescriptorLength
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (Buf);
+ FreePool (ReportDesc);
+ return Status;
+ }
+
+ //
+ // Check the presence of left and right buttons,
+ // and initialize fields of EFI_SIMPLE_POINTER_MODE.
+ //
+ if (UsbMouseDev->NumberOfButtons >= 1) {
+ UsbMouseDev->Mode.LeftButton = TRUE;
+ }
+ if (UsbMouseDev->NumberOfButtons > 1) {
+ UsbMouseDev->Mode.RightButton = TRUE;
+ }
+ UsbMouseDev->Mode.ResolutionX = 8;
+ UsbMouseDev->Mode.ResolutionY = 8;
+ UsbMouseDev->Mode.ResolutionZ = 0;
+
+ //
+ // Set boot protocol for the USB mouse.
+ // This driver only supports boot protocol.
+ //
+ UsbGetProtocolRequest (
+ UsbIo,
+ UsbMouseDev->InterfaceDescriptor.InterfaceNumber,
+ &Protocol
+ );
+ if (Protocol != BOOT_PROTOCOL) {
+ Status = UsbSetProtocolRequest (
+ UsbIo,
+ UsbMouseDev->InterfaceDescriptor.InterfaceNumber,
+ BOOT_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ FreePool (Buf);
+ FreePool (ReportDesc);
+ return Status;
+ }
+ }
+
+ FreePool (Buf);
+ FreePool (ReportDesc);
+
+ //
+ // Create event for delayed recovery, which deals with device error.
+ //
+ if (UsbMouseDev->DelayedRecoveryEvent != NULL) {
+ gBS->CloseEvent (UsbMouseDev->DelayedRecoveryEvent);
+ UsbMouseDev->DelayedRecoveryEvent = 0;
+ }
+
+ gBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ USBMouseRecoveryHandler,
+ UsbMouseDev,
+ &UsbMouseDev->DelayedRecoveryEvent
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Handler function for USB mouse's asynchronous interrupt transfer.
+
+ This function is the handler function for USB mouse's asynchronous interrupt transfer
+ to manage the mouse. It parses data returned from asynchronous interrupt transfer, and
+ get button and movement state.
+
+ @param Data A pointer to a buffer that is filled with key data which is
+ retrieved via asynchronous interrupt transfer.
+ @param DataLength Indicates the size of the data buffer.
+ @param Context Pointing to USB_KB_DEV instance.
+ @param Result Indicates the result of the asynchronous interrupt transfer.
+
+ @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
+ @retval EFI_DEVICE_ERROR Hardware error occurs.
+
+**/
+EFI_STATUS
+EFIAPI
+OnMouseInterruptComplete (
+ IN VOID *Data,
+ IN UINTN DataLength,
+ IN VOID *Context,
+ IN UINT32 Result
+ )
+{
+ USB_MOUSE_DEV *UsbMouseDevice;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ UINT8 EndpointAddr;
+ UINT32 UsbResult;
+
+ UsbMouseDevice = (USB_MOUSE_DEV *) Context;
+ UsbIo = UsbMouseDevice->UsbIo;
+
+ if (Result != EFI_USB_NOERROR) {
+ //
+ // Some errors happen during the process
+ //
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_EC_INPUT_ERROR),
+ UsbMouseDevice->DevicePath
+ );
+
+ if ((Result & EFI_USB_ERR_STALL) == EFI_USB_ERR_STALL) {
+ EndpointAddr = UsbMouseDevice->IntEndpointDescriptor.EndpointAddress;
+
+ UsbClearEndpointHalt (
+ UsbIo,
+ EndpointAddr,
+ &UsbResult
+ );
+ }
+
+ //
+ // Delete & Submit this interrupt again
+ // Handler of DelayedRecoveryEvent triggered by timer will re-submit the interrupt.
+ //
+ UsbIo->UsbAsyncInterruptTransfer (
+ UsbIo,
+ UsbMouseDevice->IntEndpointDescriptor.EndpointAddress,
+ FALSE,
+ 0,
+ 0,
+ NULL,
+ NULL
+ );
+ //
+ // EFI_USB_INTERRUPT_DELAY is defined in USB standard for error handling.
+ //
+ gBS->SetTimer (
+ UsbMouseDevice->DelayedRecoveryEvent,
+ TimerRelative,
+ EFI_USB_INTERRUPT_DELAY
+ );
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // If no error and no data, just return EFI_SUCCESS.
+ //
+ if (DataLength == 0 || Data == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Check mouse Data
+ // USB HID Specification specifies following data format:
+ // Byte Bits Description
+ // 0 0 Button 1
+ // 1 Button 2
+ // 2 Button 3
+ // 4 to 7 Device-specific
+ // 1 0 to 7 X displacement
+ // 2 0 to 7 Y displacement
+ // 3 to n 0 to 7 Device specific (optional)
+ //
+ if (DataLength < 3) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ UsbMouseDevice->StateChanged = TRUE;
+
+ UsbMouseDevice->State.LeftButton = (BOOLEAN) ((*(UINT8 *) Data & BIT0) != 0);
+ UsbMouseDevice->State.RightButton = (BOOLEAN) ((*(UINT8 *) Data & BIT1) != 0);
+ UsbMouseDevice->State.RelativeMovementX += *((INT8 *) Data + 1);
+ UsbMouseDevice->State.RelativeMovementY += *((INT8 *) Data + 2);
+
+ if (DataLength > 3) {
+ UsbMouseDevice->State.RelativeMovementZ += *((INT8 *) Data + 3);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieves the current state of a pointer device.
+
+ @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance.
+ @param MouseState A pointer to the state information on the pointer device.
+
+ @retval EFI_SUCCESS The state of the pointer device was returned in State.
+ @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to
+ GetState().
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's
+ current state.
+ @retval EFI_INVALID_PARAMETER MouseState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetMouseState (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ OUT EFI_SIMPLE_POINTER_STATE *MouseState
+ )
+{
+ USB_MOUSE_DEV *MouseDev;
+
+ if (MouseState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MouseDev = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This);
+
+ if (!MouseDev->StateChanged) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Retrieve mouse state from USB_MOUSE_DEV, which was filled by OnMouseInterruptComplete()
+ //
+ CopyMem (
+ MouseState,
+ &MouseDev->State,
+ sizeof (EFI_SIMPLE_POINTER_STATE)
+ );
+
+ //
+ // Clear previous move state
+ //
+ MouseDev->State.RelativeMovementX = 0;
+ MouseDev->State.RelativeMovementY = 0;
+ MouseDev->State.RelativeMovementZ = 0;
+
+ MouseDev->StateChanged = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Resets the pointer device hardware.
+
+ @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance.
+ @param ExtendedVerification Indicates that the driver may perform a more exhaustive
+ verification operation of the device during reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbMouseReset (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ USB_MOUSE_DEV *UsbMouseDevice;
+
+ UsbMouseDevice = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL (This);
+
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (
+ EFI_PROGRESS_CODE,
+ (EFI_PERIPHERAL_MOUSE | EFI_P_PC_RESET),
+ UsbMouseDevice->DevicePath
+ );
+
+ //
+ // Clear mouse state.
+ //
+ ZeroMem (
+ &UsbMouseDevice->State,
+ sizeof (EFI_SIMPLE_POINTER_STATE)
+ );
+ UsbMouseDevice->StateChanged = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Event notification function for EFI_SIMPLE_POINTER_PROTOCOL.WaitForInput event.
+
+ @param Event Event to be signaled when there's input from mouse.
+ @param Context Points to USB_MOUSE_DEV instance.
+
+**/
+VOID
+EFIAPI
+UsbMouseWaitForInput (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ USB_MOUSE_DEV *UsbMouseDev;
+
+ UsbMouseDev = (USB_MOUSE_DEV *) Context;
+
+ //
+ // If there's input from mouse, signal the event.
+ //
+ if (UsbMouseDev->StateChanged) {
+ gBS->SignalEvent (Event);
+ }
+}
+
+/**
+ Handler for Delayed Recovery event.
+
+ This function is the handler for Delayed Recovery event triggered
+ by timer.
+ After a device error occurs, the event would be triggered
+ with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
+ is defined in USB standard for error handling.
+
+ @param Event The Delayed Recovery event.
+ @param Context Points to the USB_MOUSE_DEV instance.
+
+**/
+VOID
+EFIAPI
+USBMouseRecoveryHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ USB_MOUSE_DEV *UsbMouseDev;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ UsbMouseDev = (USB_MOUSE_DEV *) Context;
+
+ UsbIo = UsbMouseDev->UsbIo;
+
+ //
+ // Re-submit Asynchronous Interrupt Transfer for recovery.
+ //
+ UsbIo->UsbAsyncInterruptTransfer (
+ UsbIo,
+ UsbMouseDev->IntEndpointDescriptor.EndpointAddress,
+ TRUE,
+ UsbMouseDev->IntEndpointDescriptor.Interval,
+ UsbMouseDev->IntEndpointDescriptor.MaxPacketSize,
+ OnMouseInterruptComplete,
+ UsbMouseDev
+ );
+}
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h
new file mode 100644
index 00000000..84ff97a4
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouse.h
@@ -0,0 +1,465 @@
+/** @file
+ Helper routine and corresponding data struct used by USB Mouse Driver.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_USB_MOUSE_H_
+#define _EFI_USB_MOUSE_H_
+
+
+#include <Uefi.h>
+
+#include <Protocol/SimplePointer.h>
+#include <Protocol/UsbIo.h>
+#include <Protocol/DevicePath.h>
+
+#include <Library/ReportStatusCodeLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiUsbLib.h>
+#include <Library/DebugLib.h>
+
+#include <IndustryStandard/Usb.h>
+
+#define CLASS_HID 3
+#define SUBCLASS_BOOT 1
+#define PROTOCOL_MOUSE 2
+
+#define BOOT_PROTOCOL 0
+#define REPORT_PROTOCOL 1
+
+#define USB_MOUSE_DEV_SIGNATURE SIGNATURE_32 ('u', 'm', 'o', 'u')
+
+//
+// A common header for usb standard descriptor.
+// Each stand descriptor has a length and type.
+//
+#pragma pack(1)
+typedef struct {
+ UINT8 Len;
+ UINT8 Type;
+} USB_DESC_HEAD;
+#pragma pack()
+
+///
+/// Button range and status
+///
+typedef struct {
+ BOOLEAN ButtonDetected;
+ UINT8 ButtonMinIndex;
+ UINT8 ButtonMaxIndex;
+ UINT8 Reserved;
+} USB_MOUSE_BUTTON_DATA;
+
+///
+/// Device instance of USB mouse.
+///
+typedef struct {
+ UINTN Signature;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_EVENT DelayedRecoveryEvent;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ EFI_USB_ENDPOINT_DESCRIPTOR IntEndpointDescriptor;
+ UINT8 NumberOfButtons;
+ INT32 XLogicMax;
+ INT32 XLogicMin;
+ INT32 YLogicMax;
+ INT32 YLogicMin;
+ EFI_SIMPLE_POINTER_PROTOCOL SimplePointerProtocol;
+ EFI_SIMPLE_POINTER_STATE State;
+ EFI_SIMPLE_POINTER_MODE Mode;
+ BOOLEAN StateChanged;
+ USB_MOUSE_BUTTON_DATA PrivateData;
+ EFI_UNICODE_STRING_TABLE *ControllerNameTable;
+} USB_MOUSE_DEV;
+
+///
+/// General HID Item structure
+///
+
+typedef union {
+ UINT8 Uint8;
+ UINT16 Uint16;
+ UINT32 Uint32;
+ INT8 Int8;
+ INT16 Int16;
+ INT32 Int32;
+ UINT8 *LongData;
+} HID_DATA;
+
+typedef struct {
+ UINT16 Format;
+ UINT8 Size;
+ UINT8 Type;
+ UINT8 Tag;
+ HID_DATA Data;
+} HID_ITEM;
+
+#define USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL(a) \
+ CR(a, USB_MOUSE_DEV, SimplePointerProtocol, USB_MOUSE_DEV_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gUsbMouseDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gUsbMouseComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gUsbMouseComponentName2;
+
+//
+// Functions of Driver Binding Protocol
+//
+
+/**
+ Check whether USB mouse driver supports this device.
+
+ @param This The USB mouse driver 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
+USBMouseDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Starts the mouse device with this driver.
+
+ This function consumes USB I/O Protocol, initializes USB mouse device,
+ installs Simple Pointer Protocol, and submits Asynchronous Interrupt
+ Transfer to manage the USB mouse device.
+
+ @param This The USB mouse 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 This driver supports this device.
+ @retval EFI_UNSUPPORTED This driver does not support this device.
+ @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ALREADY_STARTED This driver has been started.
+
+**/
+EFI_STATUS
+EFIAPI
+USBMouseDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop the USB mouse device handled by this driver.
+
+ @param This The USB mouse 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_UNSUPPORTED Simple Pointer Protocol is not installed on Controller.
+ @retval Others Fail to uninstall protocols attached on the device.
+
+**/
+EFI_STATUS
+EFIAPI
+USBMouseDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// 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 A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param Language 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 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
+UsbMouseComponentNameGetDriverName (
+ 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 A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param ControllerHandle The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+ @param ChildHandle The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+ @param Language 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 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
+UsbMouseComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+//
+// Functions of EFI_SIMPLE_POINTER_PROTOCOL
+//
+
+/**
+ Retrieves the current state of a pointer device.
+
+ @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance.
+ @param MouseState A pointer to the state information on the pointer device.
+
+ @retval EFI_SUCCESS The state of the pointer device was returned in State.
+ @retval EFI_NOT_READY The state of the pointer device has not changed since the last call to
+ GetState().
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to retrieve the pointer device's
+ current state.
+ @retval EFI_INVALID_PARAMETER MouseState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetMouseState (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ OUT EFI_SIMPLE_POINTER_STATE *MouseState
+ );
+
+/**
+ Resets the pointer device hardware.
+
+ @param This A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance.
+ @param ExtendedVerification Indicates that the driver may perform a more exhaustive
+ verification operation of the device during reset.
+
+ @retval EFI_SUCCESS The device was reset.
+ @retval EFI_DEVICE_ERROR The device is not functioning correctly and could not be reset.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbMouseReset (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+/**
+ Event notification function for SIMPLE_POINTER.WaitForInput event.
+
+ @param Event Event to be signaled when there's input from mouse.
+ @param Context Points to USB_MOUSE_DEV instance.
+
+**/
+VOID
+EFIAPI
+UsbMouseWaitForInput (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+//
+// Internal worker functions
+//
+
+/**
+ Uses USB I/O to check whether the device is a USB mouse device.
+
+ @param UsbIo Pointer to a USB I/O protocol instance.
+
+ @retval TRUE Device is a USB mouse device.
+ @retval FALSE Device is a not USB mouse device.
+
+**/
+BOOLEAN
+IsUsbMouse (
+ IN EFI_USB_IO_PROTOCOL *UsbIo
+ );
+
+/**
+ Initialize the USB mouse device.
+
+ This function retrieves and parses HID report descriptor, and
+ initializes state of USB_MOUSE_DEV. Then it sets indefinite idle
+ rate for the device. Finally it creates event for delayed recovery,
+ which deals with device error.
+
+ @param UsbMouseDev Device instance to be initialized.
+
+ @retval EFI_SUCCESS USB mouse device successfully initialized..
+ @retval EFI_UNSUPPORTED HID descriptor type is not report descriptor.
+ @retval Other USB mouse device was not initialized successfully.
+
+**/
+EFI_STATUS
+InitializeUsbMouseDevice (
+ IN OUT USB_MOUSE_DEV *UsbMouseDev
+ );
+
+/**
+ Handler function for USB mouse's asynchronous interrupt transfer.
+
+ This function is the handler function for USB mouse's asynchronous interrupt transfer
+ to manage the mouse. It parses data returned from asynchronous interrupt transfer, and
+ get button and movement state.
+
+ @param Data A pointer to a buffer that is filled with key data which is
+ retrieved via asynchronous interrupt transfer.
+ @param DataLength Indicates the size of the data buffer.
+ @param Context Pointing to USB_KB_DEV instance.
+ @param Result Indicates the result of the asynchronous interrupt transfer.
+
+ @retval EFI_SUCCESS Asynchronous interrupt transfer is handled successfully.
+ @retval EFI_DEVICE_ERROR Hardware error occurs.
+
+**/
+EFI_STATUS
+EFIAPI
+OnMouseInterruptComplete (
+ IN VOID *Data,
+ IN UINTN DataLength,
+ IN VOID *Context,
+ IN UINT32 Result
+ );
+
+/**
+ Handler for Delayed Recovery event.
+
+ This function is the handler for Delayed Recovery event triggered
+ by timer.
+ After a device error occurs, the event would be triggered
+ with interval of EFI_USB_INTERRUPT_DELAY. EFI_USB_INTERRUPT_DELAY
+ is defined in USB standard for error handling.
+
+ @param Event The Delayed Recovery event.
+ @param Context Points to the USB_MOUSE_DEV instance.
+
+**/
+VOID
+EFIAPI
+USBMouseRecoveryHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Parse Mouse Report Descriptor.
+
+ According to USB HID Specification, report descriptors are
+ composed of pieces of information. Each piece of information
+ is called an Item. This function retrieves each item from
+ the report descriptor and updates USB_MOUSE_DEV.
+
+ @param UsbMouse The instance of USB_MOUSE_DEV
+ @param ReportDescriptor Report descriptor to parse
+ @param ReportSize Report descriptor size
+
+ @retval EFI_SUCCESS Report descriptor successfully parsed.
+ @retval EFI_UNSUPPORTED Report descriptor contains long item.
+
+**/
+EFI_STATUS
+ParseMouseReportDescriptor (
+ OUT USB_MOUSE_DEV *UsbMouse,
+ IN UINT8 *ReportDescriptor,
+ IN UINTN ReportSize
+ );
+
+#endif
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
new file mode 100644
index 00000000..3b2f5a12
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
@@ -0,0 +1,66 @@
+## @file
+# USB Mouse Driver that manages USB mouse and produces Simple Pointer Protocol.
+#
+# USB Mouse Driver consumes USB I/O Protocol and Device Path Protocol, and produces
+# Simple Pointer Protocol on USB mouse devices.
+# It manages the USB mouse device via Asynchronous Interrupt Transfer of USB I/O Protocol,
+# and parses the data according to USB HID Specification.
+# This module refers to following specifications:
+# 1. Universal Serial Bus HID Firmware Specification, ver 1.11
+# 2. UEFI Specification, v2.1
+#
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UsbMouseDxe
+ MODULE_UNI_FILE = UsbMouseDxe.uni
+ FILE_GUID = 2D2E62AA-9ECF-43b7-8219-94E7FC713DFE
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = USBMouseDriverBindingEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+# DRIVER_BINDING = gUsbMouseDriverBinding
+# COMPONENT_NAME = gUsbMouseComponentName
+# COMPONENT_NAME2 = gUsbMouseComponentName2
+#
+
+[Sources]
+ ComponentName.c
+ MouseHid.c
+ UsbMouse.c
+ UsbMouse.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ ReportStatusCodeLib
+ UefiUsbLib
+
+[Protocols]
+ gEfiUsbIoProtocolGuid ## TO_START
+ gEfiDevicePathProtocolGuid ## TO_START
+ gEfiSimplePointerProtocolGuid ## BY_START
+
+# [Event]
+# EVENT_TYPE_RELATIVE_TIMER ## CONSUMES
+#
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ UsbMouseDxeExtra.uni
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.uni b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.uni
new file mode 100644
index 00000000..70df7c6c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.uni
@@ -0,0 +1,25 @@
+// /** @file
+// USB Mouse Driver that manages USB mouse and produces Simple Pointer Protocol.
+//
+// USB Mouse Driver consumes USB I/O Protocol and Device Path Protocol, and produces
+// Simple Pointer Protocol on USB mouse devices.
+// It manages the USB mouse device via Asynchronous Interrupt Transfer of USB I/O Protocol,
+// and parses the data according to USB HID Specification.
+// This module refers to following specifications:
+// 1. Universal Serial Bus HID Firmware Specification, ver 1.11
+// 2. UEFI Specification, v2.1
+//
+// Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Manages USB mouse and produces Simple Pointer Protocol"
+
+#string STR_MODULE_DESCRIPTION #language en-US "USB Mouse Driver consumes USB I/O Protocol and Device Path Protocol, and produces Simple Pointer Protocol on USB mouse devices. It manages the USB mouse device via Asynchronous Interrupt Transfer of USB I/O Protocol, and parses the data according to USB HID Specification.<BR><BR>\n"
+ "This module refers to following specifications:<BR>\n"
+ "1. Universal Serial Bus HID Firmware Specification, ver 1.11<BR>\n"
+ "2. UEFI Specification, v2.1<BR>"
+
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxeExtra.uni b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxeExtra.uni
new file mode 100644
index 00000000..fcabd21a
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxeExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// UsbMouseDxe Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"USB Mouse DXE Driver"
+
+