[edk2-devel] [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver

Vin Xue vinxue at outlook.com
Fri Jul 17 10:01:59 UTC 2020


Incorporate the driver for the DesignWare USB3 DRD controller device
mode (peripheral) that is defined in
edk2-platforms/devel-IntelAtomProcessorE3900 branch.

The driver is supported by Intel Atom series (Merrifield/BayTrail/
CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
(6th Generation and newer).

The driver verified on AAEON UP Squared developer board (Intel
ApoloLake platform).

The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.

It is better if the driver can be ported to ARM silicon.

Cc: Ard Biesheuvel <ard.biesheuvel at arm.com>
Cc: Leif Lindholm <leif at nuviainc.com>
Signed-off-by: Vin Xue <vinxue at outlook.com>
---
 .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
 .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
 .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
 .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
 .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
 .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
 .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
 .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
 .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
 .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
 .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
 .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030 +++++++++++++++++
 .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
 .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
 .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
 .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
 .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
 .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
 .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
 .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
 .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
 .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
 22 files changed, 12352 insertions(+)
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
 create mode 100644 Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
 create mode 100644 Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
 create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
 create mode 100644 Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h

diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
new file mode 100644
index 0000000000..acb4b6a23d
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
@@ -0,0 +1,305 @@
+/** @file
+  Copyright (c) 2004 - 2017, Intel Corporation. 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 <Uefi.h>
+#include <Library/UefiLib.h>
+
+
+/**
+  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
+UsbDeviceDxeGetDriverName (
+  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
+UsbDeviceDxeGetControllerName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
+  IN  EFI_HANDLE                                      ControllerHandle,
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,
+  IN  CHAR8                                           *Language,
+  OUT CHAR16                                          **ControllerName
+  );
+
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  mUsbDeviceDxeComponentName = {
+  UsbDeviceDxeGetDriverName,
+  UsbDeviceDxeGetControllerName,
+  "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL mUsbDeviceDxeComponentName2 = {
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) UsbDeviceDxeGetDriverName,
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) UsbDeviceDxeGetControllerName,
+  "en"
+};
+
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mUsbDeviceDxeDriverNameTable[] = {
+  { "eng;en", L"Usb Device Driver" },
+  { NULL , NULL }
+};
+
+/**
+  Retrieves a Unicode string that is the user readable name of the driver.
+
+  This function retrieves the user readable name of a driver in the form of a
+  Unicode string. If the driver specified by This has a user readable name in
+  the language specified by Language, then a pointer to the driver name is
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+  by This does not support the language specified by Language,
+  then EFI_UNSUPPORTED is returned.
+
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+                                EFI_COMPONENT_NAME_PROTOCOL instance.
+
+  @param  Language[in]          A pointer to a Null-terminated ASCII string
+                                array indicating the language. This is the
+                                language of the driver name that the caller is
+                                requesting, and it must match one of the
+                                languages specified in SupportedLanguages. The
+                                number of languages supported by a driver is up
+                                to the driver writer. Language is specified
+                                in RFC 4646 or ISO 639-2 language code format.
+
+  @param  DriverName[out]       A pointer to the Unicode string to return.
+                                This Unicode string is the name of the
+                                driver specified by This in the language
+                                specified by Language.
+
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by
+                                This and the language specified by Language was
+                                returned in DriverName.
+
+  @retval EFI_INVALID_PARAMETER Language is NULL.
+
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support
+                                the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeGetDriverName (
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
+  IN  CHAR8                        *Language,
+  OUT CHAR16                       **DriverName
+  )
+{
+  return LookupUnicodeString2 (
+           Language,
+           This->SupportedLanguages,
+           mUsbDeviceDxeDriverNameTable,
+           DriverName,
+           (BOOLEAN)(This == &mUsbDeviceDxeComponentName)
+           );
+}
+
+/**
+  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 not a valid EFI_HANDLE.
+
+  @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
+UsbDeviceDxeGetControllerName (
+  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/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
new file mode 100644
index 0000000000..2732cc2e31
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
@@ -0,0 +1,395 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 "UsbDeviceDxe.h"
+#include <Guid/EventGroup.h>
+
+EFI_DRIVER_BINDING_PROTOCOL mUsbDeviceDxeDriverBinding = {
+  UsbDeviceDxeDriverSupported,
+  UsbDeviceDxeDriverStart,
+  UsbDeviceDxeDriverStop,
+  0x1,
+  NULL,
+  NULL
+};
+
+
+
+VOID
+EFIAPI
+PlatformSpecificInit (
+  VOID
+  )
+{
+  UINTN                 XhciPciMmBase;
+  EFI_PHYSICAL_ADDRESS  XhciMemBaseAddress;
+
+  XhciPciMmBase   = MmPciAddress (
+                      0,
+                      0,
+                      PCI_DEVICE_NUMBER_XHCI,
+                      PCI_FUNCTION_NUMBER_XHCI,
+                      0
+                      );
+
+
+  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
+  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
+
+  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), 0x1310800);
+
+  PmicUSBSwitchControl (TRUE);//conduction USB switch.
+  return;
+}
+
+
+VOID
+EFIAPI
+UsbDeviceDxeExitBootService (
+  EFI_EVENT  Event,
+  VOID       *Context
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
+
+  UsbXdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
+  DEBUG ((EFI_D_INFO, "UsbDeviceDxeExitBootService enter\n"));
+
+  if (UsbXdciDevContext->XdciPollTimer != NULL) {
+    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
+    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
+    UsbXdciDevContext->XdciPollTimer = NULL;
+    }
+
+  return;
+}
+
+/**
+  The USB bus driver entry pointer.
+
+  @param ImageHandle       The driver image handle.
+  @param SystemTable       The system table.
+
+  @return EFI_SUCCESS      The component name protocol is installed.
+  @return Others           Failed to init the usb driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeEntryPoint (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  return EfiLibInstallDriverBindingComponentName2 (
+           ImageHandle,
+           SystemTable,
+           &mUsbDeviceDxeDriverBinding,
+           ImageHandle,
+           &mUsbDeviceDxeComponentName,
+           &mUsbDeviceDxeComponentName2
+           );
+}
+
+/**
+  Check whether USB bus driver support this device.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller handle to check.
+  @param  RemainingDevicePath    The remaining device path.
+
+  @retval EFI_SUCCESS            The bus supports this controller.
+  @retval EFI_UNSUPPORTED        This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS                Status;
+  EFI_PCI_IO_PROTOCOL       *PciIo;
+  USB_CLASSC                UsbClassCReg;
+
+
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_CLASSCODE_OFFSET,
+                        sizeof (USB_CLASSC) / sizeof (UINT8),
+                        &UsbClassCReg
+                        );
+
+  if (EFI_ERROR (Status)) {
+    Status = EFI_UNSUPPORTED;
+    goto ON_EXIT;
+  }
+
+  //
+  // Test whether the controller belongs to USB device type
+  //
+  // 0x0C03FE / 0x0C0380
+  //
+  if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||
+      (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||
+      ((UsbClassCReg.ProgInterface != PCI_IF_USBDEV) && (UsbClassCReg.ProgInterface != 0x80))) {
+    Status = EFI_UNSUPPORTED;
+  }
+
+ON_EXIT:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  return Status;
+}
+
+
+/**
+  Start to process the controller.
+
+  @param  This                   The USB bus driver binding instance.
+  @param  Controller             The controller to check.
+  @param  RemainingDevicePath    The remaining device patch.
+
+  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
+  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
+                                 bus.
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  )
+{
+  EFI_STATUS            Status;
+  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
+  EFI_PCI_IO_PROTOCOL   *PciIo;
+  EFI_EVENT             ExitBootServicesEvent;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Entry\n"));
+
+  UsbXdciDevContext = NULL;
+
+  //
+  // Provide protocol interface
+  //
+  //
+  // Get the PCI I/O Protocol on PciHandle
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiPciIoProtocolGuid,
+                  (VOID **) &PciIo,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_BY_DRIVER
+                  );
+
+  if (EFI_ERROR (Status)) {
+    goto ErrorExit;
+  }
+
+  UsbXdciDevContext = AllocateZeroPool (sizeof (USB_XDCI_DEV_CONTEXT));
+  if (UsbXdciDevContext == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  //
+  // Initialize the driver context
+  //
+  UsbXdciDevContext->StartUpController = FALSE;
+  UsbXdciDevContext->XdciHandle = Controller;
+  UsbXdciDevContext->FirstNodePtr = NULL;
+  UsbXdciDevContext->Signature = EFI_USB_DEV_SIGNATURE;
+
+  PciIo->Pci.Read (
+               PciIo,
+               EfiPciIoWidthUint32,
+               R_OTG_BAR0,
+               1,
+               &UsbXdciDevContext->XdciMmioBarAddr
+               );
+
+  UsbXdciDevContext->XdciMmioBarAddr &= B_OTG_BAR0_BA;
+  DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode IO addr 0x%08x\n", UsbXdciDevContext->XdciMmioBarAddr));
+
+  CopyMem (
+    &(UsbXdciDevContext->UsbFunIoProtocol),
+    &mUsbFunIoProtocol,
+    sizeof (EFI_USBFN_IO_PROTOCOL)
+    );
+
+  CopyMem (
+    &(UsbXdciDevContext->UsbDevModeProtocol),
+    &mUsbDeviceModeProtocol,
+    sizeof (EFI_USB_DEVICE_MODE_PROTOCOL)
+    );
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UsbDeviceDxeExitBootService,
+                  UsbXdciDevContext,
+                  &gEfiEventExitBootServicesGuid,
+                  &ExitBootServicesEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    goto ErrorExit;
+  }
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &UsbXdciDevContext->XdciHandle,
+                  &gEfiUsbFnIoProtocolGuid,
+                  &UsbXdciDevContext->UsbFunIoProtocol,
+                  &gEfiUsbDeviceModeProtocolGuid,
+                  &UsbXdciDevContext->UsbDevModeProtocol,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - Failed to install upper protocol, Status: %r\n", Status));
+    goto ErrorExit;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "Done - install upper protocol complete\n"));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Exit\n"));
+  return Status;
+
+ErrorExit:
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  if (UsbXdciDevContext != NULL) {
+    if (UsbXdciDevContext->XdciPollTimer != NULL) {
+      gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
+      UsbXdciDevContext->XdciPollTimer = NULL;
+    }
+    FreePool (UsbXdciDevContext);
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - UsbFunIoEntryPoint - Exit\n"));
+  return Status;
+}
+
+/**
+  Stop handle the controller by this USB bus driver.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller to release.
+  @param  NumberOfChildren       The child of USB bus that opened controller
+                                 BY_CHILD.
+  @param  ChildHandleBuffer      The array of child handle.
+
+  @retval EFI_SUCCESS            The controller or children are stopped.
+  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  )
+{
+  EFI_USBFN_IO_PROTOCOL           *UsbFunIoProtocol;
+  EFI_STATUS                      Status;
+  USB_XDCI_DEV_CONTEXT            *UsbXdciDevContext;
+
+
+  //
+  // Locate USB_BUS for the current host controller
+  //
+  Status = gBS->OpenProtocol (
+                  Controller,
+                  &gEfiUsbFnIoProtocolGuid,
+                  (VOID **)&UsbFunIoProtocol,
+                  This->DriverBindingHandle,
+                  Controller,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  UsbXdciDevContext = USBFUIO_CONTEXT_FROM_PROTOCOL (UsbFunIoProtocol);
+
+  //
+  // free pool
+  //
+  while (UsbXdciDevContext->FirstNodePtr != NULL) {
+    RemoveNode (UsbFunIoProtocol, UsbXdciDevContext->FirstNodePtr);
+  }
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  UsbXdciDevContext->XdciHandle,
+                  &gEfiUsbFnIoProtocolGuid,
+                  &UsbXdciDevContext->UsbFunIoProtocol,
+                  &gEfiUsbDeviceModeProtocolGuid,
+                  &UsbXdciDevContext->UsbDevModeProtocol,
+                  NULL
+                  );
+
+  if (UsbXdciDevContext->StartUpController == TRUE) {
+    Status = StopController (UsbFunIoProtocol);
+    DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode STOP UsbFnDeInitDevice %r\n", Status));
+  }
+
+  if (UsbXdciDevContext->XdciPollTimer != NULL) {
+    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
+    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
+    UsbXdciDevContext->XdciPollTimer = NULL;
+  }
+
+  gBS->CloseProtocol (
+         Controller,
+         &gEfiPciIoProtocolGuid,
+         This->DriverBindingHandle,
+         Controller
+         );
+
+  FreePool (UsbXdciDevContext);
+  return EFI_SUCCESS;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
new file mode 100644
index 0000000000..36620f9b12
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
@@ -0,0 +1,159 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 __USB_DEVICE_DXE_H__
+#define __USB_DEVICE_DXE_H__
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DriverLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Protocol/EfiUsbFnIo.h>
+#include <Protocol/UsbDeviceModeProtocol.h>
+#include <PlatformBaseAddresses.h>
+#include <ScAccess.h>
+#include "UsbFuncIo.h"
+#include "UsbDeviceMode.h"
+
+
+#define PCI_IF_USBDEV                      0xFE
+
+#define EFI_USB_DEV_SIGNATURE              0x55534244 //"USBD"
+#define USBFUIO_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbFunIoProtocol, EFI_USB_DEV_SIGNATURE)
+#define USBUSBD_CONTEXT_FROM_PROTOCOL(a)   CR (a, USB_XDCI_DEV_CONTEXT, UsbDevModeProtocol, EFI_USB_DEV_SIGNATURE)
+
+
+typedef struct _USB_FUIO_EVENT_NODE   USB_FUIO_EVENT_NODE;
+
+#pragma pack(1)
+struct _USB_FUIO_EVENT_NODE{
+  EFI_USBFN_MESSAGE            Message;
+  UINTN                        PayloadSize;
+  EFI_USBFN_MESSAGE_PAYLOAD    Payload;
+  USB_FUIO_EVENT_NODE          *Nextptr;
+};
+
+typedef struct {
+  UINTN                         Signature;
+  UINTN                         XdciMmioBarAddr;
+  EFI_HANDLE                    XdciHandle;
+  //
+  // Timer to handle EndPoint event periodically.
+  //
+  EFI_EVENT                     XdciPollTimer;
+  EFI_USB_DEVICE_MODE_PROTOCOL  UsbDevModeProtocol;
+  EFI_USBFN_IO_PROTOCOL         UsbFunIoProtocol;
+
+  //
+  // Structure members used by UsbFunIoProtocol.
+  //
+  USB_MEM_NODE                  *FirstNodePtr;
+  EFI_USB_DEVICE_INFO           *DevInfoPtr;
+  EFI_USB_CONFIG_INFO           IndexPtrConfig;
+  EFI_USB_INTERFACE_INFO        IndexPtrInteface;
+  USB_DEVICE_ENDPOINT_INFO      IndexPtrInEp;
+  USB_DEVICE_ENDPOINT_INFO      IndexPtrOutEp;
+  XDCI_CORE_HANDLE              *XdciDrvIfHandle;
+  USB_DEV_CORE                  *DrvCore;
+  UINT16                        VendorId;
+  UINT16                        DeviceId;
+  USBD_EP_XFER_REC              EndPointXferRec[DWC_XDCI_MAX_ENDPOINTS];
+  BOOLEAN                       StartUpController;
+  BOOLEAN                       DevReConnect;
+  BOOLEAN                       DevResetFlag;
+  EFI_EVENT                     TimerEvent;
+  USB_FUIO_EVENT_NODE           *EventNodePtr;
+  //
+  // Following structure members are used by UsbDevModeProtocol.
+  //
+
+} USB_XDCI_DEV_CONTEXT;
+#pragma pack()
+
+
+
+/**
+  Check whether USB bus driver support this device.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller handle to check.
+  @param  RemainingDevicePath    The remaining device path.
+
+  @retval EFI_SUCCESS            The bus supports this controller.
+  @retval EFI_UNSUPPORTED        This device isn't supported.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverSupported (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Start to process the controller.
+
+  @param  This                   The USB bus driver binding instance.
+  @param  Controller             The controller to check.
+  @param  RemainingDevicePath    The remaining device patch.
+
+  @retval EFI_SUCCESS            The controller is controlled by the usb bus.
+  @retval EFI_ALREADY_STARTED    The controller is already controlled by the usb
+                                 bus.
+  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStart (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
+  );
+
+/**
+  Stop handle the controller by this USB bus driver.
+
+  @param  This                   The USB bus driver binding protocol.
+  @param  Controller             The controller to release.
+  @param  NumberOfChildren       The child of USB bus that opened controller
+                                 BY_CHILD.
+  @param  ChildHandleBuffer      The array of child handle.
+
+  @retval EFI_SUCCESS            The controller or children are stopped.
+  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceDxeDriverStop (
+  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
+  IN EFI_HANDLE                   Controller,
+  IN UINTN                        NumberOfChildren,
+  IN EFI_HANDLE                   *ChildHandleBuffer
+  );
+
+VOID
+EFIAPI
+PlatformSpecificInit (
+  VOID
+  );
+
+extern EFI_COMPONENT_NAME_PROTOCOL    mUsbDeviceDxeComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL   mUsbDeviceDxeComponentName2;
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
new file mode 100644
index 0000000000..acf5021327
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
@@ -0,0 +1,74 @@
+## @file
+#
+#  Copyright (c) 2008 - 2017, Intel Corporation. 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                    = 0x00010005
+  BASE_NAME                      = UsbDeviceDxe
+  FILE_GUID                      = 42CF2D4A-78B4-4B80-80F9-96A83A630D70
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = UsbDeviceDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources.common]
+  UsbDeviceDxe.c
+  UsbFuncIo.c
+  UsbIoNode.c
+  ComponentName.c
+  UsbDeviceMode.c
+  XdciDevice.c
+  XdciDWC.c
+  XdciTable.c
+  XdciUtility.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  BroxtonSiPkg/BroxtonSiPkg.dec
+  BroxtonPlatformPkg/PlatformPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  MemoryAllocationLib
+  TimerLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  PmicLib
+
+[Protocols]
+  gEfiUsbDeviceModeProtocolGuid
+  gEfiUsbFnIoProtocolGuid
+  gEfiPciIoProtocolGuid
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+
+[Guids]
+  gEfiEventExitBootServicesGuid
+
+#[BuildOptions]
+#  MSFT:*_*_*_CC_FLAGS = /D SUPPORT_SUPER_SPEED
+#  GCC:*_*_*_CC_FLAGS = -DSUPPORT_SUPER_SPEED
+
+[Depex]
+  TRUE
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
new file mode 100644
index 0000000000..48a37a37fb
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
@@ -0,0 +1,1489 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <PlatformBaseAddresses.h>
+#include <ScAccess.h>
+#include "XdciUtility.h"
+#include "UsbDeviceMode.h"
+#include "UsbDeviceDxe.h"
+
+//
+// Global USBD driver object. This is the main private driver object
+// that contains all data needed for this driver to operate.
+//
+USB_DEVICE_DRIVER_OBJ mDrvObj;
+
+//
+// Global data IO transaction request object
+//
+USB_DEVICE_IO_REQ  mCtrlIoReq = {
+  //
+  // IO information containing the Buffer and data size
+  //
+  {
+    NULL,
+    0,
+  },
+  //
+  // Note: This object is used for Control Ep transfers only
+  // therefore the endpoint info must always be NULL
+  //
+  {
+    NULL,
+    NULL,
+  }
+};
+
+//
+// global flag to signal device event processing loop to run/stop
+//
+BOOLEAN mXdciRun = FALSE;
+
+STATIC VOID
+XhciSwitchSwid(BOOLEAN enable)
+{
+  UINTN                             XhciPciMmBase;
+  EFI_PHYSICAL_ADDRESS              XhciMemBaseAddress;
+  UINT32                            DualRoleCfg0;
+  UINT32                            DualRoleCfg1;
+
+  XhciPciMmBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_XHCI, PCI_FUNCTION_NUMBER_XHCI, 0);
+  XhciMemBaseAddress = MmioRead32 ((UINTN) (XhciPciMmBase + R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
+  DEBUG ((DEBUG_INFO, "XhciPciMmBase=%x, XhciMemBaseAddress=%x\n", XhciPciMmBase, XhciMemBaseAddress));
+
+  DualRoleCfg0 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0));
+  if (enable) {
+    DualRoleCfg0 = DualRoleCfg0 | (1 << 24) | (1 << 21) | (1 << 20);
+    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Set SW ID : 0x%x \n", DualRoleCfg0));
+  }
+  else {
+    DualRoleCfg0 = DualRoleCfg0 & ~(1 << 24) & ~(1 << 21) & ~(1 << 20);
+    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Clear SW ID : 0x%x \n", DualRoleCfg0));
+  }
+  MmioWrite32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG0), DualRoleCfg0);
+
+  DualRoleCfg1 = MmioRead32 ((UINTN)(XhciMemBaseAddress + R_XHCI_MEM_DUAL_ROLE_CFG1));
+  DEBUG ((DEBUG_INFO, "DualRoleCfg1 : 0x%x \n", DualRoleCfg1));
+}
+
+VOID
+EFIAPI
+UsbdMonitorEvents (
+  IN EFI_EVENT            Event,
+  IN VOID                 *Context
+  )
+{
+  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
+  UINT32                  EventCount;
+  UINT32                  PreEventCount;
+  UINT32                  LoopCount;
+
+  XdciDevContext = (USB_XDCI_DEV_CONTEXT *) Context;
+  EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+  if (EventCount == 0) {
+    return;
+  }
+
+  LoopCount = 0;
+  PreEventCount = EventCount;
+  while (EventCount != 0) {
+    if (UsbDeviceIsrRoutineTimerBased (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
+      DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
+    }
+    EventCount = UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+    if (PreEventCount == EventCount) {
+      LoopCount++;
+      if (LoopCount >= 5) {
+        DEBUG ((DEBUG_INFO, "USB is working on a long event...\n"));
+        break;
+      }
+    } else {
+      LoopCount = 0;
+    }
+  }
+
+  return;
+}
+
+/**
+  Initializes the XDCI core
+
+  @param MmioBar       Address of MMIO BAR
+  @param XdciHndl      Double pointer to for XDCI layer to set as an
+                       opaque handle to the driver to be used in subsequent
+                       interactions with the XDCI layer.
+
+  @return EFI_SUCCESS if successfully initialized XDCI, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdInit (
+  IN UINT32    MmioBar,
+  IN VOID      **XdciHndl
+  )
+{
+  EFI_STATUS               Status = EFI_DEVICE_ERROR;
+  USB_DEV_CONFIG_PARAMS    ConfigParams;
+
+  XhciSwitchSwid(TRUE);
+
+  DEBUG ((DEBUG_INFO, "UsbdInit start\n"));
+  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
+  ConfigParams.BaseAddress  = MmioBar;
+  ConfigParams.Role = USB_ROLE_DEVICE;
+  ConfigParams.Speed = USB_SPEED_SUPER;
+
+  Status = UsbDeviceInit (&ConfigParams, XdciHndl);
+
+  DEBUG ((DEBUG_INFO, "UsbdInit status is %x\n", Status));
+  DEBUG ((DEBUG_INFO, "ConfigParams.BaseAddress 0x%x\n", ConfigParams.BaseAddress));
+
+  return Status;
+}
+
+
+/**
+  Copies relevant endpoint data from standard USB endpoint descriptors
+  to the usbEpInfo structure used by the XDCI
+
+  @param EpDest   destination structure
+  @param EpSrc    source structure
+
+  @return VOID
+
+**/
+VOID
+UsbdSetEpInfo (
+  IN USB_EP_INFO                 *EpDest,
+  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
+  )
+{
+  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
+  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
+
+  //
+  // start by clearing all data in the destination
+  //
+  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
+  EpDesc = EpSrc->EndpointDesc;
+  EpCompDesc = EpSrc->EndpointCompDesc;
+
+  if (EpDesc != NULL) {
+    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; //Bits 0-3 are ep num
+    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
+    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
+    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
+    EpDest->Interval = EpDesc->Interval;
+  }
+  if (EpCompDesc != NULL) {
+    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
+    EpDest->BurstSize = EpCompDesc->MaxBurst;
+    EpDest->Mult = EpCompDesc->BytesPerInterval;
+  }
+
+  return;
+}
+
+
+/**
+  Initializes the given endpoint
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param DevEpInfo Pointer to endpoint info structure
+                   for the endpoint to initialize
+
+  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdInitEp (
+  IN VOID                      *XdciHndl,
+  IN USB_DEVICE_ENDPOINT_INFO  *DevEpInfo
+  )
+{
+  EFI_STATUS   Status = EFI_DEVICE_ERROR;
+  USB_EP_INFO  EpInfo;
+
+  UsbdSetEpInfo (&EpInfo, DevEpInfo);
+  Status = UsbDeviceInitEp (XdciHndl, &EpInfo);
+
+  return Status;
+}
+
+
+/**
+  Callback handler used when transfer operations complete. Calls
+  upper layer routine to handle the operation.
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param XferReq   Pointer to the transfer request structure
+
+  @return VOID
+
+**/
+VOID
+EFIAPI
+UsbdXferDoneHndlr (
+  IN VOID                    *XdciHndl,
+  IN USB_XFER_REQUEST        *XferReq
+  )
+{
+  EFI_USB_DEVICE_XFER_INFO  XferInfo;
+
+  DEBUG ((DEBUG_INFO, "UsbdXferDoneHndlr\n"));
+
+  XferInfo.EndpointNum = (UINT8)XferReq->EpInfo.EpNum;
+  XferInfo.EndpointDir = XferReq->EpInfo.EpDir;
+  XferInfo.EndpointType = XferReq->EpInfo.EpType;
+  XferInfo.Buffer = XferReq->XferBuffer;
+  XferInfo.Length = XferReq->ActualXferLen;
+
+  //
+  // If this is a non-control transfer complete, notify the class driver
+  //
+  if (XferInfo.EndpointNum > 0) {
+    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
+      mDrvObj.UsbdDevObj->DataCallback (&XferInfo);
+    }
+  }
+
+  return;
+}
+
+
+/**
+  Queue a request to transmit data
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param IoReq     Pointer to IO structure containing details of the
+                   transfer request
+
+  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdEpTxData (
+  IN VOID               *XdciHndl,
+  IN USB_DEVICE_IO_REQ  *IoReq
+  )
+{
+  EFI_STATUS        Status = EFI_DEVICE_ERROR;
+  USB_XFER_REQUEST  TxReq;
+
+  //
+  //set endpoint data
+  //
+  UsbdSetEpInfo (&(TxReq.EpInfo), &(IoReq->EndpointInfo)); // set endpoint data
+
+  //
+  //if this is a control endpoint, set the number and direction
+  //
+  if (IoReq->EndpointInfo.EndpointDesc == NULL) {
+    TxReq.EpInfo.EpNum = 0;
+    TxReq.EpInfo.EpDir = UsbEpDirIn;
+  }
+
+  //
+  // setup the trasfer request
+  //
+  TxReq.XferBuffer = IoReq->IoInfo.Buffer;
+  TxReq.XferLen = IoReq->IoInfo.Length;
+  TxReq.XferDone = UsbdXferDoneHndlr;
+
+  DEBUG ((DEBUG_INFO,  "TX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x, MaxPktSize: 0x%x\n",\
+          TxReq.EpInfo.EpNum, TxReq.EpInfo.EpDir, TxReq.EpInfo.EpType, TxReq.EpInfo.MaxPktSize));
+
+  Status = UsbXdciDeviceEpTxData (XdciHndl, &TxReq);
+
+  return Status;
+}
+
+
+/**
+  Queue a request to receive data
+
+  @param XdciHndl  Pointer (handle) to the XDCI driver object
+  @param IoReq     Pointer to IO structure containing details of the
+                   receive request
+
+  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdEpRxData (
+  IN VOID               *XdciHndl,
+  IN USB_DEVICE_IO_REQ  *IoReq
+  )
+{
+  EFI_STATUS        Status = EFI_DEVICE_ERROR;
+  USB_XFER_REQUEST  RxReq;
+  UINT32            ReqPacket;
+
+  DEBUG ((DEBUG_INFO,  "RX REQUEST in: IoReq->IoInfo.Length: 0x%x\n", IoReq->IoInfo.Length));
+  DEBUG ((DEBUG_INFO,  "RX REQUEST in: MaxPacketSize: 0x%x\n", IoReq->EndpointInfo.EndpointDesc->MaxPacketSize));
+
+  if (IoReq->EndpointInfo.EndpointDesc->MaxPacketSize == 0) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // set endpoint data
+  //
+  UsbdSetEpInfo (&(RxReq.EpInfo), &(IoReq->EndpointInfo));
+
+  //
+  // setup the trasfer request
+  //
+  RxReq.XferBuffer = IoReq->IoInfo.Buffer;
+
+  //
+  // Transfer length should be multiple of USB packet size.
+  //
+  ReqPacket = IoReq->IoInfo.Length / IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
+  ReqPacket = ((IoReq->IoInfo.Length % IoReq->EndpointInfo.EndpointDesc->MaxPacketSize) == 0)? ReqPacket : ReqPacket + 1;
+  RxReq.XferLen = ReqPacket * IoReq->EndpointInfo.EndpointDesc->MaxPacketSize;
+
+  RxReq.XferDone = UsbdXferDoneHndlr;
+
+  DEBUG ((DEBUG_INFO,  "RX REQUEST: EpNum: 0x%x, epDir: 0x%x, epType: 0x%x\n",\
+          RxReq.EpInfo.EpNum, RxReq.EpInfo.EpDir, RxReq.EpInfo.EpType));
+  DEBUG ((DEBUG_INFO,  "RX REQUEST send: XferLen: 0x%x\n", RxReq.XferLen));
+
+  Status = UsbXdciDeviceEpRxData (XdciHndl, &RxReq);
+
+  return Status;
+}
+
+
+/**
+  Callback used to handle Reset events from the XDCI
+
+  @param Param Pointer to a generic callback parameter structure
+
+  @return XDCI usb status
+
+**/
+EFI_STATUS
+EFIAPI
+UsbdResetEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM  *Param
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdResetEvtHndlr\n"));
+
+  //
+  // reset device address to 0
+  //
+  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdResetHdlr() - Failed to set address in XDCI\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+  Callback used to handle Connection done events from the XDCI
+
+  @param Param Pointer to a generic callback parameter structure
+
+  @return XDCI usb status
+
+**/
+EFI_STATUS
+EFIAPI
+UsbdConnDoneEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM *Param
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdConnDoneEvtHndlr\n"));
+
+  //
+  //reset device address to 0
+  //
+  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
+  }
+
+  //
+  // set the device state to attached/connected
+  //
+  mDrvObj.State = UsbDevStateAttached;
+
+  return Status;
+}
+
+
+/**
+  Callback used to handle Control Endpoint Setup events from the XDCI
+
+  @param Param Pointer to a generic callback parameter structure
+
+  @return XDCI usb status
+
+**/
+EFI_STATUS
+EFIAPI
+UsbdSetupEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM *Param
+  )
+{
+  EFI_STATUS              Status = EFI_SUCCESS;
+  EFI_USB_DEVICE_REQUEST  Req;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr\n"));
+
+  //
+  // Fill out request object from the incomming Buffer
+  //
+  CopyMem (&Req, Param->Buffer, sizeof(EFI_USB_DEVICE_REQUEST));
+
+  Status = UsbdSetupHdlr (&Req);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr: EFI_DEVICE_ERROR\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+ * Callback used to handle XferNotReady events from the XDCI
+ *
+ * @param Param Pointer to a generic callback parameter structure
+ *
+ * @return XDCI usb status
+ */
+EFI_STATUS
+EFIAPI
+UsbdNrdyEvtHndlr (
+  IN USB_DEVICE_CALLBACK_PARAM *Param
+  )
+{
+  DEBUG ((DEBUG_INFO, "UsbdNrdyEvtHndlr\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Registers callbacks for event handlers with the XDCI layer.
+  The functions will be called as the registered events are triggered.
+
+  @param  XdciHndl to XDCI core driver
+  @return EFI_SUCCESS if successful, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdRegisterCallbacks (
+  IN VOID  *XdciHndl
+  )
+{
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_RESET_EVENT, UsbdResetEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_CONNECTION_DONE, UsbdConnDoneEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_SETUP_PKT_RECEIVED, UsbdSetupEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_XFER_NRDY, UsbdNrdyEvtHndlr) != EFI_SUCCESS) {
+    goto UdciRegCallbackError;
+  }
+
+  return EFI_SUCCESS;
+
+UdciRegCallbackError:
+  return EFI_DEVICE_ERROR;
+}
+
+
+/**
+  Returns the configuration descriptor for this device. The data
+  Buffer returned will also contain all downstream interface and
+  endpoint Buffers.
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param DescIndex the index of the descriptor to return
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetConfigDesc (
+  IN VOID      *Buffer,
+  IN UINT8     DescIndex,
+  IN UINT32    ReqLen,
+  IN UINT32    *DataLen
+  )
+{
+  EFI_STATUS             Status = EFI_DEVICE_ERROR;
+  UINT8                  NumConfigs = 0;
+  UINT32                 ConfigLen = 0;
+  USB_DEVICE_CONFIG_OBJ  *ConfigObj = NULL;
+  VOID                   *Descriptor = 0;
+  UINT32                 Length = 0;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc()\n"));
+
+  //
+  // For a CONFIGURATION request we send back all descriptors branching out
+  // from this descriptor including the INTERFACE and ENDPOINT descriptors
+  //
+  //
+  // Verify the requested configuration exists - check valid index
+  //
+  NumConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
+
+  if (DescIndex < NumConfigs) {
+    //
+    // get the configuration object using the index Offset
+    //
+    ConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + DescIndex);
+    //
+    // get the complete configuration Buffer block including Interface and Endpoint data
+    //
+    Descriptor = ConfigObj->ConfigAll;
+    //
+    // The config descriptor TotalLength has the full value for all desc Buffers
+    //
+    ConfigLen = ConfigObj->ConfigDesc->TotalLength;
+    //
+    // copy the data to the output Buffer
+    //
+    Length = MIN (ReqLen, ConfigLen);
+    CopyMem (Buffer, Descriptor, Length);
+    *DataLen = Length;
+    Status = EFI_SUCCESS;
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc() - Invalid Config index: %i\n", DescIndex));
+  }
+
+  if (Status == EFI_SUCCESS) {
+    if (ConfigObj != NULL) {
+      PrintConfigDescriptor (ConfigObj->ConfigDesc);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Sets the active configuration to the selected configuration index if it exists
+
+  @param CfgValue  the configuration value to set
+
+  @return EFI_SUCCESS if the configuration was set, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdSetConfig (
+  UINT8  CfgValue
+  )
+{
+  EFI_STATUS                 Status = EFI_DEVICE_ERROR;
+  UINT8                      numConfigs = 0;
+  USB_DEVICE_CONFIG_OBJ      *pConfigObj = NULL;
+  USB_DEVICE_INTERFACE_OBJ   *pIfObj = NULL;
+  USB_DEVICE_ENDPOINT_OBJ    *pEpObj = NULL;
+  UINT8                      cfgItr = 0;
+  UINT8                      ifItr = 0;
+  UINT8                      epItr = 0;
+  USB_DEVICE_ENDPOINT_INFO   EpInfo;
+  USB_EP_INFO                UsbEpInfo;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetConfig()\n"));
+  //
+  // Verify the requested configuration exists - check valid index
+  //
+  numConfigs = mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
+
+  if (CfgValue != 0) {
+    //
+    // Search for a matching configuration
+    //
+    for (cfgItr = 0; cfgItr < numConfigs; cfgItr++) {
+      pConfigObj = (mDrvObj.UsbdDevObj->ConfigObjs + cfgItr);
+      if (pConfigObj->ConfigDesc->ConfigurationValue == CfgValue) {
+
+        //
+        // Set the active configuration object
+        //
+        mDrvObj.ActiveConfigObj = pConfigObj;
+        //
+        // Find all interface objects for this configuration
+        //
+        for (ifItr = 0; ifItr < pConfigObj->ConfigDesc->NumInterfaces; ifItr++) {
+          pIfObj = (pConfigObj->InterfaceObjs + ifItr);
+          //
+          // Configure the Endpoints in the XDCI
+          //
+          for (epItr = 0; epItr < pIfObj->InterfaceDesc->NumEndpoints; epItr++) {
+            pEpObj = (pIfObj->EndpointObjs + epItr);
+
+            EpInfo.EndpointDesc = pEpObj->EndpointDesc;
+            EpInfo.EndpointCompDesc = pEpObj->EndpointCompDesc;
+
+            if (UsbdInitEp (mDrvObj.XdciDrvObj, &EpInfo) == EFI_SUCCESS) {
+              UsbdSetEpInfo(&UsbEpInfo, &EpInfo);
+              if (UsbDeviceEpEnable (mDrvObj.XdciDrvObj, &UsbEpInfo) == EFI_SUCCESS) {
+                Status = EFI_SUCCESS;
+              } else {
+                DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to enable endpoint\n"));
+              }
+            } else {
+              DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to initialize endpoint\n"));
+            }
+          }
+        }
+        //
+        // Let the class driver know it is configured
+        //
+        if (Status == EFI_SUCCESS) {
+          if (mDrvObj.UsbdDevObj->ConfigCallback != NULL) {
+            mDrvObj.UsbdDevObj->ConfigCallback (CfgValue);
+          }
+        }
+
+        mDrvObj.State = UsbDevStateConfigured; // we are now configured
+
+        break; // break from config search loop
+      }
+    }
+  }
+
+  if (EFI_ERROR (Status)) {
+   DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Invalid requested configuration value: %i\n", CfgValue));
+  }
+
+  return Status;
+}
+
+
+/**
+  Returns the currently active configuration value
+
+  @param Buffer    Pointer to destination Buffer to copy configuration value to
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if config value is successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetConfig (
+  VOID      *Buffer,
+  UINT32    ReqLen,
+  UINT32    *DataLen
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetConfig()\n"));
+
+  if (ReqLen >= 1) { // length of data expected must be 1
+    if (mDrvObj.ActiveConfigObj != NULL) { // assure we have a config active
+      *DataLen = 1; // one byte for ConfigurationValue
+      *(UINT8*)Buffer = mDrvObj.ActiveConfigObj->ConfigDesc->ConfigurationValue;
+
+      Status = EFI_SUCCESS;
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbdGetConfig() - No active configuration available\n"));
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdGetConfig() - Invalid data length\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+  Returns the requested string descriptor if it exists
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param DescIndex the index of the descriptor to return
+  @param LangId    the target language ID
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetStringDesc (
+  VOID      *Buffer,
+  UINT8     DescIndex,
+  UINT16    LangId,
+  UINT32    ReqLen,
+  UINT32    *DataLen
+  )
+{
+  EFI_STATUS             Status = EFI_DEVICE_ERROR;
+  UINT32                 Length = 0;
+  USB_STRING_DESCRIPTOR  *StringDesc;
+  UINT8                  Index = 0;
+  UINT8                  StrLangEntries = 0;
+  BOOLEAN                StrLangFound = FALSE;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Index: 0x%x, LangId: 0x%x, ReqLen: 0x%x\n", DescIndex, LangId, ReqLen));
+
+  //
+  // index zero of the string table contains the supported language codes
+  //
+  if (DescIndex == 0) {
+    StringDesc = (mDrvObj.UsbdDevObj->StringTable);
+    Length = MIN (ReqLen, StringDesc->Length);
+    CopyMem (Buffer, StringDesc, Length);
+    *DataLen = Length;
+    Status = EFI_SUCCESS;
+  } else {
+
+    //
+    // Verify the requested language ID is supported. String descriptor Zero
+    // (First entry in the string table) is expected to contain the language list.
+    // The requested language ID is specified in the Index member of the request.
+    //
+    StringDesc = mDrvObj.UsbdDevObj->StringTable; // get language string descriptor
+    StrLangEntries = ((StringDesc->Length - 2) >> 1);
+    DEBUG ((DEBUG_INFO, "StrLangEntries=%x\n", StrLangEntries));
+
+    DEBUG ((DEBUG_INFO, "Looking LangID: \n"));
+
+    for (Index = 0; Index < StrLangEntries; Index++) {
+      DEBUG ((DEBUG_INFO, "LangID [%x]= %x\n", Index, StringDesc->LangID [Index]));
+
+      if (StringDesc->LangID [Index] == LangId) {
+        DEBUG ((DEBUG_INFO, "Found it\n"));
+        StrLangFound = TRUE;
+      }
+    }
+
+    //
+    // If we found a matching language, attempt to get the string index requested
+    //
+    if (StrLangFound == TRUE) {
+      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: StrLangFound=Found, DescIndex=%x, StrTblEntries=%x\n", DescIndex, mDrvObj.UsbdDevObj->StrTblEntries));
+
+      if (DescIndex < mDrvObj.UsbdDevObj->StrTblEntries) {
+        //
+        // get the string descriptor for the requested index
+        //
+        StringDesc = (mDrvObj.UsbdDevObj->StringTable + DescIndex);
+
+        Length = MIN (ReqLen, StringDesc->Length);
+        DEBUG ((DEBUG_INFO, "ReqLen=%x, StringLength=%x, Length=%x\n", ReqLen, StringDesc->Length, Length));
+
+        CopyMem (Buffer, StringDesc, Length);
+        *DataLen = Length;
+        Status = EFI_SUCCESS;
+      } else {
+        DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Invalid String index in USB_REQ_GET_DESCRIPTOR request\n"));
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Unsupported String Language ID for USB_REQ_GET_DESCRIPTOR request\n"));
+    }
+  }
+
+  if (Status == EFI_SUCCESS) {
+    PrintStringDescriptor (StringDesc);
+  }
+  return Status;
+}
+
+
+#ifdef SUPPORT_SUPER_SPEED
+/**
+  Returns the configuration descriptor for this device. The data
+  Buffer returned will also contain all downstream interface and
+  endpoint Buffers.
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if descritor successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetBOSDesc (
+  IN VOID      *Buffer,
+  IN UINT32    ReqLen,
+  IN UINT32    *DataLen
+  )
+{
+  EFI_USB_BOS_DESCRIPTOR  *BosDesc = 0;
+  UINT32                  Length = 0;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetBOSDesc()\n"));
+
+  BosDesc = mDrvObj.UsbdDevObj->BosDesc;
+  Length = MIN (ReqLen, mDrvObj.UsbdDevObj->BosDesc->TotalLength);
+
+  CopyMem(Buffer, BosDesc, Length);
+  *DataLen = Length;
+
+  PrintBOSDescriptor (BosDesc);
+
+  return EFI_SUCCESS;
+}
+#endif
+
+/**
+  Returns the current status for Device/Interface/Endpoint
+
+  @param Buffer    Pointer to destination Buffer to copy descriptor data to
+  @param ReqType   The type of status to get
+  @param ReqLen    the length in bytes of the request Buffer
+  @param DataLen   Pointer whos value is to be filled with the byte count of
+                   data copied to the output Buffer
+
+  @return EFI_SUCCESS if status successfully copied, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdGetStatus (
+  VOID      *Buffer,
+  UINT8     ReqType,
+  UINT32    ReqLen,
+  UINT32    *DataLen
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdGetStatus()\n"));
+
+  if (ReqLen >= 2) { // length of data must be at least 2 bytes
+    switch (ReqType & USB_TARGET_MASK) {
+      case USB_TARGET_DEVICE:
+        *DataLen = 2; // two byte for status
+        *(UINT16*)Buffer = USB_STATUS_SELFPOWERED;
+        Status = EFI_SUCCESS;
+        break;
+
+      case USB_TARGET_INTERFACE:
+        //
+        // No implementation needed at this time
+        //
+        break;
+
+      case USB_TARGET_ENDPOINT:
+        //
+        // No implementation needed at this time
+        // Should specify if endpoint is halted. Implement as necessary.
+        //
+        break;
+
+      case USB_TARGET_OTHER:
+        //
+        // No implementation needed at this time
+        //
+        break;
+
+      default:
+        break;
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdGetStatus() - Invalid data length\n"));
+  }
+
+  return Status;
+}
+
+
+/**
+  Sets the address of the device
+
+  @param address   the address value to set
+
+  @return EFI_SUCCESS if address was set, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdSetAddress (
+  UINT8    Address
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetAddress: setting address: 0x%x\n", Address));
+
+  if (Address <= 0x7F) { // address must not be > 127
+    mDrvObj.Address = Address;
+
+    //
+    // Configure Address in the XDCI
+    //
+    Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, mDrvObj.Address);
+    if (!EFI_ERROR (Status)) {
+      mDrvObj.State = UsbDevStateAddress;
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbdSetAddress: Failed to set address in XDCI\n"));
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbdSetAddress: Invalid address: 0x%x\n", Address));
+  }
+
+  return Status;
+}
+
+
+/**
+  Handles Setup device requests. Standard requests are immediately
+  handled here, and any Class/Vendor specific requests are forwarded
+  to the class driver
+
+  @param CtrlRequest  Pointer to a device request
+
+  @return EFI_SUCCESS if request successfully handled, FALSE otherwise
+
+**/
+EFI_STATUS
+UsbdSetupHdlr (
+  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
+  )
+{
+  EFI_STATUS              Status = EFI_DEVICE_ERROR;
+  UINT8                   DescIndex = 0;
+  USB_DEVICE_DESCRIPTOR   *DevDesc = 0;
+
+  //
+  // Initialize the IO object
+  //
+  mCtrlIoReq.IoInfo.Length = 0;
+
+  DEBUG ((DEBUG_INFO, "UsbdSetupHdlr start\n"));
+  PrintDeviceRequest (CtrlRequest);
+
+  //
+  // Handle Standard Device Requests
+  //
+  if ((CtrlRequest->RequestType & USB_REQ_TYPE_MASK) == USB_REQ_TYPE_STANDARD) {
+    switch (CtrlRequest->Request) {
+      case USB_REQ_GET_DESCRIPTOR:
+        DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Host requests get descriptor\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
+          DescIndex = (CtrlRequest->Value & 0xff); // low byte is the index requested
+          switch (CtrlRequest->Value >> 8) { // high byte contains request type
+            case USB_DESC_TYPE_DEVICE:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Device\n"));
+              DevDesc = mDrvObj.UsbdDevObj->DeviceDesc;
+              //
+              // copy the data to the output Buffer
+              //
+              mCtrlIoReq.IoInfo.Length = MIN (CtrlRequest->Length, DevDesc->Length);
+              CopyMem (mCtrlIoReq.IoInfo.Buffer, DevDesc, mCtrlIoReq.IoInfo.Length);
+              PrintDeviceDescriptor (DevDesc);
+              break;
+
+            case USB_DESC_TYPE_CONFIG:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Configuration\n"));
+              Status = UsbdGetConfigDesc (
+                         mCtrlIoReq.IoInfo.Buffer,
+                         DescIndex,
+                         CtrlRequest->Length,
+                         &(mCtrlIoReq.IoInfo.Length)
+                         );
+              break;
+
+            case USB_DESC_TYPE_STRING:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: String\n"));
+              Status = UsbdGetStringDesc (
+                         mCtrlIoReq.IoInfo.Buffer,
+                         DescIndex,
+                         CtrlRequest->Index,
+                         CtrlRequest->Length,
+                         &(mCtrlIoReq.IoInfo.Length)
+                         );
+              break;
+
+#ifdef SUPPORT_SUPER_SPEED
+            case USB_DESC_TYPE_BOS:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: BOS\n"));
+              Status = UsbdGetBOSDesc (
+                         mCtrlIoReq.IoInfo.Buffer,
+                         CtrlRequest->Length,
+                         &(mCtrlIoReq.IoInfo.Length)
+                         );
+              break;
+
+            case USB_DESC_TYPE_SS_ENDPOINT_COMPANION:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Endpoint Companion\n"));
+              break;
+#endif
+
+            default:
+              DEBUG ((DEBUG_INFO, "Descriptor tyep: Unsupported, USB_REQ_GET_DESCRIPTOR request: 0x%x\n", (CtrlRequest->Value >> 8)));
+              break;
+          }
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr() - Invalid direction for USB_REQ_GET_DESCRIPTOR request\n"));
+        }
+        break;
+
+      case USB_REQ_GET_CONFIG:
+        DEBUG ((DEBUG_INFO, "USB_REQ_GET_CONFIG\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_D_TO_H) {
+          Status = UsbdGetConfig (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_CONFIG request\n"));
+        }
+        break;
+
+      case USB_REQ_SET_CONFIG:
+        DEBUG ((DEBUG_INFO, "USB_REQ_SET_CONFIG\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
+          Status = UsbdSetConfig ((UINT8)CtrlRequest->Value);
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_CONFIG request\n"));
+        }
+        break;
+
+      case USB_REQ_SET_ADDRESS:
+        DEBUG ((DEBUG_INFO, "USB_REQ_SET_ADDRESS\n"));
+        if (CtrlRequest->RequestType == USB_RT_TX_DIR_H_TO_D) {
+          Status = UsbdSetAddress ((UINT8)CtrlRequest->Value);
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_SET_ADDRESS request\n"));
+        }
+        break;
+
+      case USB_REQ_GET_STATUS:
+        DEBUG ((DEBUG_INFO, "USB_REQ_GET_STATUS\n"));
+        if (CtrlRequest->RequestType & USB_RT_TX_DIR_D_TO_H) {
+          Status = UsbdGetStatus (mCtrlIoReq.IoInfo.Buffer, CtrlRequest->RequestType, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for USB_REQ_GET_STATUS request\n"));
+        }
+        break;
+#ifdef SUPPORT_SUPER_SPEED
+      case USB_REQ_CLEAR_FEATURE:
+      case USB_REQ_SET_FEATURE:
+      case USB_REQ_SET_DESCRIPTOR:
+      case USB_REQ_GET_INTERFACE:
+      case USB_REQ_SET_INTERFACE:
+      case USB_REQ_SYNCH_FRAME:
+#endif
+      default:
+         DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Unsupported Standard Request: 0x%x\n", CtrlRequest->Request));
+          break;
+    }
+  } else { // This is not a Standard request, it specifies Class/Vendor handling
+    //
+    // Forward request to class driver
+    //
+    DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Class/Vendor Request\n"));
+    if (mDrvObj.UsbdDevObj->SetupCallback != NULL) {
+      mDrvObj.UsbdDevObj->SetupCallback (CtrlRequest, &(mCtrlIoReq.IoInfo));
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "dataLen=%x\n", mCtrlIoReq.IoInfo.Length));
+  //
+  // Transfer data according to request if necessary
+  //
+  if (mCtrlIoReq.IoInfo.Length> 0) {
+    Status = UsbdEpTxData (mDrvObj.XdciDrvObj, &mCtrlIoReq);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to TX data\n"));
+    }
+  } else {
+    //
+    // If we are not responding with data, send control status
+    //
+    Status = UsbDeviceEp0TxStatus (mDrvObj.XdciDrvObj);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to Tx Ep0 Status\n"));
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Handles Connection done events. Sets the device address to zero.
+
+  @return EFI_SUCCESS if able to set the address, EFI_DEVICE_ERROR otherwise
+
+**/
+EFI_STATUS
+UsbdConnDoneHdlr (
+  VOID
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr()\n"));
+
+  //
+  // reset device address to 0
+  //
+  Status = UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in XDCI\n"));
+  }
+
+  //
+  // set the device state to attached/connected
+  //
+  mDrvObj.State = UsbDevStateAttached;
+
+  return Status;
+}
+
+
+/**
+  Handles transmit/receive completion events. Directly handles
+  control endpoint events and forwards class/vendor specific events
+  to the class drivers.
+
+  @param   XferInfo   Pointer to Xfer structure
+
+  @return
+
+**/
+VOID
+UsbdXferDoneHdlr (
+  IN EFI_USB_DEVICE_XFER_INFO    *XferInfo
+  )
+{
+  //
+  // If this is a non-control transfer complete, notify the class driver
+  //
+  if (XferInfo->EndpointNum > 0) {
+    if (mDrvObj.UsbdDevObj->DataCallback != NULL) {
+      mDrvObj.UsbdDevObj->DataCallback (XferInfo);
+    }
+  }
+
+  return;
+}
+
+
+/**
+  Binds a USB class driver with this USB device driver core.
+  After calling this routine, the driver is ready to begin
+  USB processing.
+
+  @param  UsbdDevObj   Pointer to a usbd device object which contains
+                       all relevant information for the class driver device
+
+  @return TRUE if binding was successful, FALSE otherwise
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceBind (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_OBJ                             *UsbdDevObj
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+
+  //
+  // allocate Tx Buffer
+  //
+  mCtrlIoReq.IoInfo.Buffer = AllocateZeroPool (USB_EPO_MAX_PKT_SIZE_ALL);
+  if (mCtrlIoReq.IoInfo.Buffer != NULL) {
+    mDrvObj.UsbdDevObj = UsbdDevObj;
+    mDrvObj.ActiveConfigObj = NULL;
+    mDrvObj.Address = 0;
+    mDrvObj.State = UsbDevStateInit;
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceBind() - Failed to allocate IO Buffer\n"));
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  return Status;
+}
+
+
+/**
+  Unbinds the USB class driver from this USB device driver core.
+
+  @return TRUE if successful, FALSE otherwise
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceUnbind (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  mDrvObj.UsbdDevObj = NULL;
+  mDrvObj.ActiveConfigObj = NULL;
+  mDrvObj.Address = 0;
+  mDrvObj.State = UsbDevStateOff;
+  mDrvObj.XdciInitialized = FALSE;
+
+  //
+  // release allocated Buffer data
+  //
+  if (mCtrlIoReq.IoInfo.Buffer) {
+    FreePool (mCtrlIoReq.IoInfo.Buffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Performs continual USB device event processing until a cancel
+  event occurs
+
+  @param   TimeoutMs   Connection timeout in ms. If 0, waits forever.
+  @return  TRUE if run executed normally, FALSE if error ocurred
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceRun (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN UINT32                                     TimeoutMs
+  )
+{
+  EFI_STATUS              Status = EFI_DEVICE_ERROR;
+  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
+
+  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
+
+  //
+  // can only run if XDCI is initialized
+  //
+  if ((mDrvObj.XdciInitialized == TRUE)) {
+
+    if ((mDrvObj.State == UsbDevStateConfigured) && (XdciDevContext->XdciPollTimer == NULL)) {
+      Status = gBS->CreateEvent (
+                      EVT_TIMER | EVT_NOTIFY_SIGNAL,
+                      TPL_NOTIFY,
+                      UsbdMonitorEvents,
+                      XdciDevContext,
+                      &XdciDevContext->XdciPollTimer
+                      );
+      if (!EFI_ERROR (Status)) {
+        Status = gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (20));
+        DEBUG ((EFI_D_ERROR, "UsbDeviceRun Create Event\n"));
+      }
+    }
+
+    mXdciRun = TRUE; // set the run flag to active
+    Status = EFI_SUCCESS;
+
+    //
+    // start the Event processing loop
+    //
+    while (TRUE) {
+      if (XdciDevContext->XdciPollTimer == NULL) {
+        if (UsbDeviceIsrRoutine (mDrvObj.XdciDrvObj) != EFI_SUCCESS) {
+          DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event ISR\n"));
+        }
+      }
+
+      //
+      // Check if a run cancel request exists, if so exit processing loop
+      //
+      if (mXdciRun == FALSE) {
+        if (XdciDevContext->XdciPollTimer != NULL) {
+          DEBUG ((EFI_D_ERROR, "UsbDeviceRun close Event\n"));
+          gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerCancel, 0);
+          gBS->CloseEvent (XdciDevContext->XdciPollTimer);
+          XdciDevContext->XdciPollTimer = NULL;
+        }
+        Status = EFI_SUCCESS;
+        DEBUG ((DEBUG_INFO, "UsbDeviceRun() - processing was cancelled\n"));
+        break;
+      }
+
+      //
+      // check for timeout
+      //
+      if (TimeoutMs == 0)
+        return EFI_TIMEOUT;
+      gBS->Stall (50);
+      TimeoutMs--;
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  Sets a flag to stop the running device processing loop
+
+  @return TRUE always
+
+**/
+EFI_STATUS
+EFIAPI
+UsbDeviceStop (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  mXdciRun = FALSE; // set run flag to FALSE to stop processing
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceInitXdci (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  EFI_STATUS            Status = EFI_DEVICE_ERROR;
+  USB_XDCI_DEV_CONTEXT  *XdciDevContext;
+
+  XdciDevContext = USBUSBD_CONTEXT_FROM_PROTOCOL (This);
+
+  PlatformSpecificInit ();
+
+  if (mDrvObj.XdciInitialized == FALSE) {
+    if (XdciDevContext->XdciMmioBarAddr != 0) {
+
+      //
+      // Initialize device controller driver
+      //
+      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Initializing Controller...\n"));
+
+      //
+      // Initialize the device controller interface
+      //
+      if (UsbdInit ((UINT32)XdciDevContext->XdciMmioBarAddr, &mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+
+        //
+        // Setup callbacks
+        //
+        if (UsbdRegisterCallbacks (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+
+          mDrvObj.XdciInitialized = TRUE;
+          Status = EFI_SUCCESS;
+
+          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Controller initialization complete\n"));
+        } else {
+          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to register UDCI callbacks\n"));
+        }
+      } else {
+        DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to initialize UDCI\n"));
+      }
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI MMIO BAR not set\n"));
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI already initialized\n"));
+    Status = EFI_ALREADY_STARTED;
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceConnect(
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO,  "UsbDeviceConnect \n"));
+  if (UsbXdciDeviceConnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+    Status = EFI_SUCCESS;
+  }
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceDisConnect (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO,  "UsbDeviceDisConnect \n"));
+  if (UsbDeviceDisconnect (mDrvObj.XdciDrvObj) == EFI_SUCCESS) {
+    mDrvObj.State = UsbDevStateInit;
+    Status = EFI_SUCCESS;
+  }
+
+  XhciSwitchSwid(FALSE);
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceEpTxData(
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = UsbdEpTxData (mDrvObj.XdciDrvObj, IoRequest);
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbDeviceEpRxData(
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = UsbdEpRxData (mDrvObj.XdciDrvObj, IoRequest);
+  return Status;
+}
+
+
+//
+// The Runtime UsbDeviceMode Protocol instance produced by this driver
+//
+EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol = {
+  UsbDeviceInitXdci,
+  UsbDeviceConnect,
+  UsbDeviceDisConnect,
+  UsbDeviceEpTxData,
+  UsbDeviceEpRxData,
+  UsbDeviceBind,
+  UsbDeviceUnbind,
+  UsbDeviceRun,
+  UsbDeviceStop
+};
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
new file mode 100644
index 0000000000..ac9c89b2f1
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
@@ -0,0 +1,39 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 _USB_DEVICE_MODE_DXE_H_
+#define _USB_DEVICE_MODE_DXE_H_
+
+#include <Uefi.h>
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UsbDeviceLib.h>
+#include <Protocol/UsbDeviceModeProtocol.h>
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+
+
+///
+/// Function declaration
+///
+EFI_STATUS
+UsbdSetupHdlr (
+  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
+  );
+
+extern EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol;
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
new file mode 100644
index 0000000000..a4138328fd
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
@@ -0,0 +1,2221 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 "UsbDeviceDxe.h"
+
+//
+// 16 bytes in a guid x 2 characters per byte, 4 chars for dashes and a NUL
+//
+#define CHARS_IN_GUID (sizeof(GUID) * 2 + 4 + 1)
+
+//
+// Strings that get sent with the USB Connection
+//
+static CHAR16 mUsbFnDxeMfgString[] = L"Intel Corporation";
+static CHAR16 mUsbFnDxeProductString[] = L"Broxton";
+static CHAR16 mUsbFnDxeSerialNumber[] = L"INT123456";
+
+//
+// Duplicated from MiscSystemManufacturerData.c Some parts of it will
+// replaced with device-specific unique values.
+//
+static GUID mSmBiosUniqueGuid = {
+        0x5e24fe9c, 0xc8d0, 0x45bd, 0xa7, 0x9f, 0x54, 0xea, 0x5f, 0xbd, 0x3d, 0x97
+    };
+
+EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol = {
+  EFI_USBFN_IO_PROTOCOL_REVISION,
+  DetectPort,
+  ConfigureEnableEndpoints,
+  GetEndpointMaxPacketSize,
+  GetDeviceInfo,
+  GetVendorIdProductId,
+  AbortTransfer,
+  GetEndpointStallState,
+  SetEndpointStallState,
+  EventHandler,
+  Transfer,
+  GetMaxTransferSize,
+  AllocateTransferBuffer,
+  FreeTransferBuffer,
+  StartController,
+  StopController,
+  SetEndpointPolicy,
+  GetEndpointPolicy
+};
+
+
+EFI_STATUS
+PrintEventBuffer(
+  IN  EFI_USBFN_IO_PROTOCOL  *This
+  )
+{
+  UINT32                          EventCount;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  UINT32                          Index;
+  UINT32                          *DbBufPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+
+  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
+
+  DbBufPtr = (UINT32*)(UINTN)XdciCorePtr->CurrentEventBuffer;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: XdciCorePtr->AlignedEventBuffers 0x%08x\n", (UINTN)XdciCorePtr->AlignedEventBuffers));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_S\n"));
+  for (Index = 0; Index < ((EventCount / 4) + 1); Index++) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "0x%08x\n", DbBufPtr[Index]));
+  }
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_E\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+Debug End
+**/
+
+/**
+  Returns information about what type of device was attached.
+
+  @param[in]  This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] PortType           Returns the USB port type.
+
+
+  @retval EFI_SUCCESS            The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
+  @retval EFI_DEVICE_ERROR       The physical device reported an error.
+  @retval EFI_NOT_READY          The physical device is busy or not ready to
+                                 process this request or the device is not
+                                 attached to the host.
+
+
+**/
+EFI_STATUS
+EFIAPI
+DetectPort (
+  IN  EFI_USBFN_IO_PROTOCOL  *This,
+  OUT EFI_USBFN_PORT_TYPE    *PortType
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            Status;
+  UINT8                 Value8;
+
+  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  //
+  // USBSRCDETRSLT Bit[5:2]
+  // Result of USB HW Source Detection algorithm
+  // Power-Domain: VRTC
+  // Result of USB HW Source Detection algorithm :
+  // 0000 = Not determined
+  // 0001 = SDP Attached
+  // 0010 = DCP Attached
+  // 0011 = CDP Attached
+  // 0100 = ACA Attached
+  // 0101 = SE1 Attached
+  // 0110 = MHL Attached
+  // 0111 = Floating D+/D- Attached
+  // 1000 = Other Attached
+  // 1001 = DCP detected by ext. USB PHY
+  // 1010-1111 = Rsvd
+  // Reset: 0000B
+  //
+
+  Value8 =PmicRead8 (0x5E, 0X29);
+  if ((Value8 & 0x03) != 0x02) {
+    *PortType = EfiUsbUnknownPort;
+    Status = EFI_NOT_READY;
+    goto out;
+  }
+
+  Value8 = Value8 >> 2 & 0x0f;
+  Status = EFI_SUCCESS;
+  switch (Value8) {
+    case 1:
+      *PortType = EfiUsbStandardDownstreamPort;
+      break;
+    case 2:
+      *PortType = EfiUsbDedicatedChargingPort;
+      break;
+    case 3:
+      *PortType = EfiUsbChargingDownstreamPort;
+      break;
+
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+      *PortType = EfiUsbUnknownPort;
+      break;
+    case 0:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+      *PortType = EfiUsbUnknownPort;
+      Status = EFI_NOT_READY;
+     break;
+  }
+
+out:
+  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  The AllocateTransferBuffer function allocates a memory region of Size bytes
+  and returns the address of the allocated memory that satisfies underlying
+  controller requirements in the location referenced by Buffer.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] Size               The number of bytes to allocate for the transfer
+                                Buffer.
+  @param[in] Buffer             A pointer to a pointer to the allocated Buffer
+                                if the call succeeds; undefined otherwise.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval The requested transfer Buffer could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+AllocateTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN UINTN                    Size,
+  OUT VOID                    **Buffer
+  )
+{
+  EFI_STATUS            Status;
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  VOID                  *AllocateBufferPtr;
+  USB_MEM_NODE          *NodePtr;
+
+  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (Size == 0) {
+    Status = EFI_INVALID_PARAMETER;
+    goto ErrorExit;
+  }
+
+  AllocateBufferPtr = AllocateZeroPool (Size);
+
+  if (AllocateBufferPtr == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  //
+  // Create new node
+  //
+  Status = InsertNewNodeToHead (This, &NodePtr);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  NodePtr->Size = Size;
+  NodePtr->AllocatePtr = AllocateBufferPtr;
+
+  *Buffer = AllocateBufferPtr;
+
+  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer addr 0x%08x\n", AllocateBufferPtr));
+  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Exit\n"));
+  return EFI_SUCCESS;
+
+ErrorExit:
+
+  DEBUG ((USB_FUIO_DEBUG_ERROR, "AllocateTransferBuffer - ERRROR %r\n",Status));
+  return Status;
+}
+
+
+/**
+  Deallocates the memory allocated for the transfer Buffer by
+  AllocateTransferBuffer function.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] Buffer             Buffer Pointer to the transfer Buffer
+                                to deallocate.
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+FreeTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN VOID                     *Buffer
+  )
+{
+  EFI_STATUS            Status;
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Entry\n"));
+
+  Status = RemoveNode (This, Buffer);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - ERROR\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  Configure endpoints Based on supplied device and configuration descriptors.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] DeviceInfo         A pointer to EFI_USBFN_DEVICE_INFO instance.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to
+                                lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+ConfigureEnableEndpoints (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_DEVICE_INFO           *DeviceInfo
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  Status = EFI_SUCCESS;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - Entry\n"));
+  //
+  //Assuming that the hardware has already been initialized,
+  //this function configures the endpoints using supplied
+  //DeviceInfo, activates the port, and starts receiving USB events
+  //
+  Status = EFI_SUCCESS;
+  if (DeviceInfo == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto FUNC_EXIT;
+  }
+
+  UsbFuncIoDevPtr->DevInfoPtr->DeviceDescriptor = DeviceInfo->DeviceDescriptor;
+
+  //
+  // Set Configure table
+  //
+  if (DeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
+    DEBUG ((EFI_D_ERROR, "!!!Error ConfigNum over '1' %d\n", DeviceInfo->DeviceDescriptor->NumConfigurations));
+  }
+  UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor = DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor;
+  UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[0] = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0];
+
+  //
+  // Set Interface
+  //
+  if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces > 1) {
+    DEBUG ((EFI_D_ERROR, "!!!Error NumInterfaces[0] over '1' %d\n", DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
+  }
+  UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
+
+  //
+  // Set Endpoint
+  //
+  if (UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints > 2) {
+    DEBUG ((EFI_D_ERROR, "!!!Error NumEndPoint[0] over '2' %d\n", UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints));
+  }
+
+  UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc = NULL;
+  UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc = NULL;
+
+  if ((DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0]->EndpointAddress & USB_ENDPOINT_DIR_IN) != 0) {
+    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
+    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
+  } else {
+    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
+    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc = DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, " In Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress));
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, " Out Ep Num 0x%02x\n", UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc->EndpointAddress));
+
+FUNC_EXIT:
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - exit %r\n", Status));
+  return Status;
+}
+
+/**
+  Returns the maximum packet size of the specified endpoint type for
+  the supplied bus Speed.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] EndpointType       Endpoint type as defined as EFI_USB_ENDPOINT_TYPE.
+  @param[in] BusSpeed           Bus Speed as defined as EFI_USB_BUS_SPEED.
+  @param[in] MaxPacketSize      The maximum packet size, in bytes,
+                                of the specified endpoint type.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+**/
+EFI_STATUS
+EFIAPI
+GetEndpointMaxPacketSize (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  IN EFI_USB_ENDPOINT_TYPE      EndpointType,
+  IN EFI_USB_BUS_SPEED          BusSpeed,
+  OUT UINT16                    *MaxPacketSize
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  USB_DEV_CORE                      *DevCorePtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DevCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = DevCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Entry\n"));
+
+  switch (EndpointType) {
+    case UsbEndpointControl:
+#ifdef SUPPORT_SUPER_SPEED
+      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_SS; // Default to super Speed
+#else
+      *MaxPacketSize = USB_EP0_MAX_PKT_SIZE_HS; // Default to high Speed
+#endif
+      break;
+
+    case UsbEndpointBulk:
+#ifdef SUPPORT_SUPER_SPEED
+      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_SS; // Default to super Speed
+#else
+      *MaxPacketSize = USB_BULK_EP_PKT_SIZE_HS; // Default to high Speed
+#endif
+      break;
+
+    case UsbEndpointInterrupt:
+      *MaxPacketSize = 1;
+      break;
+
+    case UsbEndpointIsochronous:
+    default:
+      Status = EFI_DEVICE_ERROR;
+      break;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Exit %r\n", Status));
+  return Status;
+}
+
+
+/**
+  Returns the maximum supported transfer size.
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] MaxTransferSize    The maximum supported transfer size, in bytes.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+**/
+EFI_STATUS
+EFIAPI
+GetMaxTransferSize (
+  IN EFI_USBFN_IO_PROTOCOL     *This,
+  OUT UINTN                    *MaxTransferSize
+  )
+{
+  //
+  // Need to check, Make max transfer package to 8MB
+  //
+  *MaxTransferSize = MAX_TRANSFER_PACKET;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function returns the unique device ID of the device--this matches
+  what is populated in the SMBIOS table.
+
+  @param[in/out] BufferSize     On input, the size of the Buffer in bytes.
+                                On output, the amount of data returned in Buffer
+                                in bytes.
+
+  @param[out] Buffer            A pointer to a Buffer to return the requested
+                                information as a Unicode string. What string are
+                                we talking about
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_BUFFER_TOO_SMALL  A parameter is invalid.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetDeviceSerialNumber (
+    IN OUT UINTN *BufferSize,
+    OUT VOID *Buffer OPTIONAL
+  )
+{
+    EFI_STATUS Status = EFI_SUCCESS;
+    CHAR16 UuidString[CHARS_IN_GUID];
+    UINTN CharsCopied;
+
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber\n"));
+    //
+    // check bounds
+    //
+    if (*BufferSize < sizeof(UuidString)) {
+        Status = EFI_BUFFER_TOO_SMALL;
+        *BufferSize = 0;
+        goto Error;
+    }
+
+    //
+    // The rest of mSmBiosUniqueGuid will be same. Note that we cannot
+    // read the SMBIOS table directly, as it might not be ready by the time we
+    // are to read it. The population of the data from the eMMC is ready
+    // by the time we are here.
+    //
+
+    //
+    // Print to to a string, and copy it off
+    //
+    CharsCopied = UnicodeSPrint(UuidString, sizeof(UuidString), L"%g", &mSmBiosUniqueGuid);
+    if (CharsCopied != (CHARS_IN_GUID - 1))
+    {
+        Status = EFI_BUFFER_TOO_SMALL;
+        *BufferSize = 0;
+        goto Error;
+    }
+    CopyMem(Buffer, UuidString, sizeof(UuidString));
+    *BufferSize = sizeof(UuidString);
+
+Error:
+
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "-GetDeviceSerialNumber, Status = 0x%08x\r\n", Status));
+
+    return Status;
+}
+
+
+/**
+  Returns device specific information Based on the supplied identifier as
+  a Unicode string
+
+  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in] Id                 Requested information id.
+  @param[in] BufferSize         On input, the size of the Buffer in bytes.
+                                On output, the amount of data returned in Buffer
+                                in bytes.
+  @param[in] Buffer             A pointer to a Buffer to return the requested
+                                information as a Unicode string. What string are
+                                we talking about
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+**/
+EFI_STATUS
+EFIAPI
+GetDeviceInfo (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  IN EFI_USBFN_DEVICE_INFO_ID   Id,
+  IN OUT UINTN                  *BufferSize,
+  OUT VOID                      *Buffer OPTIONAL
+  )
+{
+  EFI_STATUS                    Status;
+  USB_XDCI_DEV_CONTEXT          *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  Status = EFI_SUCCESS;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Entry\n"));
+
+  if ((BufferSize == 0) || (Buffer == NULL)) {
+    Status = EFI_INVALID_PARAMETER;
+    goto FUN_EXIT;
+  }
+
+  switch (Id) {
+
+    //
+    // FIXME: Get real serial number of board
+    //
+    case EfiUsbDeviceInfoSerialNumber:
+        if (*BufferSize < sizeof(mUsbFnDxeSerialNumber)) {
+            Status = EFI_BUFFER_TOO_SMALL;
+            *BufferSize = 0;
+            goto FUN_EXIT;
+        }
+        CopyMem(Buffer, mUsbFnDxeSerialNumber, sizeof(mUsbFnDxeSerialNumber));
+        *BufferSize = sizeof(mUsbFnDxeSerialNumber);
+        break;
+
+    case EfiUsbDeviceInfoManufacturerName:
+        if (*BufferSize < sizeof(mUsbFnDxeMfgString)) {
+            Status = EFI_BUFFER_TOO_SMALL;
+            *BufferSize = 0;
+            goto FUN_EXIT;
+        }
+        CopyMem(Buffer, mUsbFnDxeMfgString, sizeof(mUsbFnDxeMfgString));
+        *BufferSize = sizeof(mUsbFnDxeMfgString);
+        break;
+
+    case EfiUsbDeviceInfoProductName:
+        if (*BufferSize < sizeof(mUsbFnDxeProductString)) {
+            Status = EFI_BUFFER_TOO_SMALL;
+            *BufferSize = 0;
+            goto FUN_EXIT;
+        }
+        CopyMem(Buffer, mUsbFnDxeProductString, sizeof(mUsbFnDxeProductString));
+        *BufferSize = sizeof(mUsbFnDxeProductString);
+        break;
+
+    case EfiUsbDeviceInfoUnknown:
+    default:
+      Status = EFI_UNSUPPORTED;
+      *BufferSize = 0;
+      DEBUG ((USB_FUIO_DEBUG_ERROR, "Unknown ID %d encountered.\r\n", Id));
+      break;
+  }
+
+FUN_EXIT:
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Exit %r\n", Status));
+  return Status;
+}
+
+
+/**
+  Returns vendor-id and product-id of the device.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] Vid               Returned vendor-id of the device.
+  @param[out] Pid               Returned product-id of the device.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_NOT_FOUND         Unable to return vid or pid.
+
+**/
+EFI_STATUS
+EFIAPI
+GetVendorIdProductId (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  OUT UINT16                    *Vid,
+  OUT UINT16                    *Pid
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  //
+  //   *Vid = 0x8086
+  //   *Pid = 0x0A65
+  //
+  *Vid = UsbFuncIoDevPtr->VendorId;
+  *Pid = UsbFuncIoDevPtr->DeviceId;
+  return EFI_SUCCESS;
+}
+
+/**
+  Aborts transfer on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
+                                transfer needs to be canceled.
+  @param[in]  Direction         Direction of the endpoint.
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+AbortTransfer (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  USB_DEV_CORE                      *UsbDeviceCorePtr;
+  USB_EP_INFO                       EpInfo;
+  EFI_STATUS                        Status;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Entry\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  if (UsbFuncIoDevPtr->DevResetFlag == TRUE) {
+    return Status;
+  }
+
+  EpInfo.EpNum = EndpointIndex;
+  EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
+
+  Status = UsbDeviceEpCancelTransfer (UsbFuncIoDevPtr->DrvCore, &EpInfo);
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Exit %r\n", Status));
+  return Status;
+}
+
+/**
+  Returns the stall state on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
+                                transfer needs to be canceled.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  State             Boolean, true value indicates that the endpoint
+                                is in a stalled state, false otherwise.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+GetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN OUT BOOLEAN                  *State
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  UINT32                            EndPoint;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Entry\n"));
+
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  XdciCorePtr = UsbFuncIoDevPtr->XdciDrvIfHandle;
+
+  if (XdciCorePtr->EpHandles[EndPoint].State == USB_EP_STATE_STALLED) {
+    *State = TRUE;
+  } else {
+    *State = FALSE;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+UsbSetAddress (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT32                        Address
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  USB_DEV_CORE                      *UsbDeviceCorePtr;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - 0x%04x Entry\n", Address));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  Status = UsbDeviceSetAddress (UsbDeviceCorePtr, (UINT32)Address);
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto EXIT_SET_ADDRESS;
+  }
+
+  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_NO_RESPONSE;
+    goto EXIT_SET_ADDRESS;
+  }
+
+EXIT_SET_ADDRESS:
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - Exit %r\n", Status));
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbSetconfigure (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT32                       InterFaceIndex
+  )
+{
+  EFI_STATUS                      Status;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  UINT32                          InterfaceNum;
+  UINT32                          EndPointNum;
+  UINT32                          EndPointIndex;
+  EFI_USB_INTERFACE_INFO          *InterfaceInfoPtr;
+  USB_EP_INFO                     EpInfo;
+  USB_DEVICE_ENDPOINT_INFO        EpDescInfo;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - 0x%04x Entry\n", InterFaceIndex));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  Status = EFI_SUCCESS;
+
+  InterfaceNum = UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->NumInterfaces;
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor));
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - DescriptorType 0x%04x ; ConfigurationValue 0x%04x\n",
+          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->DescriptorType,
+          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor->ConfigurationValue
+          ));
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - InterfaceNum 0x%04x \n", InterfaceNum));
+  if (InterfaceNum < InterFaceIndex) {
+    Status = EFI_INVALID_PARAMETER;
+    goto EXIT__SET_CONFIGURE;
+  }
+
+  //
+  // Arry strart form '0', Index start from '1'.
+  //
+  InterfaceInfoPtr = UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[InterFaceIndex - 1];
+  EndPointNum = InterfaceInfoPtr->InterfaceDescriptor->NumEndpoints;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Total EP NUM 0x%04x \n", EndPointNum));
+
+  for (EndPointIndex = 0; EndPointIndex < EndPointNum; EndPointIndex++) {
+    EpDescInfo.EndpointDesc = InterfaceInfoPtr->EndpointDescriptorTable[EndPointIndex];
+    EpDescInfo.EndpointCompDesc = NULL;
+    UsbFnSetEpInfo (&EpInfo, &EpDescInfo);
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "EndpointAddress 0x%02x\n", EpDescInfo.EndpointDesc->EndpointAddress));
+
+    if (UsbDeviceInitEp (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
+       if (UsbDeviceEpEnable (UsbDeviceCorePtr, &EpInfo) == EFI_SUCCESS) {
+       } else {
+         Status = EFI_DEVICE_ERROR;
+         DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable() - Failed to enable endpoint\n"));
+       }
+    } else {
+       Status = EFI_DEVICE_ERROR;
+       DEBUG ((DEBUG_INFO, "UsbDeviceInitEp() - Failed to initialize endpoint\n"));
+    }
+  }
+
+  Status = UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_NO_RESPONSE;
+    goto EXIT__SET_CONFIGURE;
+  }
+
+
+EXIT__SET_CONFIGURE:
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Exit %r\n", Status));
+
+  return Status;
+}
+
+/**
+  Sets or clears the stall state on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which the ongoing
+                                transfer needs to be canceled.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  State             Requested stall state on the specified endpoint.
+                                True value causes the endpoint to stall;
+                                false value clears an existing stall.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+SetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN BOOLEAN                      State
+  )
+{
+  EFI_STATUS                        Status;
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  USB_EP_INFO                       pEpInfo;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Entry\n"));
+  Status = EFI_SUCCESS;
+
+  pEpInfo.EpNum = EndpointIndex;
+  pEpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
+
+  if (State == TRUE) {
+    Status = UsbDeviceEpStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
+  } else {
+    Status = UsbDeviceEpClearStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UINTN) &pEpInfo);
+  }
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Exit\n"));
+  return Status;
+}
+
+EFI_STATUS
+DeviceEventCheck(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  USBD_EVENT_BUF              *EventIndex,
+  OUT UINT32                      *ProcessSize,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  OUT BOOLEAN                     *EventFlag
+  )
+{
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          EventReg;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry....\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EventReg = (EventIndex->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
+  EventReg >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
+  *EventFlag = FALSE;
+
+  //
+  // Assume default event size. Change it in switch case if
+  // different
+  //
+  *ProcessSize =  DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+
+  switch (EventReg) {
+    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
+      *Message = EfiUsbMsgBusEventDetach;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
+      //
+      //  In resetDet will prepare setup Xfer package
+      //
+      UsbFuncIoDevPtr->DevReConnect = FALSE;
+      UsbFuncIoDevPtr->DevResetFlag = TRUE;
+
+      usbProcessDeviceResetDet (XdciCorePtr);
+      UsbDeviceSetAddress (UsbDeviceCorePtr, 0);
+      *Message = EfiUsbMsgBusEventReset;
+      *EventFlag = TRUE;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
+      usbProcessDeviceResetDone(XdciCorePtr);
+      UsbDeviceSetAddress(UsbDeviceCorePtr, 0);
+      UsbFuncIoDevPtr->DevReConnect = TRUE;
+      UsbFuncIoDevPtr->DevResetFlag = FALSE;
+      *EventFlag = TRUE;
+      *Message = EfiUsbMsgNone;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
+      *Message = EfiUsbMsgBusEventSuspend;
+      *EventFlag = TRUE;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
+      *Message = EfiUsbMsgBusEventResume;
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
+      *ProcessSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
+      *Message = EfiUsbMsgNone;
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFUDwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
+      break;
+
+    default:
+      *EventFlag = FALSE;
+      *Message = EfiUsbMsgNone;
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUWcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", EventReg));
+      break;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry exit.... \n"));
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+Ep0XferDone(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  UINT32                      EndPointNum,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  DWC_XDCI_ENDPOINT               *EpHandle;
+  DWC_XDCI_TRB                    *Trb;
+  UINT32                          TrbCtrl;
+  UINT32                          TrbSts;
+  UINT32                          BufferLen;
+  EFI_STATUS                      DevStatus;
+  USB_EP_INFO                     EpInfo;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
+  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0XferDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
+  }
+
+  DevStatus = EFI_SUCCESS;
+  BufferLen = 0;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointNum:%d, TRB: Addr 0x%08x!!!\n", EndPointNum, (UINTN)Trb));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
+
+  //
+  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
+  // check the RX request complete and continue next transfer request
+  //
+  EpHandle->CheckFlag = FALSE;
+  EpHandle->CurrentXferRscIdx = 0;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D01!!\n"));
+  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D02!!\n"));
+  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D03!!\n" ));
+  BufferLen = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D04 TrbCtrl :: %x!!\n", TrbCtrl));
+  switch (TrbCtrl) {
+    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
+      //
+      // This is delay for other host USB controller(none Intel), identify device get fail issue.
+      //
+      gBS->Stall(130);
+      BufferLen = 8;
+
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "AlignedSetupBuffer::0x%08x!!\n", XdciCorePtr->AlignedSetupBuffer));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload::0x%08x!!\n", (UINTN)Payload));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "BufferLen::0x%08x!!\n", (UINTN)BufferLen));
+      *Message = EfiUsbMsgSetupPacket;
+      CopyMem (Payload, XdciCorePtr->AlignedSetupBuffer, BufferLen);
+
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D06!!\n"));
+      if (!(XdciCorePtr->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
+        if ((XdciCorePtr->AlignedSetupBuffer[0]  == 0x00) ) {
+          if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_ADDRESS)) {
+            //
+            // set address
+            //
+            UsbSetAddress (
+              This,
+              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
+              );
+
+            *Message = EfiUsbMsgNone;
+          } else if ((XdciCorePtr->AlignedSetupBuffer[1]  == USB_DEV_SET_CONFIGURATION)) {
+            DEBUG ((USB_FUIO_DEBUG_EVENT_I, "\n set configure !!!"));
+            UsbSetconfigure (
+              This,
+              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciCorePtr->AlignedSetupBuffer[2])
+              );
+            *Message = EfiUsbMsgNone;
+          }
+        }
+      }
+
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D07!!\n"));
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
+      DEBUG ((DEBUG_INFO, "Ep0 done DWC_XDCI_TRB_CTRL_TYPE_DATA!!\n"));
+	  //
+      // Notify upper layer of control transfer completion
+      // if a callback function was registerd
+      //
+      if ((EndPointNum & 0x01) == 0) {
+        *Message = EfiUsbMsgEndpointStatusChangedRx;
+      } else {
+        *Message = EfiUsbMsgEndpointStatusChangedTx;
+      }
+      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
+      Payload->utr.Direction = (UINT8)(EndPointNum & 0x01);
+      Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
+
+      DEBUG ((DEBUG_INFO, "Ep0 EndPointNum: %x!!!\n", (UINT32)EndPointNum));
+      DEBUG ((DEBUG_INFO, "Ep0 done XferLength: %x!!!\n", (UINT32)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength));
+      Payload->utr.Buffer = (VOID*)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
+      Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
+
+      if (TrbSts == 0) {
+        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
+          Payload->utr.TransferStatus = UsbTransferStatusComplete;
+        } else {
+          Payload->utr.TransferStatus = UsbTransferStatusActive;
+        }
+      } else if (TrbSts != 0) {
+        Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_HWO_MASK;
+        *Message = EfiUsbMsgNone;
+        Payload->utr.TransferStatus = UsbTransferStatusAborted;
+        DEBUG ((DEBUG_INFO, "Flush FIFO!!!\n" ));
+        EpInfo.EpNum = 0;
+        EpInfo.EpDir =UsbEpDirIn;
+        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
+        EpInfo.EpNum = 0;
+        EpInfo.EpDir =UsbEpDirOut;
+        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
+        DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
+      }
+
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
+      Payload->utr.Buffer = (VOID*) UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferAddress;
+      Payload->utr.BytesTransferred = 0;
+      Payload->utr.EndpointIndex = (UINT8)(EndPointNum >> 1);
+      if ((EndPointNum & 0x01) == 0) {
+        *Message = EfiUsbMsgEndpointStatusChangedRx;
+      } else {
+        *Message = EfiUsbMsgEndpointStatusChangedTx;
+      }
+
+      if (TrbSts == 0) {
+        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
+          Payload->utr.TransferStatus = UsbTransferStatusComplete;
+        } else {
+          Payload->utr.TransferStatus = UsbTransferStatusActive;
+        }
+      } else if (TrbSts != 0) {
+        Payload->utr.TransferStatus = UsbTransferStatusAborted;
+      }
+
+      DevStatus = UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr->AlignedSetupBuffer);
+
+      if (DevStatus) {
+        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
+      }
+      DEBUG ((DEBUG_INFO, "Status phase done. Queue next SETUP packet==>\n"));
+      break;
+
+    default:
+      *Message = EfiUsbMsgNone;
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
+      break;
+  }
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+NoneEp0XferDone(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  UINT32                      EndPointNum,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  DWC_XDCI_ENDPOINT               *EpHandle;
+  DWC_XDCI_TRB                    *Trb;
+  UINT32                          TrbCtrl;
+  UINT32                          TrbSts;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EpHandle = &XdciCorePtr->EpHandles[EndPointNum];
+  Trb = XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "NoneEp0XferDone. HW owns TRB: %x!!!, EndPointNum: %x\n", (UINT32)(UINTN)Trb, EndPointNum));
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " TRB: Addr 0x%08x!!!\n", (UINTN)Trb));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrLow: %x!!!\n", (UINT32)Trb->BuffPtrLow));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrHigh: %x!!!\n", (UINT32)Trb->BuffPtrHigh));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->LenXferParams: %x!!!\n", (UINT32)Trb->LenXferParams));
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->TrbCtrl: %x!!!\n", (UINT32)Trb->TrbCtrl));
+
+  //
+  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
+  // check the RX request complete and continue next transfer request
+  //
+  EpHandle->CheckFlag = FALSE;
+  EpHandle->CurrentXferRscIdx = 0;
+  *Message = EfiUsbMsgNone;
+
+  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
+
+  Payload->utr.BytesTransferred = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength;
+  Payload->utr.EndpointIndex = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].LogEpNum;
+  Payload->utr.Direction = UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Direction;
+  Payload->utr.Buffer = (VOID*)(UINTN)(Trb->BuffPtrLow);
+  UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Complete = TRUE;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointAddress = 0x%08x\n", Payload->utr.EndpointIndex));
+  if (Payload->utr.Direction == EfiUsbEndpointDirectionDeviceTx) {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceTx\n"));
+    *Message = EfiUsbMsgEndpointStatusChangedTx;
+  } else {
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Direction::EfiUsbEndpointDirectionDeviceRx\n"));
+    *Message = EfiUsbMsgEndpointStatusChangedRx;
+  }
+
+  if (TrbSts == 0) {
+    if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) == 0) {
+      Payload->utr.TransferStatus = UsbTransferStatusComplete;
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
+    } else {
+      Payload->utr.TransferStatus = UsbTransferStatusComplete;
+      Payload->utr.BytesTransferred -= (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusComplete\n"));
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::Length %d \n", Payload->utr.BytesTransferred ));
+    }
+  } else if (TrbSts != 0) {
+    Payload->utr.TransferStatus = UsbTransferStatusAborted;
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::UsbTransferStatusAborted\n"));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Ep0XferNotReady(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  UINT32                      EndPointNum,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
+  IN  UINT32                      EpStatus
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+
+  *Message = EfiUsbMsgNone;
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EpEventCheck(
+  IN  EFI_USBFN_IO_PROTOCOL       *This,
+  IN  USBD_EVENT_BUF              *EventIndex,
+  OUT UINT32                      *ProcessSize,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
+  OUT BOOLEAN                     *EventFlag
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          EventReg;
+  UINT32                          EpEvent;
+  UINT32                          EndPointNumber;
+  UINT32                          EventStatus;
+  USB_EP_STATE                    Ep_State;
+  UINTN                           TmpBufferSize;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EndPoint Event....\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EventReg = EventIndex->Event;
+  *ProcessSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+  *EventFlag = TRUE;
+  TmpBufferSize = 0;
+
+  //
+  // Get EP num
+  //
+  EndPointNumber = (EventReg & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS;
+
+  EventStatus = EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK;
+
+  //
+  // Interpret event and handle transfer completion here
+  //
+  EpEvent = (EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_EP EventReg 0x%08x\n", EventReg));
+
+  switch (EpEvent) {
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT\n"));
+      if (EndPointNumber > 1) {
+        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP None_Control transfer\n"));
+        NoneEp0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
+      } else {
+        //
+        // Control transfer
+        //
+        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer\n"));
+        Ep0XferDone (This, EndPointNumber, Message, PayloadSize, Payload);
+      }
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY\n"));
+      *Message = EfiUsbMsgNone;
+      if(EndPointNumber < (sizeof(UsbFuncIoDevPtr->EndPointXferRec) / sizeof(UsbFuncIoDevPtr->EndPointXferRec[0]))) {
+        if ((UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag == TRUE) && \
+              (UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].Complete == TRUE)) {
+          DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Request send ZLP\n"));
+          if ((EndPointNumber & 0x01) != 0) {
+            Transfer(This,
+                     UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress,
+                     EfiUsbEndpointDirectionDeviceTx,
+                     &TmpBufferSize,
+                     NULL
+                    );
+            UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag = FALSE;
+          }
+
+        }
+      } else {
+        //
+        // Is it data stage or status stage
+        //
+        // Data Statge
+        //
+        Ep_State = USB_EP_STATE_DATA;
+        //
+        // Control transfer
+        //
+        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer not ready\n"));
+        Ep0XferNotReady (This, EndPointNumber, Message, PayloadSize, Payload, EventStatus);
+        *EventFlag = FALSE;
+      }
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS\n"));
+      break;
+
+    default:
+      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUDwcXdciProcessEpEvent: UNKNOWN EP event\n"));
+      break;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::EndPoint Event....exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ProcessIntLineEvents(
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT32                       EventCount,
+  IN UINT32                       *ProceSsEvent,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
+  OUT BOOLEAN                     *EventFlag
+  )
+{
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          CurrentEventAddr;
+  UINT32                          ProceSsEventSize;
+  BOOLEAN                         EventReport;
+  BOOLEAN                         EpEventReport;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->CurrentEventBuffer);
+  EventReport = FALSE;
+  EpEventReport = FALSE;
+  ProceSsEventSize = 0;
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Entry\n"));
+
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: XdciCorePtr->CurrentEventBuffer 0x%08x\n", XdciCorePtr->CurrentEventBuffer));
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EventCount0x%08x\n", EventCount));
+   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::CurrentEventAddr 0x%08x\n", CurrentEventAddr));
+
+  while ((EventCount != 0) && (EventReport == FALSE)) {
+     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::event0x%08x\n", XdciCorePtr->CurrentEventBuffer->Event));
+     if ((XdciCorePtr->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) != 0) {
+       //
+       // Device event
+       //
+       DeviceEventCheck (
+         This,
+         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
+         &ProceSsEventSize,
+         Message,
+         &EventReport
+         );
+       if (EventReport == TRUE) {
+         *EventFlag = TRUE;
+       }
+
+     } else {
+       //
+       // EndPoint Event
+       //
+       EpEventCheck (
+         This,
+         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
+         &ProceSsEventSize,
+         Message,
+         PayloadSize,
+         Payload,
+         &EpEventReport
+         );
+     }
+
+     if ((*Message != EfiUsbMsgNone) || (EpEventReport == TRUE)) {
+       EventReport = TRUE;
+       *EventFlag = TRUE;
+     }
+
+     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr 0x%08x :: ProceSsEventSize 0x%08x\n", (UINTN)CurrentEventAddr,ProceSsEventSize));
+
+     EventCount -= ProceSsEventSize;
+     *ProceSsEvent += ProceSsEventSize;
+     if ((CurrentEventAddr + ProceSsEventSize) >= \
+         ((UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers) +
+          (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))) {
+       CurrentEventAddr = (UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers);
+    } else {
+      CurrentEventAddr += ProceSsEventSize;
+    }
+    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr Update 0x%08x :: ProceSsEventSize 0x%08x\n", CurrentEventAddr,ProceSsEventSize));
+
+    XdciCorePtr->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER*)(UINTN)CurrentEventAddr;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents Exit\n\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  ISR inokes Event Handler.  Look at which interrupt has happened and see
+  if there are event handler registerd and if so fire them 1 by one.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Message           Indicates the event that initiated this
+                                notification.
+  @param[in]  PayloadSize       On input, the size of the memory pointed by Payload.
+                                On output, the amount of data returned in Payload.
+  @param[in]  Payload           A pointer to EFI_USBFN_MESSAGE_PAYLOAD instance to
+                                return additional payload for current message.
+
+
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer not large enough to hold
+                                the message payload.
+
+**/
+EFI_STATUS
+EFIAPI
+EventHandler(
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  )
+{
+  UINT32                          EventCount;
+  UINT32                          PeventCount;
+  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
+  UINT32                          MaxIntNum;
+  UINT32                          IntIndex;
+  USB_DEV_CORE                    *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                *XdciCorePtr;
+  BOOLEAN                         EventFlag;
+  EFI_TPL                         OriginalTpl;
+
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Entry\n"));
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
+    UsbFnInitDevice (This);
+  }
+  OriginalTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+  *Message = EfiUsbMsgNone;
+  MaxIntNum = (UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_GHWPARAMS1_REG) &
+                 DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
+                 DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS;
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EventFlag = TRUE;
+
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "XdciCorePtr->MaxDevIntLines 0x%08x\n", XdciCorePtr->MaxDevIntLines));
+  EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
+
+  for (IntIndex = 0; IntIndex < XdciCorePtr->MaxDevIntLines ; IntIndex++) {
+    //
+    // Get the number of events HW has written for this
+    //  interrupt line
+    //
+    EventCount = UsbRegRead ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex));
+    EventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+    PeventCount = 0;
+
+    //
+    // Process interrupt line Buffer only if count is non-zero
+    //
+    if (EventCount) {
+      //
+      // Process events in this Buffer
+      //
+      ProcessIntLineEvents (
+        This,
+        EventCount,
+        &PeventCount,
+        Message,
+        PayloadSize,
+        Payload,
+        &EventFlag
+        );
+
+      //
+      // Write back the Processed number of events so HW decrements it from current
+      // event count
+      //
+      UsbRegWrite ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex), PeventCount);
+
+      //
+      // for debug
+      //
+      if (*Message != EfiUsbMsgNone) {
+        break;
+      }
+
+      if (EventFlag == TRUE) {
+        break;
+      }
+    }
+  }
+
+  gBS->RestoreTPL (OriginalTpl);
+  //
+  //EVENT_EXIT:
+  //
+  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+
+/**
+  Copies relevant endpoint data from standard USB endpoint descriptors
+  to the usbEpInfo structure used by the XDCI
+
+  @param pEpDest   destination structure
+  @param pEpSrc    source structure
+
+  @return VOID
+
+**/
+VOID
+UsbFnSetEpInfo (
+  IN USB_EP_INFO                 *EpDest,
+  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
+  )
+{
+  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc = NULL;
+  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc = NULL;
+
+  //
+  // start by clearing all data in the destination
+  //
+  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
+  EpDesc = EpSrc->EndpointDesc;
+  EpCompDesc = EpSrc->EndpointCompDesc;
+
+  if (EpDesc != NULL) {
+    EpDest->EpNum = EpDesc->EndpointAddress & 0x0F; // Bits 0-3 are ep num
+    EpDest->EpDir = ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN) > 0) ? UsbEpDirIn : UsbEpDirOut;
+    DEBUG ((DEBUG_INFO, "EpDest->EpNum 0x%02x\n", EpDest->EpNum));
+    DEBUG ((DEBUG_INFO, "EpDest->EpDir 0x%02x\n", EpDest->EpDir));
+    EpDest->EpType = EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
+    EpDest->MaxPktSize = EpDesc->MaxPacketSize;
+    EpDest->Interval = EpDesc->Interval;
+  }
+  if (EpCompDesc != NULL) {
+    EpDest->MaxStreams = EpCompDesc->Attributes & USB_EP_BULK_BM_ATTR_MASK;
+    EpDest->BurstSize = EpCompDesc->MaxBurst;
+    EpDest->Mult = EpCompDesc->BytesPerInterval;
+  }
+
+  return;
+}
+
+
+EFI_STATUS
+SetFnIoReqInfo(
+  IN     EFI_USBFN_IO_PROTOCOL         *This,
+  IN     UINT8                         EndpointIndex,
+  IN     EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                         *BufferSize,
+  IN OUT VOID                          *Buffer,
+  IN OUT USB_XFER_REQUEST              *XfIoreq
+  )
+{
+  USB_XDCI_DEV_CONTEXT     *UsbFuncIoDevPtr;
+  EFI_STATUS               Status;
+  UINTN                    ReqPacket;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  Status = EFI_SUCCESS;
+  ReqPacket = 0;
+
+  switch (EndpointIndex) {
+    case 0: // Control endpoint
+      XfIoreq->EpInfo.EpNum = 0;
+      XfIoreq->EpInfo.EpDir = Direction? UsbEpDirIn : UsbEpDirOut;
+      break;
+
+
+    default:
+      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrInEp);
+      } else {
+        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr->IndexPtrOutEp);
+        //
+        // reference from "UsbDeviceMode.c", function UsbdEpRxData
+        //
+
+        //
+        // Transfer length should be multiple of USB packet size.
+        //
+        ReqPacket = *BufferSize/ XfIoreq->EpInfo.MaxPktSize;
+        ReqPacket = ((XfIoreq->XferLen % XfIoreq->EpInfo.MaxPktSize) == 0)? ReqPacket : ReqPacket + 1;
+        XfIoreq->XferLen = (UINT32)ReqPacket * XfIoreq->EpInfo.MaxPktSize;
+
+      }
+      break;
+  }
+
+  if (EFI_ERROR(Status)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  XfIoreq->XferBuffer = Buffer;
+  XfIoreq->XferLen = (UINT32)(*BufferSize);
+  XfIoreq->XferDone = NULL;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Primary function to handle transfer in either direction Based on specified
+  direction and on the specified endpoint.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the endpoint on which TX or RX transfer
+                                needs to take place.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  BufferSize        If Direction is EfiUsbEndpointDirectionDeviceRx:
+                                On input, the size of the Buffer in bytes.
+                                On output, the amount of data returned in Buffer in bytes.
+                                If Direction is EfiUsbEndpointDirectionDeviceTx:
+                                On input, the size of the Buffer in bytes.
+                                On output, the amount of data actually transmitted in bytes.
+  @param[in]  Buffer            If Direction is EfiUsbEndpointDirectionDeviceRx:
+                                The Buffer to return the received data.
+                                If Direction is EfiUsbEndpointDirectionDeviceTx:
+                                The Buffer that contains the data to be transmitted.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_NOT_READY         The physical device is busy or not ready to
+                                process this request.
+
+**/
+EFI_STATUS
+EFIAPI
+Transfer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
+  USB_DEV_CORE                      *UsbDeviceCorePtr;
+  XDCI_CORE_HANDLE                  *XdciCorePtr;
+  EFI_STATUS                        Status;
+  USB_XFER_REQUEST                  XferReq;
+  UINT32                            EndPoint;
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Transfer - Entry\n"));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:EndpointIndex 0x%02x\n", EndpointIndex));
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Direction 0x%02x\n", Direction));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  UsbDeviceCorePtr = UsbFuncIoDevPtr->DrvCore;
+  XdciCorePtr = UsbDeviceCorePtr->ControllerHandle;
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  Status = SetFnIoReqInfo (
+             This,
+             EndpointIndex,
+             Direction,
+             BufferSize,
+             Buffer,
+             &XferReq
+             );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "Set SetFnIoReqInfo - Error Stop!!!\n"));
+    while(1);
+    Status = EFI_DEVICE_ERROR;
+    goto FUN_EXIT;
+  }
+
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].EpNum = EndPoint;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Direction = Direction;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferAddress = (UINTN)Buffer;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferLength = (UINT32)(*BufferSize);
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].LogEpNum = EndpointIndex;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Complete = FALSE;
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = FALSE;
+
+  Status = EFI_DEVICE_ERROR;
+  switch (EndpointIndex) {
+    case 0: // Control endpoint
+      if (*BufferSize == 0) {
+        if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+          Status = UsbDeviceEp0TxStatus(UsbDeviceCorePtr);
+        } else {
+          Status = UsbDeviceEp0RxStatus(UsbDeviceCorePtr);
+        }
+      } else if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+        Status = UsbXdciDeviceEpTxData(UsbDeviceCorePtr, &XferReq);
+      } else if (Direction == EfiUsbEndpointDirectionDeviceRx) {
+        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Setup Package - ??? Stop!!!\n"));
+      }
+      break;
+
+    default:
+      Status = EFI_SUCCESS;
+      if (Direction == EfiUsbEndpointDirectionDeviceTx) {
+        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceTx Size = %d\n",(*BufferSize) ));
+        XferReq.Zlp = TRUE;
+        if ((((*BufferSize) % 512) == 0) && ((*BufferSize) != 0)) {
+          UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = TRUE;
+          DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Zlp flag\n"));
+        }
+        Status = UsbXdciDeviceEpTxData (UsbDeviceCorePtr, &XferReq);
+      } else {
+        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n EfiUsbEndpointDirectionDeviceRx Size = %d\n",(*BufferSize) ));
+        Status = UsbXdciDeviceEpRxData (UsbDeviceCorePtr, &XferReq);
+      }
+      break;
+  }
+
+  if (EFI_ERROR(Status)) {
+    goto FUN_EXIT;
+  }
+
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+  }
+
+FUN_EXIT:
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:Transfer - Exit %r\n", Status));
+  return Status;
+}
+
+
+/**
+  This function supplies power to the USB controller if needed, initialize
+  hardware and internal data structures, and then return.
+  The port must not be activated by this function.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+StartXdciController (
+  IN EFI_USBFN_IO_PROTOCOL    *This
+  )
+{
+  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
+  USB_DEV_CONFIG_PARAMS        ConfigParams;
+  EFI_STATUS                   Status;
+
+  Status = EFI_SUCCESS;
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (UsbFuncIoDevPtr->StartUpController == TRUE) {
+    goto EXIT_START_CONTROLLER;
+  }
+
+  ConfigParams.ControllerId = USB_ID_DWC_XDCI;
+  ConfigParams.BaseAddress = (UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr;
+  ConfigParams.Role = USB_ROLE_DEVICE;
+  ConfigParams.Speed = USB_SPEED_HIGH;
+
+  //
+  //*Vid = 0x8086
+  //*Pid = 0x0A65
+  //
+  UsbFuncIoDevPtr->VendorId = USBFU_VID;
+  UsbFuncIoDevPtr->DeviceId = USBFU_PID;
+  UsbFuncIoDevPtr->StartUpController = TRUE;
+
+  Status = UsbDeviceInit (&ConfigParams, (VOID **)&UsbFuncIoDevPtr->DrvCore);
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto EXIT_START_CONTROLLER;
+  }
+
+  UsbFuncIoDevPtr->XdciDrvIfHandle = UsbFuncIoDevPtr->DrvCore->ControllerHandle;
+
+EXIT_START_CONTROLLER:
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "StartXdciController - Exit :: %r\n", Status));
+  return Status;
+}
+
+
+/**
+  This function disables the hardware device by resetting the run/stop bit
+  and power off the USB controller if needed.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+**/
+EFI_STATUS
+EFIAPI
+StopXdciController (
+  IN EFI_USBFN_IO_PROTOCOL    *This
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            DevStatus;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Entry\n"));
+
+  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "The Controller not yet start up skip deinit\n"));
+    return EFI_SUCCESS;
+  }
+
+  if (This == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DevStatus = UsbDeviceDeinit (UsbFuncIoDevPtr->DrvCore, TRUE);
+
+  UsbFuncIoDevPtr->DrvCore = NULL;
+  UsbFuncIoDevPtr->XdciDrvIfHandle = NULL;
+  UsbFuncIoDevPtr->StartUpController = FALSE;
+
+  if (DevStatus != EFI_SUCCESS) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  This function sets the configuration policy for the specified non-control endpoint.
+  Refer to the description for calling restrictions
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the non-control endpoint for
+                                which the policy needs to be set.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  PolicyType        Policy type the user is trying to set for
+                                the specified non-control endpoint.
+  @param[in]  BufferSize        The size of the Buffer in bytes.
+  @param[in]  Buffer            The new value for the policy parameter that
+                                PolicyType specifies.
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN UINTN                        BufferSize,
+  IN VOID                         *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            Status;
+  UINT32                EndPoint;
+  UINT8                 *FlagPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  FlagPtr = NULL;
+
+  switch (PolicyType) {
+    case EfiUsbPolicyUndefined:
+    case EfiUsbPolicyMaxTransactionSize:
+    case EfiUsbPolicyZeroLengthTerminationSupport:
+
+     Status = EFI_UNSUPPORTED;
+     break;
+
+    default:
+     FlagPtr = Buffer;
+     Status = EFI_SUCCESS;
+     break;
+  }
+
+  if (BufferSize < 1) {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointPolicy - ERROR %r\n", Status));
+    return Status;
+  }
+
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag = *FlagPtr;
+
+  return Status;
+}
+
+
+/**
+  This function retrieves the configuration policy for the specified non-control
+  endpoint. There are no associated calling restrictions for this function.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  EndpointIndex     Indicates the non-control endpoint for
+                                which the policy needs to be set.
+  @param[in]  Direction         Direction of the endpoint.
+  @param[in]  PolicyType        Policy type the user is trying to set for
+                                the specified non-control endpoint.
+  @param[in]  BufferSize        The size of the Buffer in bytes.
+  @param[in]  Buffer            The new value for the policy parameter that
+                                PolicyType specifies.
+
+
+  @retval EFI_SUCCESS           The function returned successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_DEVICE_ERROR      The physical device reported an error.
+  @retval EFI_UNSUPPORTED       Changing this policy value is not supported.
+  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer is not large enough to
+                                hold requested policy value.
+
+**/
+EFI_STATUS
+EFIAPI
+GetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN OUT UINTN                    *BufferSize,
+  IN OUT VOID                     *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
+  EFI_STATUS            Status;
+  UINT32                EndPoint;
+  UINT32                MaxPacketSize;
+  BOOLEAN               SetFlag;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+  MaxPacketSize = 0;
+  SetFlag = FALSE;
+
+  switch (PolicyType) {
+    case EfiUsbPolicyUndefined:
+
+     Status = EFI_UNSUPPORTED;
+     break;
+
+    case EfiUsbPolicyMaxTransactionSize:
+    case EfiUsbPolicyZeroLengthTerminationSupport:
+    default:
+     if (Buffer == NULL) {
+       Status = EFI_INVALID_PARAMETER;
+     } else {
+       Status = EFI_SUCCESS;
+     }
+     break;
+  }
+
+  EndPoint = UsbGetPhysicalEpNum (EndpointIndex, Direction ? UsbEpDirIn : UsbEpDirOut);
+
+  if (EFI_ERROR(Status)) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointPolicy - ERROR %r\n", Status));
+    return Status;
+  }
+
+  if (PolicyType == EfiUsbPolicyMaxTransactionSize) {
+
+    if (*BufferSize < sizeof(UINT32)) {
+       Status = EFI_INVALID_PARAMETER;
+    } else {
+      MaxPacketSize = MAX_TRANSFER_PACKET;
+      CopyMem (Buffer, &MaxPacketSize, sizeof(UINT32));
+    }
+
+  } else if (PolicyType == EfiUsbPolicyZeroLengthTerminationSupport) {
+    if (*BufferSize < sizeof(BOOLEAN)) {
+       Status = EFI_INVALID_PARAMETER;
+    } else {
+      SetFlag = TRUE;
+      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
+    }
+
+  } else if (PolicyType == EfiUsbPolicyZeroLengthTermination) {
+    if (*BufferSize < sizeof(BOOLEAN)) {
+       Status = EFI_INVALID_PARAMETER;
+    } else {
+      SetFlag =  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag;
+      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
+    }
+  } else {
+    Status = EFI_INVALID_PARAMETER;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+UsbFnInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  EFI_STATUS                   Status;
+  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
+
+  Status = EFI_SUCCESS;
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  PlatformSpecificInit ();
+
+  UsbFuncIoDevPtr->StartUpController = FALSE;
+  Status = StartXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
+  if (EFI_ERROR (Status)) {
+    Status = EFI_DEVICE_ERROR;
+    goto DEV_INIT_EXIT;
+  }
+
+  Status = UsbXdciDeviceConnect (UsbFuncIoDevPtr->DrvCore);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbXdciDeviceConnect Status %x\n", Status));
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto DEV_INIT_EXIT;
+  }
+
+
+DEV_INIT_EXIT:
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+StartController (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+UsbFnDeInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  EFI_STATUS                   Status;
+  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  if (UsbFuncIoDevPtr->StartUpController == FALSE) {
+    DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFn:StopController:The Controller not yet start up force return EFI_SUCCESS\n"));
+    return EFI_SUCCESS;
+  }
+
+  //
+  // disconnect
+  //
+  Status = UsbDeviceDisconnect (UsbFuncIoDevPtr->DrvCore);
+  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbDeviceDisconnect Status %x\n", Status));
+  if (Status != EFI_SUCCESS) {
+    Status = EFI_DEVICE_ERROR;
+    goto DEV_DEINIT_EXIT;
+  }
+
+  //
+  // StopController
+  //
+  Status = StopXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
+  UsbFuncIoDevPtr->StartUpController = FALSE;
+
+DEV_DEINIT_EXIT:
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+StopController (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  return UsbFnDeInitDevice(This);
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
new file mode 100644
index 0000000000..ad3d296db9
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
@@ -0,0 +1,234 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 __EFI_USB_FUNCTION_IO_INTERFACE_H__
+#define __EFI_USB_FUNCTION_IO_INTERFACE_H__
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DriverLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/EfiUsbFnIo.h>
+#include <Library/PmicLib.h>
+#include <Library/UsbDeviceLib.h>
+#include <Library/PrintLib.h>
+#include "UsbIoNode.h"
+#include "XdciDWC.h"
+#include "UsbDeviceMode.h"
+
+//
+// Debug message setting
+//
+#define USB_FUIO_DEBUG_INFO              EFI_D_INFO
+#define USB_FUIO_DEBUG_LOAD              EFI_D_LOAD
+#define USB_FUIO_DEBUG_ERROR             EFI_D_ERROR
+#define USB_FUIO_DEBUG_EVENT_I           0 //DEBUG_INIT
+#define USB_FUIO_DEBUG_EVENT_D           EFI_D_ERROR
+#define USB_FUIO_DEBUG_EVENT_NOTREADY_D  EFI_D_ERROR
+#define USB_FUIO_DEBUG_EVENT_NOTREADY_I  0 //DEBUG_INIT
+
+#define MAX_TRANSFER_PACKET     (8 * 1024 * 1024)
+
+#define USBFU_VID     0x8086
+#define USBFU_PID     0x0A65
+
+#pragma pack(1)
+typedef struct {
+  UINT8                     ProgInterface;
+  UINT8                     SubClassCode;
+  UINT8                     BaseCode;
+} USB_CLASSC;
+
+//
+// Event Buffer Struct
+//
+typedef struct  {
+  UINT32 Event;
+  UINT32 DevTstLmp1;
+  UINT32 DevTstLmp2;
+  UINT32 Reserved;
+} USBD_EVENT_BUF;
+
+typedef struct  {
+  UINT32                        EpNum;
+  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
+  UINTN                         XferAddress;
+  UINT32                        XferLength;
+  UINT8                         LogEpNum;
+  BOOLEAN                       Complete;
+  BOOLEAN                       ZlpFlag;
+} USBD_EP_XFER_REC;
+
+#pragma pack()
+
+EFI_STATUS
+UsbFnInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  );
+
+EFI_STATUS
+UsbFnDeInitDevice (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  );
+
+EFI_STATUS
+EFIAPI
+DetectPort (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT EFI_USBFN_PORT_TYPE          *PortType
+  );
+
+EFI_STATUS
+EFIAPI
+AllocateTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINTN                         Size,
+  OUT VOID                         **Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+FreeTransferBuffer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN VOID                          *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+ConfigureEnableEndpoints (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_DEVICE_INFO           *DeviceInfo
+ );
+
+EFI_STATUS
+EFIAPI
+GetEndpointMaxPacketSize (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_ENDPOINT_TYPE         EndpointType,
+  IN EFI_USB_BUS_SPEED             BusSpeed,
+  OUT UINT16                       *MaxPacketSize
+ );
+
+EFI_STATUS
+EFIAPI
+GetMaxTransferSize (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT UINTN                        *MaxTransferSize
+  );
+
+EFI_STATUS
+EFIAPI
+GetDeviceInfo (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USBFN_DEVICE_INFO_ID      Id,
+  IN OUT UINTN                     *BufferSize,
+  OUT VOID                         *Buffer OPTIONAL
+  );
+
+EFI_STATUS
+EFIAPI
+GetVendorIdProductId (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT UINT16                       *Vid,
+  OUT UINT16                       *Pid
+  );
+
+EFI_STATUS
+EFIAPI
+AbortTransfer (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
+  );
+
+EFI_STATUS
+EFIAPI
+GetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT BOOLEAN                   *State
+  );
+
+EFI_STATUS
+EFIAPI
+SetEndpointStallState (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN BOOLEAN                       State
+  );
+
+EFI_STATUS
+EFIAPI
+EventHandler (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  OUT EFI_USBFN_MESSAGE            *Message,
+  IN OUT UINTN                     *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD    *Payload
+  );
+
+EFI_STATUS
+EFIAPI
+Transfer (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+StartController (
+  IN EFI_USBFN_IO_PROTOCOL         *This
+  );
+
+EFI_STATUS
+EFIAPI
+StopController (
+  IN EFI_USBFN_IO_PROTOCOL         *This
+  );
+
+EFI_STATUS
+EFIAPI
+SetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN EFI_USBFN_POLICY_TYPE         PolicyType,
+  IN UINTN                         BufferSize,
+  IN VOID                          *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+GetEndpointPolicy (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN EFI_USBFN_POLICY_TYPE         PolicyType,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  );
+
+VOID
+UsbFnSetEpInfo (
+  IN USB_EP_INFO                 *EpDest,
+  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
+  );
+
+extern EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol;
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
new file mode 100644
index 0000000000..8fc6e10046
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
@@ -0,0 +1,177 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 "UsbDeviceDxe.h"
+
+
+/**
+  The SearchNode function search a memory address for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+  @param[out] Node              The match node record of the driver aloocate
+                                memory region.
+  @param[out] PNode             The pervious match node record of the driver
+                                aloocate memory region.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+SearchNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer,
+  OUT USB_MEM_NODE             **Node,
+  OUT USB_MEM_NODE             **PNode
+  )
+{
+  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
+  USB_MEM_NODE         *NodeL;
+  USB_MEM_NODE         *PNodeL;
+  EFI_STATUS           Status;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+  NodeL = UsbFuncIoDevPtr->FirstNodePtr;
+  PNodeL = NULL;
+  Status = EFI_NOT_FOUND;
+
+  while (Node != NULL) {
+    if (NodeL->AllocatePtr == Buffer) {
+      break;
+    }
+
+    PNodeL = NodeL;
+    NodeL = NodeL->NextPtr;
+  }
+
+  if (NodeL != NULL && Node != NULL) {
+    *Node = NodeL;
+    *PNode = PNodeL;
+    Status = EFI_SUCCESS;
+  }
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Exit %r\n", Status));
+  return Status;
+}
+
+/**
+  The InsertNewNodeToHead function remove a memory for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+RemoveNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer
+  )
+{
+  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
+  USB_MEM_NODE         *Node;
+  USB_MEM_NODE         *PNode;
+  EFI_STATUS           Status;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Entry\n"));
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL (This);
+
+  Status = SearchNode (This, Buffer, &Node, &PNode);
+
+  if (EFI_ERROR(Status) || PNode == NULL) {
+    DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "RemoveNode - Node Not Found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  if (Node != UsbFuncIoDevPtr->FirstNodePtr) {
+    PNode->NextPtr = Node->NextPtr;
+  } else {
+    UsbFuncIoDevPtr->FirstNodePtr = Node->NextPtr;
+  }
+
+  FreePool (Node->AllocatePtr);
+  FreePool (Node);
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Exit\n"));
+  return EFI_SUCCESS;
+}
+
+/**
+  The InsertNewNodeToHead function allocates a memory for record the driver allocate
+  memory region and insert the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] USB_MEM_NODE      return the new node address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
+
+**/
+EFI_STATUS
+InsertNewNodeToHead (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  OUT USB_MEM_NODE             **Node
+  )
+{
+  USB_MEM_NODE         *NewNodePtr;
+  USB_MEM_NODE         *CurrentNodePtr;
+  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
+  EFI_STATUS           Status;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Entry\n"));
+
+  if (This == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto ErrorExit;
+  }
+
+  UsbFuncIoDevPtr = USBFUIO_CONTEXT_FROM_PROTOCOL(This);
+
+  //
+  // Create the new node
+  //
+  NewNodePtr = AllocateZeroPool (sizeof(USB_MEM_NODE));
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "NewNodePtr - Addr = 0x%08x\n",(UINTN)NewNodePtr));
+
+  if (NewNodePtr == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto ErrorExit;
+  }
+
+  //
+  // insert the new node
+  //
+  CurrentNodePtr = UsbFuncIoDevPtr->FirstNodePtr;
+  UsbFuncIoDevPtr->FirstNodePtr = NewNodePtr;
+
+  if (CurrentNodePtr != NULL) {
+    NewNodePtr->NextPtr = CurrentNodePtr;
+  }
+
+  *Node = NewNodePtr;
+
+  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Exit\n"));
+  return EFI_SUCCESS;
+
+ErrorExit:
+
+  DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "CreateNewNode - error %r\n",Status));
+  return Status;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
new file mode 100644
index 0000000000..ecedb2748b
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
@@ -0,0 +1,90 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 __EFI_USB_FUIO_MEM_NODE__
+#define __EFI_USB_FUIO_MEM_NODE__
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DriverLib.h>
+
+#define  USB_DEBUG_MEM_NODE_INFO  EFI_D_INIT
+#define  USB_DEBUG_MEM_NODE_ERROR EFI_D_ERROR
+
+
+typedef struct {
+  UINTN                         Size;
+  VOID                          *AllocatePtr;
+  VOID                          *NextPtr;
+} USB_MEM_NODE;
+
+/**
+  The SearchNode function search a memory address for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+  @param[out] Node              The match node record of the driver aloocate
+                                memory region.
+  @param[out] PNode             The pervious match node record of the driver
+                                aloocate memory region.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+SearchNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer,
+  OUT USB_MEM_NODE             **Node,
+  OUT USB_MEM_NODE             **PNode
+  );
+
+/**
+  The InsertNewNodeToHead function remove a memory for record the driver allocate
+  memory region and the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[in]  Buffer            The driver alocate memory address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
+**/
+EFI_STATUS
+RemoveNode (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  IN  VOID                     *Buffer
+  );
+
+/**
+  The InsertNewNodeToHead function allocates a memory for record the driver allocate
+  memory region and insert the node to the head link list.
+
+  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL instance.
+  @param[out] USB_MEM_NODE      return the new node address.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could not be allocated.
+
+**/
+EFI_STATUS
+InsertNewNodeToHead (
+  IN  EFI_USBFN_IO_PROTOCOL    *This,
+  OUT USB_MEM_NODE             **Node
+  );
+
+  #endif
+
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
new file mode 100644
index 0000000000..6a53068681
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
@@ -0,0 +1,156 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 _XDCI_COMMON_H_
+#define _XDCI_COMMON_H_
+
+#define USB_SETUP_DATA_PHASE_DIRECTION_MASK  (0x80)
+
+//
+// EP direction
+//
+typedef enum {
+  UsbEpDirOut = 0,
+  UsbEpDirIn  = 1
+} USB_EP_DIR;
+
+//
+// USB Speeds
+//
+typedef enum {
+  USB_SPEED_HIGH  = 0,
+  USB_SPEED_FULL,
+  USB_SPEED_LOW,
+  USB_SPEED_SUPER = 4
+} USB_SPEED;
+
+typedef enum {
+  USB_ID_DWC_XDCI = 0,
+  USB_CORE_ID_MAX
+} USB_CONTROLLER_ID;
+
+typedef enum {
+  USB_ROLE_HOST = 1,
+  USB_ROLE_DEVICE,
+  USB_ROLE_OTG
+} USB_ROLE;
+
+typedef enum {
+  USB_XFER_QUEUED    = 0,
+  USB_XFER_SUCCESSFUL,
+  USB_XFER_STALL
+} USB_XFER_STATUS;
+
+typedef enum {
+  USB_DEVICE_DISCONNECT_EVENT       = 0,
+  USB_DEVICE_RESET_EVENT,
+  USB_DEVICE_CONNECTION_DONE,
+  USB_DEVICE_STATE_CHANGE_EVENT,
+  USB_DEVICE_WAKEUP_EVENT,
+  USB_DEVICE_HIBERNATION_REQ_EVENT,
+  USB_DEVICE_SOF_EVENT              = 7,
+  USB_DEVICE_ERRATIC_ERR_EVENT      = 9,
+  USB_DEVICE_CMD_CMPLT_EVENT,
+  USB_DEVICE_BUFF_OVERFLOW_EVENT,
+  USB_DEVICE_TEST_LMP_RX_EVENT,
+  USB_DEVICE_SETUP_PKT_RECEIVED,
+  USB_DEVICE_XFER_NRDY,
+  USB_DEVICE_XFER_DONE
+} USB_DEVICE_EVENT_ID;
+
+typedef enum {
+  U0 = 0,
+  U1,
+  U2,
+  U3,
+  SS_DIS,
+  RX_DET,
+  SS_INACT,
+  POLL,
+  RECOV,
+  HRESET,
+  CMPLY,
+  LPBK,
+  RESUME_RESET = 15
+} USB_DEVICE_SS_LINK_STATE;
+
+typedef enum {
+  CTRL_SETUP_PHASE,
+  CTRL_DATA_PHASE,
+  CTRL_STATUS_PHASE
+} USB_CONTROL_XFER_PHASE;
+
+typedef enum  {
+  USB_EP_STATE_DISABLED = 0,
+  USB_EP_STATE_ENABLED,
+  USB_EP_STATE_STALLED,
+  USB_EP_STATE_SETUP,
+  USB_EP_STATE_IN_DATA,
+  USB_EP_STATE_OUT_DATA,
+  USB_EP_STATE_DATA,
+  USB_EP_STATE_STATUS
+} USB_EP_STATE;
+
+typedef struct  {
+  VOID                      *ParentHandle;
+  UINT32                    Hird;
+  UINT32                    EpNum;
+  USB_SPEED                 Speed;
+  USB_EP_STATE              EpState;
+  USB_EP_DIR                EpDir;
+  UINT8                     EpType;
+  USB_DEVICE_SS_LINK_STATE  LinkState;
+  UINT8                     *Buffer;
+  BOOLEAN                   SsEvent;
+} USB_DEVICE_CALLBACK_PARAM;
+
+//
+// USB endpoint
+//
+typedef struct {
+  UINT32       EpNum;
+  USB_EP_DIR   EpDir;
+  UINT8        EpType;
+  UINT32       MaxPktSize;
+  UINT32       MaxStreams;
+  UINT32       BurstSize;
+  UINT32       Interval;
+  UINT32       Mult;
+} USB_EP_INFO;
+
+//
+// USB transfer request
+//
+typedef struct _USB_XFER_REQUEST USB_XFER_REQUEST;
+
+typedef
+VOID
+(EFIAPI *USB_XFER_DONE_CALLBACK) (
+  IN VOID                    *XdciHndl,
+  IN USB_XFER_REQUEST        *XferReq
+  );
+
+struct _USB_XFER_REQUEST {
+  VOID                      *XferBuffer;     // Buffer address. bus-width aligned
+  UINT32                    XferLen;         // Requested transfer length
+  UINT32                    ActualXferLen;  // Actual transfer length at completion callback stage
+  UINT32                    StreamId;        // Stream ID. Only relevant for bulk streaming
+  UINT32                    FrameNum;        // Only relevant for periodic transfer
+  USB_XFER_STATUS           XferStatus;      // Transfer status
+  USB_EP_INFO               EpInfo;          // EP info
+  USB_XFER_DONE_CALLBACK    XferDone;        // Transfer completion callback
+  BOOLEAN                   Zlp;              // Do zero-length transfer
+};
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
new file mode 100644
index 0000000000..3569ba6975
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
@@ -0,0 +1,4030 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 "UsbDeviceMode.h"
+#include "XdciInterface.h"
+#include "XdciDWC.h"
+
+
+UINT32
+UsbRegRead (
+  IN UINT32    Base,
+  IN UINT32    Offset
+  )
+{
+  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
+  return *addr;
+}
+
+VOID
+UsbRegWrite (
+  IN UINT32    Base,
+  IN UINT32    Offset,
+  IN UINT32    val
+  )
+{
+  volatile UINT32 *addr = (volatile UINT32 *)((UINTN)(Base) + (UINTN)(Offset));
+  *addr = val;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to obtain physical endpoint number
+  xDCI needs physical endpoint number for EP registers
+  We also use it to index into our EP array
+  Note: Certain data structures/commands use logical EP numbers
+  as opposed to physical endpoint numbers so one should be
+  careful when interpreting EP numbers
+  @EpNum: Logical endpoint number
+  @epDir: Direction for the endpoint
+
+**/
+STATIC
+UINT32
+DwcXdciGetPhysicalEpNum (
+  IN UINT32        EndpointNum,
+  IN USB_EP_DIR    EndpointDir
+  )
+{
+  return EndpointDir? ((EndpointNum << 1) | EndpointDir) : (EndpointNum << 1);
+}
+
+
+/**
+  Internal utility function:
+  This function is used to obtain the MPS for control transfers
+  Based on the Speed. If this is called before bus reset completes
+  then it returns MPS Based on desired Speed. If it is after bus
+  reset then MPS returned is Based on actual negotiated Speed
+  @CoreHandle: xDCI controller handle address
+  @mps: address of 32-bit variable to return the MPS
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreGetCtrlMps (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              *mps
+  )
+{
+  if (CoreHandle == NULL) {
+      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID handle\n"));
+      return EFI_DEVICE_ERROR;
+  }
+
+  if (mps == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (CoreHandle->ActualSpeed) {
+    case USB_SPEED_HIGH:
+      *mps = DWC_XDCI_HS_CTRL_EP_MPS;
+      break;
+    case USB_SPEED_FULL:
+      *mps = DWC_XDCI_FS_CTRL_EP_MPS;
+      break;
+    case USB_SPEED_LOW:
+      *mps = DWC_XDCI_LS_CTRL_EP_MPS;
+      break;
+    case USB_SPEED_SUPER:
+      *mps = DWC_XDCI_SS_CTRL_EP_MPS;
+      break;
+    default:
+      *mps = 0;
+      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: UNKNOWN Speed\n"));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to initialize the parameters required
+  for executing endpoint command
+  @CoreHandle: xDCI controller handle address
+  @EpInfo: EP info address
+  @ConfigAction: Configuration action specific to EP command
+  @EpCmd: xDCI EP command for which parameters are initialized
+  @EpCmdParams: address of struct to return EP params
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreInitEpCmdParams (
+  IN XDCI_CORE_HANDLE                *CoreHandle,
+  IN USB_EP_INFO                     *EpInfo,
+  IN UINT32                          ConfigAction,
+  IN DWC_XDCI_ENDPOINT_CMD           EpCmd,
+  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
+  )
+{
+  EFI_STATUS  status = EFI_SUCCESS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitEpCmdParams: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Reset params
+  //
+  EpCmdParams->Param0 = EpCmdParams->Param1 = EpCmdParams->Param2 = 0;
+
+  switch (EpCmd) {
+    case EPCMD_SET_EP_CONFIG:
+      //
+      // Issue DEPCFG command for EP
+      // Issue a DEPCFG (Command 1) command for endpoint
+      //
+      if (EpInfo->MaxStreams) {
+        EpCmdParams->Param1 = DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK;
+      }
+
+      if (EpInfo->Interval) {
+        EpCmdParams->Param1 |= ((EpInfo->Interval-1) << DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS);
+      }
+
+      //
+      // Set EP num
+      //
+      EpCmdParams->Param1 |= (EpInfo->EpNum << DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS);
+      //
+      // Set EP direction
+      //
+      EpCmdParams->Param1 |= (EpInfo->EpDir << DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS);
+      //
+      // Set EP-specific Event enable for not ready and
+      // complete events
+      //
+      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK;
+      //
+      // Setup the events we want enabled for this EP
+      //
+      EpCmdParams->Param1 |= (DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK |
+                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK |
+                                DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK);
+
+      //
+      // We only have one interrupt line for this core.
+      // Set interrupt number to 0
+      //
+      EpCmdParams->Param1 &= ~DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK;
+
+      //
+      // Set FIFOnum = 0 for control EP0
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK;
+
+      //
+      // Program FIFOnum for non-EP0 EPs
+      //
+      if (EpInfo->EpNum && EpInfo->EpDir) {
+        EpCmdParams->Param0 |= (EpInfo->EpNum << DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS);
+      }
+
+      //
+      // Program max packet size
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK;
+      EpCmdParams->Param0 |= (EpInfo->MaxPktSize << DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS);
+
+      //
+      // Set Burst size. 0 means burst size of 1
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK;
+      EpCmdParams->Param0 |= (EpInfo->BurstSize << DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS);
+
+      //
+      // Set EP type
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK;
+      EpCmdParams->Param0 |= (EpInfo->EpType << DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS);
+
+      //
+      // Set config action
+      //
+      EpCmdParams->Param0 &= ~DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK;
+      EpCmdParams->Param0 |= (ConfigAction << DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS);
+      break;
+
+    case EPCMD_SET_EP_XFER_RES_CONFIG:
+      // Set Param0 to 1. Same for all EPs when resource
+      // configuration is done
+      //
+      EpCmdParams->Param0 = 1;
+      break;
+
+    case EPCMD_END_XFER:
+      //
+      // Nothing to set. Already reset params for all cmds
+      //
+      break;
+
+    case EPCMD_START_NEW_CONFIG:
+      //
+      // Nothing to set. Already reset params for all cmds
+      //
+      break;
+
+    default:
+      status = EFI_INVALID_PARAMETER;
+      DEBUG ((DEBUG_INFO, "\nDwcXdciCoreInitEpCmdParams: INVALID Parameter"));
+      break;
+  }
+
+  return status;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to issue the xDCI endpoint command
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical EP num
+  @EpCmd: xDCI EP command
+  @EpCmdParams: EP command parameters address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreIssueEpCmd (
+  IN XDCI_CORE_HANDLE                *CoreHandle,
+  IN UINT32                          EpNum,
+  IN UINT32                          EpCmd,
+  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = 5000;//DWC_XDCI_MAX_DELAY_ITERATIONS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIssueEpCmd: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Set EP command parameter values
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_PARAM2_REG(EpNum),
+    EpCmdParams->Param2
+    );
+
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_PARAM1_REG(EpNum),
+    EpCmdParams->Param1
+    );
+
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_PARAM0_REG(EpNum),
+    EpCmdParams->Param0
+    );
+
+  //
+  // Set the command code and activate it
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EPCMD_REG(EpNum),
+    EpCmd | DWC_XDCI_EPCMD_CMD_ACTIVE_MASK
+    );
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreIssueEpCmd. ERROR: Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to flush all FIFOs
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreFlushAllFifos (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushAllFifos: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Write the command to flush all FIFOs
+  //
+  UsbRegWrite(
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to flush Tx FIFO specific to an endpoint
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical EP num
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreFlushEpTxFifo (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32 fifoNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Translate to FIFOnum
+  // NOTE: Assuming this is a Tx EP
+  //
+  fifoNum = (EpNum >> 1);
+
+  //
+  // TODO: Currently we are only using TxFIFO 0. Later map these
+  // Write the FIFO num/dir param for the generic command.
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_PARAM_REG,
+    ((UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG) & ~DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK) | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK)
+    );
+
+  //
+  // Write the command to flush all FIFOs
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+
+STATIC
+EFI_STATUS
+DwcXdciCorePrepareOneTrb (
+  IN DWC_XDCI_TRB            *Trb,
+  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
+  IN UINT32                  LastBit,
+  IN UINT32                  ChainBit,
+  IN UINT8                   *BufferPtr,
+  IN UINT32                  size
+  )
+{
+  DEBUG ((DEBUG_INFO, "Trb is 0x%x, BufferPtr is 0x%x, size is 0x%x\n", Trb, BufferPtr, size));
+
+  Trb->BuffPtrLow = (UINT32)(UINTN)BufferPtr;
+  Trb->BuffPtrHigh = 0;
+  Trb->LenXferParams = size;
+  Trb->TrbCtrl = TrbCtrl << DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+
+  if (ChainBit)
+    Trb->TrbCtrl |= ChainBit << DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS;
+
+  if (LastBit)
+    Trb->TrbCtrl |= LastBit << DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS;
+
+  Trb->TrbCtrl |= DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK| DWC_XDCI_TRB_CTRL_HWO_MASK;
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciCorePrepareOneTrb) Trb->BuffPtrLow = 0x%x, Trb->LenXferParams is 0x%x, Trb->TrbCtrl is 0x%x\n",
+                                                       Trb->BuffPtrLow, Trb->LenXferParams, Trb->TrbCtrl));
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal utility function:
+  This function is used to initialize transfer request block
+  @CoreHandle: xDCI controller handle address
+  @Trb: Address of TRB to initialize
+  @TrbCtrl: TRB control value
+  @buffPtr: Transfer Buffer address
+  @size: Size of the transfer
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreInitTrb (
+  IN XDCI_CORE_HANDLE        *CoreHandle,
+  IN DWC_XDCI_TRB            *Trb,
+  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
+  IN UINT8                   *BufferPtr,
+  IN UINT32                  size
+  )
+{
+#define ONE_TRB_SIZE      (DWC_XDCI_TRB_BUFF_SIZE_MASK & 0x00F00000)
+  UINT8                   *TrbBuffer;
+  UINT32                  TrbCtrlLast;
+  UINT32                  TrbCtrlChain;
+  UINT32                  TrbIndex;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (Trb == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID handle\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+  
+   //
+   // Init TRB fields
+   // NOTE: Assuming we are only using 32-bit addresses
+   // TODO: update for 64-bit addresses
+   //
+  if (size <= DWC_XDCI_TRB_BUFF_SIZE_MASK) {
+    //
+    // Can transfer in one TRB
+    //
+    TrbCtrlChain = 0;
+    TrbCtrlLast = 1;
+    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, BufferPtr, size);
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Can't transfer in one TRB.
+  // Seperate it in every ONE_TRB_SIZE of TRB
+  //
+  TrbBuffer = BufferPtr;
+  TrbIndex = 0;
+  while (size > ONE_TRB_SIZE) {
+    TrbCtrlChain = 1;
+    TrbCtrlLast = 0;
+    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, ONE_TRB_SIZE);
+    TrbBuffer += ONE_TRB_SIZE;
+    size -= ONE_TRB_SIZE;
+    Trb++;
+    TrbIndex++;
+    if (TrbIndex >= DWC_XDCI_TRB_NUM)
+      return EFI_OUT_OF_RESOURCES;
+  }
+  TrbCtrlChain = 0;
+  TrbCtrlLast = 1;
+  DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain, TrbBuffer, size);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to start a SETUP phase on control endpoint
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciCoreStartEp0SetupXfer (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      status = EFI_DEVICE_ERROR;
+  DWC_XDCI_TRB                    *Trb;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreStartEp0SetupXfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (CoreHandle->EpHandles[0].State == USB_EP_STATE_SETUP) {
+    DEBUG ((DEBUG_INFO, "EP0 was already in SETUP phase\n"));
+    return EFI_SUCCESS;
+  }
+
+  CoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
+  Trb = CoreHandle->Trbs;
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreStartEp0SetupXfer)\n"));
+
+  status = DwcXdciCoreInitTrb (
+             CoreHandle,
+             Trb,
+             TRBCTL_SETUP,
+             CoreHandle->AlignedSetupBuffer,
+             8
+             );
+
+  if (status)
+    return status;
+
+  //
+  // Issue a DEPSTRTXFER for EP0
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command to start transfer on physical
+  // endpoint 0
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             0,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  //
+  // Save new resource index for this transfer
+  //
+  CoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead (
+                                                     CoreHandle->BaseAddress,
+                                                     DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
+                                                     );
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process the state change event
+  @CoreHandle: xDCI controller handle address
+  @event: device event dword
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceStateChangeEvent (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              Event
+  )
+{
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceStateChangeEvent: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  CoreHandle->HirdVal = (Event & DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS;
+
+  CoreHandle->LinkState = ((Event & DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK) >> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS);
+
+  if (CoreHandle->EventCallbacks.DevLinkStateCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.LinkState = CoreHandle->LinkState;
+    CoreHandle->EventCallbacks.CbEventParams.Hird = CoreHandle->HirdVal;
+    CoreHandle->EventCallbacks.CbEventParams.SsEvent = (Event & DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK) ? 1 : 0;
+    CoreHandle->EventCallbacks.DevLinkStateCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to issue a command to end transfer
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical EP num for which transfer is to be ended
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciEndXfer (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  EFI_STATUS                      status;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          cmdParams;
+  DWC_XDCI_TRB                    *TrbPtr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciEndXfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  CoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
+
+  //
+  // Issue a DEPENDXFER for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  cmdParams = ((CoreHandle->EpHandles[EpNum].CurrentXferRscIdx << DWC_XDCI_EPCMD_RES_IDX_BIT_POS) | DWC_XDCI_EPCMD_FORCE_RM_MASK);
+
+  if (CoreHandle->EpHandles[EpNum].CurrentXferRscIdx == 0) {
+    return EFI_SUCCESS;
+  }
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd(
+             CoreHandle,
+             EpNum,
+             cmdParams | DWC_XDCI_EPCMD_END_XFER,
+             &EpCmdParams
+             );
+
+  if (!status) {
+    CoreHandle->EpHandles[EpNum].CurrentXferRscIdx = 0;
+    TrbPtr = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
+    ZeroMem (TrbPtr, DWC_XDCI_TRB_NUM * sizeof (DWC_XDCI_TRB));
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process bus reset detection event
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceResetDet (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  EFI_STATUS  status = EFI_SUCCESS;
+
+  if (CoreHandle == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Flush all FIFOs
+  //
+  status = DwcXdciCoreFlushAllFifos(CoreHandle);
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to flush FIFOs\n"));
+  }
+
+  //
+  // Start SETUP phase on EP0
+  //
+  status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to start SETUP phase for EP0\n"));
+    return status;
+  }
+
+  //
+  // Notify upper layer if a callback is registerd for
+  //  this event
+  //
+  if (CoreHandle->EventCallbacks.DevBusResetCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    status = CoreHandle->EventCallbacks.DevBusResetCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process connection done (means reset
+  complete) event
+  @CoreHandle: xDCI controller handle address
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceResetDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          BaseAddr;
+  EFI_STATUS                      status = EFI_SUCCESS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceResetDone: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+  CoreHandle->ActualSpeed = (UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK);
+  DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDone CoreHandle->ActualSpeed is %x\n", CoreHandle->ActualSpeed));
+
+  //
+  // Program MPS Based on the negotiated Speed
+  //
+  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[0].EpInfo.MaxPktSize);
+  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle->EpHandles[1].EpInfo.MaxPktSize);
+
+  //
+  // Init DEPCFG cmd params for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             CoreHandle,
+             &CoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             0,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    return status;
+  }
+
+  //
+  // Init DEPCFG cmd params for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             CoreHandle,
+             &CoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             1,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  //
+  // Put the other PHY into suspend
+  //
+  if (CoreHandle->ActualSpeed == USB_SPEED_SUPER) {
+    //
+    // Put HS PHY to suspend
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB2PHYCFG_REG (0),
+      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) | DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+      );
+
+    //
+    // Clear SS PHY's suspend mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB3PIPECTL_REG (0),
+      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+      );
+
+  } else {
+    //
+    // Put SS PHY to suspend
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB3PIPECTL_REG(0),
+      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) | DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+      );
+
+    //
+    // Clear HS PHY's suspend mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GUSB2PHYCFG_REG(0),
+      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+      );
+  }
+
+  //
+  // Notify upper layer if callback is registered
+  //
+  if (CoreHandle->EventCallbacks.DevResetDoneCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.Speed = CoreHandle->ActualSpeed;
+    CoreHandle->EventCallbacks.DevResetDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process device event
+  @CoreHandle: xDCI controller handle address
+  @IntLineEventBuffer: event Buffer pointing to device event
+  @ProcessedEventSize: address of variable to save the size of
+  the event that was Processed
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessDeviceEvent (
+  IN XDCI_CORE_HANDLE         *CoreHandle,
+  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
+  IN UINT32                   *ProcessedEventSize
+  )
+{
+  UINT32 event;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceEvent: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Extract device event
+  //
+  event = (IntLineEventBuffer->Event & DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
+  event >>= DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
+
+  //
+  // Assume default event size. Change it in switch case if
+  //  different
+  //
+  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+
+  switch (event) {
+    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
+      DwcXdciProcessDeviceResetDet (CoreHandle);
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
+      DwcXdciProcessDeviceResetDone (CoreHandle);
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
+      DwcXdciProcessDeviceStateChangeEvent (CoreHandle, IntLineEventBuffer->Event);
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
+      DEBUG ((DEBUG_INFO, "Device DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT\n"));
+      *ProcessedEventSize = DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n", event));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process EP not ready for
+  non-control endpoints
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEpXferNotReady (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  //
+  // TODO: Not doing on-demand transfers
+  // Revisit if required for later use
+  //
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process EP not ready for
+  control endpoints
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number
+  @dataStage: EP not ready when data stage token was received
+  @statusStage: EP not ready when status stage token was received
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEp0XferNotReady (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum,
+  IN UINT32              epEventStatus
+  )
+{
+  USB_EP_STATE        epState = USB_EP_STATE_SETUP;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferNotReady: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+  //
+  // Is it data stage or status stage
+  //
+  if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK) {
+    epState = USB_EP_STATE_DATA;
+  } else if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK) {
+    epState = USB_EP_STATE_STATUS;
+  }
+
+  if ((EpNum == 0) && (epState == USB_EP_STATE_STATUS)) {
+    if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK) {
+      DEBUG ((DEBUG_INFO, "XFER_ACTIVE\n"));
+    } else {
+      DEBUG ((DEBUG_INFO, "XFER_NOT_ACTIVE\n"));
+    }
+    DwcXdciEp0ReceiveStatusPkt (CoreHandle);
+  }
+
+  //
+  // Notify upper layer if a callback is registered for
+  // this event
+  //
+  if (CoreHandle->EventCallbacks.DevXferNrdyCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.EpState = epState;
+    CoreHandle->EventCallbacks.DevXferNrdyCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process transfer phone done for EP0
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number (0 for OUT and 1 for IN)
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEp0XferPhaseDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  DWC_XDCI_ENDPOINT    *epHandle;
+  DWC_XDCI_TRB         *Trb;
+  EFI_STATUS           status = EFI_SUCCESS;
+  UINT32               TrbSts;
+  UINT32               TrbCtrl;
+  UINT32               TrbBufsize;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferPhaseDone: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  epHandle = &CoreHandle->EpHandles[EpNum];
+  Trb = CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
+  DEBUG ((DEBUG_INFO, "(DwcXdciProcessEp0XferPhaseDone)EpNum is %d\n", EpNum));
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone. HW owns TRB: %x!!!\n", (UINT32)(UINTN)Trb));
+  }
+
+  epHandle->CurrentXferRscIdx = 0;
+  epHandle->State = USB_EP_STATE_ENABLED;
+  TrbCtrl = (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
+  TrbSts = (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >> DWC_XDCI_TRB_STATUS_BIT_POS;
+  TrbBufsize = Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
+
+  switch (TrbCtrl) {
+    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
+      DEBUG ((DEBUG_INFO, "SETUP\n"));
+      if (CoreHandle->EventCallbacks.DevSetupPktReceivedCallback) {
+        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+        CoreHandle->EventCallbacks.CbEventParams.Buffer = CoreHandle->AlignedSetupBuffer;
+        status = CoreHandle->EventCallbacks.DevSetupPktReceivedCallback (&CoreHandle->EventCallbacks.CbEventParams);
+      }
+
+      if (!(CoreHandle->AlignedSetupBuffer[0] & USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
+        //
+        // Keep a Buffer ready for setup phase
+        //
+        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
+      }
+
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
+      DEBUG ((DEBUG_INFO, "STATUS2\n"));
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
+      DEBUG ((DEBUG_INFO, "STATUS3\n"));
+      //
+      // Notify upper layer of control transfer completion
+      // if a callback function was registerd
+      //
+      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
+        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
+        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
+        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
+        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+      }
+
+      //
+      // Status phase done. Queue next SETUP packet
+      //
+      status = DwcXdciCoreStartEp0SetupXfer(CoreHandle);
+
+      if (status) {
+        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED to queue SETUP\n"));
+      }
+      break;
+
+    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
+      DEBUG ((DEBUG_INFO, "DATA\n"));
+      if (TrbSts == DWC_XDCI_TRB_STATUS_SETUP_PENDING || TrbBufsize != 0) {
+        DEBUG ((DEBUG_INFO, "ERROR: Control transfert aborted by host: Setup pending\n"));
+        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
+      }
+
+      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
+        CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+        CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
+        CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
+        CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(Trb->BuffPtrLow);
+        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+      }
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: UNHANDLED STATE in TRB\n"));
+      break;
+  }
+
+  return status;
+}
+
+
+/**
+  Internal function:
+  This function is used to process transfer done for
+  non-control endpoints
+  @CoreHandle: xDCI controller handle address
+  @EpNum: Physical endpoint number
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEpXferDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  DWC_XDCI_ENDPOINT    *epHandle;
+  DWC_XDCI_TRB         *Trb;
+  USB_XFER_REQUEST     *XferReq;
+  UINT32               remainingLen;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  epHandle = &CoreHandle->EpHandles[EpNum];
+  epHandle->CurrentXferRscIdx = 0;
+  Trb = epHandle->Trb;
+  XferReq = &epHandle->XferHandle;
+
+  //
+  // if transfer done, set CheckFlag to FALSE for allow next transfer request.
+  //
+  epHandle->CheckFlag = FALSE;
+
+  if ((Trb == NULL) || (XferReq == NULL)) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Compute the actual transfer length
+  //
+  XferReq->ActualXferLen = XferReq->XferLen;
+  remainingLen = (Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK);
+
+  if (remainingLen > XferReq->XferLen) {
+    //
+    // Buffer overrun? This should never happen
+    //
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: Possible Buffer overrun\n"));
+  } else {
+    XferReq->ActualXferLen -= remainingLen;
+  }
+
+  //
+  // Notify upper layer of request-specific transfer completion
+  // if there is a callback specifically for this request
+  //
+  if (XferReq->XferDone) {
+    XferReq->XferDone(CoreHandle->ParentHandle, XferReq);
+  }
+
+  //
+  // Notify upper layer if a callback was registered
+  //
+  if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
+    CoreHandle->EventCallbacks.CbEventParams.ParentHandle = CoreHandle->ParentHandle;
+    CoreHandle->EventCallbacks.CbEventParams.EpNum = (EpNum >> 1);
+    CoreHandle->EventCallbacks.CbEventParams.EpDir = (EpNum & 1);
+    CoreHandle->EventCallbacks.CbEventParams.EpType = epHandle->EpInfo.EpType;
+    CoreHandle->EventCallbacks.CbEventParams.Buffer = (UINT8 *)(UINTN)(epHandle->Trb->BuffPtrLow);
+    CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle->EventCallbacks.CbEventParams);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process endpoint events
+  @CoreHandle: xDCI controller handle address
+  @IntLineEventBuffer:  address of Buffer containing event
+  to process
+  @ProcessedEventSize: address to save the size of event
+  Processed
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessEpEvent (
+  IN XDCI_CORE_HANDLE         *CoreHandle,
+  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
+  IN UINT32                   *ProcessedEventSize
+  )
+{
+  UINT32          EpNum;
+  UINT32          epEvent;
+  UINT32          epEventStatus;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpEvent: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  epEvent = IntLineEventBuffer->Event;
+
+  *ProcessedEventSize = DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
+
+  //
+  // Get EP num
+  //
+  EpNum = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS);
+  epEventStatus = (epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK);
+
+  //
+  // Interpret event and handle transfer completion here
+  //
+  epEvent = ((epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS);
+
+  switch (epEvent) {
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
+      DEBUG ((DEBUG_INFO, "XFER_CMPLT ep %d\n", EpNum));
+      if (EpNum > 1) {
+        DwcXdciProcessEpXferDone (CoreHandle, EpNum);
+      } else {
+        DwcXdciProcessEp0XferPhaseDone (CoreHandle, EpNum);
+      }
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
+      DEBUG ((DEBUG_INFO, "IN_PROGRESS\n"));
+      break;
+
+    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
+      DEBUG ((DEBUG_INFO, "NOT_READY ep %d\n", EpNum));
+      if (EpNum > 1) {
+        //
+        // Endpoint transfer is not ready
+        //
+        DwcXdciProcessEpXferNotReady (CoreHandle, EpNum);
+      } else {
+        DwcXdciProcessEp0XferNotReady (CoreHandle, EpNum, epEventStatus);
+      }
+      break;
+
+    default:
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessEpEvent: UNKNOWN EP event\n"));
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Internal function:
+  This function is used to process events on single interrupt line
+  @CoreHandle: xDCI controller handle address
+  @eventCount:  event bytes to process
+  @ProcessedEventCount: address to save the size
+  (in bytes) of event Processed
+  Processed
+
+**/
+STATIC
+EFI_STATUS
+DwcXdciProcessInterruptLineEvents (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              eventCount,
+  IN UINT32              *ProcessedEventCount
+  )
+{
+  UINT32    ProcessedEventSize = 0;
+  UINT32    currentEventAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (CoreHandle->CurrentEventBuffer == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents: INVALID event Buffer\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  currentEventAddr = (UINT32)(UINTN)(CoreHandle->CurrentEventBuffer);
+
+  //
+  // Process eventCount/eventSize number of events
+  // in this run
+  //
+  while (eventCount) {
+    if (CoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
+      DwcXdciProcessDeviceEvent (
+        CoreHandle,
+        CoreHandle->CurrentEventBuffer,
+        &ProcessedEventSize
+        );
+    } else {
+      DwcXdciProcessEpEvent (
+        CoreHandle,
+        CoreHandle->CurrentEventBuffer,
+        &ProcessedEventSize);
+    }
+
+    eventCount -= ProcessedEventSize;
+    *ProcessedEventCount += ProcessedEventSize;
+    if ((currentEventAddr + ProcessedEventSize) >=
+        ((UINT32)(UINTN)(CoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
+       ) {
+      currentEventAddr = (UINT32)(UINTN)(CoreHandle->AlignedEventBuffers);
+      DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
+    } else {
+      currentEventAddr += ProcessedEventSize;
+    }
+
+    CoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
+  }
+
+  return EFI_SUCCESS;
+}
+
+//
+// DWC XDCI APIs
+//
+
+/**
+  Interface:
+
+  This function is used to initialize the xDCI core
+  @configParams: Parameters from app to configure the core
+  @deviceCorePtr:  HW-independent APIs handle for device core
+  @CoreHandle: xDCI controller handle retured
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN VOID                     *deviceCorePtr,
+  IN VOID                     **CoreHandle
+  )
+{
+  EFI_STATUS                      status = EFI_DEVICE_ERROR;
+  UINT32                          BaseAddr;
+  XDCI_CORE_HANDLE                *LocalCoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT8                           i;
+
+  LocalCoreHandle = (XDCI_CORE_HANDLE *)AllocateZeroPool (sizeof(XDCI_CORE_HANDLE));
+
+  if (CoreHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  ZeroMem (LocalCoreHandle, sizeof(XDCI_CORE_HANDLE));
+
+  LocalCoreHandle->ParentHandle = deviceCorePtr;
+
+  *CoreHandle = (VOID *)LocalCoreHandle;
+
+  LocalCoreHandle->Id = ConfigParams->ControllerId;
+  LocalCoreHandle->BaseAddress = BaseAddr = ConfigParams->BaseAddress;
+  LocalCoreHandle->Flags = ConfigParams->Flags;
+  LocalCoreHandle->DesiredSpeed = LocalCoreHandle->ActualSpeed = ConfigParams->Speed;
+  LocalCoreHandle->Role = ConfigParams->Role;
+
+  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
+    );
+  //
+  // Wait until core soft reset completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
+
+  //
+  // All FIFOs are flushed at this point
+  //
+  //
+  // Ensure we have EP0 Rx/Tx handles initialized
+  //
+  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = UsbEpDirOut;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpType = USB_ENDPOINT_CONTROL;
+  LocalCoreHandle->EpHandles[0].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
+  //
+  // 0 means burst size of 1
+  //
+  LocalCoreHandle->EpHandles[0].EpInfo.BurstSize = 0;
+
+  LocalCoreHandle->EpHandles[1].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[1].EpInfo.EpDir = UsbEpDirIn;
+  LocalCoreHandle->EpHandles[1].EpInfo.EpType = USB_ENDPOINT_CONTROL;
+  LocalCoreHandle->EpHandles[1].EpInfo.MaxPktSize = DWC_XDCI_SS_CTRL_EP_MPS;
+  //
+  // 0 means burst size of 1
+  //
+  LocalCoreHandle->EpHandles[1].EpInfo.BurstSize = 0;
+
+  LocalCoreHandle->DevState = UsbDevStateDefault;
+
+  //
+  // Clear KeepConnect bit so we can allow disconnect and
+  // re-connect. Stay in RX_DETECT state
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
+    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
+    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) | (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
+    );
+
+  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
+
+  //
+  // Clear ULPI auto-resume bit
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
+  //
+  // Only one RxFIFO
+  //
+  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
+
+  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
+    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
+            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
+  }
+
+  //
+  // TODO: Need to check if TxFIFO should start where RxFIFO ends
+  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
+  //
+
+  //
+  // Allocate and Initialize Event Buffers
+  //
+  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
+
+  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
+  //
+  // One event Buffer per interrupt line.
+  //  Need to align it to size of event Buffer
+  //  Buffer needs to be big enough. Otherwise the core
+  //  won't operate
+  //
+  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
+                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
+                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
+                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
+                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
+
+  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GEVNTADR_REG (i),
+      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
+      );
+
+    //
+    // Clear High 32bit address register, GEVNTADR register is 64-bit register
+    // default is 0xffffffffffffffff
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
+
+    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
+    //
+    // Write size and clear the mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_EVNTSIZ_REG (i),
+      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
+      );
+
+    //
+    // Write 0 to the event count register as the last step
+    //
+    //  for event configuration
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
+
+    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
+                        i,
+                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
+  }
+
+    //
+    // Program Global Control Register to disable scaledown,
+    // disable clock gating
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GCTL_REG,
+      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
+                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
+                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
+                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
+
+    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
+
+  //
+  // TODO: Program desired Speed and set LPM capable
+  // We will do this when SuperSpeed works. For now,
+  // force into High-Speed mode to aVOID anyone trying this
+  // on Super Speed port
+  //
+#ifdef SUPPORT_SUPER_SPEED
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
+    );
+#else
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
+    );
+#endif
+
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
+
+  //
+  // Enable Device Interrupt Events
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DEVTEN_REG,
+    DWC_XDCI_DEVTEN_DEVICE_INTS
+    );
+  //
+  // Program the desired role
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GCTL_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
+    );
+  //
+  // Clear USB2 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+    );
+
+  //
+  // Clear USB3 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB3PIPECTL_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+    );
+
+  //
+  // Issue DEPSTARTCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams);
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Prepare a Buffer for SETUP packet
+  //
+  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
+                            LocalCoreHandle->UnalignedTrbs +
+                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
+                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
+                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
+  //
+  // Allocate Setup Buffer that is 8-byte aligned
+  //
+  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
+                                            (DWC_XDCI_SETUP_BUFF_SIZE -
+                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+  //
+  // Aligned Buffer for status phase
+  //
+  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
+                                           (DWC_XDCI_SETUP_BUFF_SIZE -
+                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+
+  //
+  // Enable Physical Endpoints 0
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
+    );
+  //
+  // Enable Physical Endpoints 1
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
+  return status;
+}
+
+
+/**
+  Interface:
+  This function is used to de-initialize the xDCI core
+  @CoreHandle: xDCI controller handle
+  @flags: Special flags for de-initializing the core in
+  particular way
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDeinit (
+  IN VOID      *CoreHandle,
+  IN UINT32    flags
+  )
+{
+  FreePool (CoreHandle);
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to register event callback function
+  @CoreHandle: xDCI controller handle
+  @event: Event for which callback is to be registered
+  @callbackFn: Callback function to invoke after event occurs
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreRegisterCallback (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: event is %d\n", Event));
+  switch (Event) {
+    case USB_DEVICE_DISCONNECT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_RESET_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBusResetCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_CONNECTION_DONE:
+      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_STATE_CHANGE_EVENT:
+      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_WAKEUP_EVENT:
+      LocalCoreHandle->EventCallbacks.DevWakeupCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_HIBERNATION_REQ_EVENT:
+      LocalCoreHandle->EventCallbacks.DevHibernationCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_SOF_EVENT:
+      LocalCoreHandle->EventCallbacks.DevSofCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_ERRATIC_ERR_EVENT:
+      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_CMD_CMPLT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_TEST_LMP_RX_EVENT:
+      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_SETUP_PKT_RECEIVED:
+      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_XFER_NRDY:
+      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = CallbackFunc;
+      break;
+
+    case USB_DEVICE_XFER_DONE:
+      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = CallbackFunc;
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to unregister event callback function
+  @CoreHandle: xDCI controller handle
+  @event: Event for which callback function is to be unregistered
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreUnregisterCallback (
+  IN VOID                   *CoreHandle,
+  IN USB_DEVICE_EVENT_ID    event
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreUnregisterCallback: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  switch (event) {
+    case USB_DEVICE_DISCONNECT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevDisconnectCallback = NULL;
+      break;
+
+    case USB_DEVICE_RESET_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBusResetCallback = NULL;
+      break;
+
+    case USB_DEVICE_CONNECTION_DONE:
+      LocalCoreHandle->EventCallbacks.DevResetDoneCallback = NULL;
+      break;
+
+    case USB_DEVICE_STATE_CHANGE_EVENT:
+      LocalCoreHandle->EventCallbacks.DevLinkStateCallback = NULL;
+      break;
+
+    case USB_DEVICE_WAKEUP_EVENT:
+      LocalCoreHandle->EventCallbacks.DevWakeupCallback = NULL;
+      break;
+
+    case USB_DEVICE_HIBERNATION_REQ_EVENT:
+      LocalCoreHandle->EventCallbacks.DevHibernationCallback = NULL;
+      break;
+
+    case USB_DEVICE_SOF_EVENT:
+      LocalCoreHandle->EventCallbacks.DevSofCallback = NULL;
+      break;
+
+    case USB_DEVICE_ERRATIC_ERR_EVENT:
+      LocalCoreHandle->EventCallbacks.DevErraticErrCallback = NULL;
+      break;
+
+    case USB_DEVICE_CMD_CMPLT_EVENT:
+      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback = NULL;
+      break;
+
+    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
+      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback = NULL;
+      break;
+
+    case USB_DEVICE_TEST_LMP_RX_EVENT:
+      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback = NULL;
+      break;
+
+    case USB_DEVICE_SETUP_PKT_RECEIVED:
+      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback = NULL;
+      break;
+
+    case USB_DEVICE_XFER_NRDY:
+      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback = NULL;
+      break;
+
+    case USB_DEVICE_XFER_DONE:
+      LocalCoreHandle->EventCallbacks.DevXferDoneCallback = NULL;
+      break;
+
+    default:
+      break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used as an interrupt service routine
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutine (
+  IN VOID     *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32              BaseAddr;
+  UINT32              eventCount;
+  UINT32              ProcessedEventCount;
+  UINT32              i;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutine: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (LocalCoreHandle->InterrupProcessing == TRUE) {
+    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
+    return EFI_SUCCESS;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+  //
+  // Event Buffer corresponding to each interrupt line needs
+  // to be Processed
+  //
+  LocalCoreHandle->InterrupProcessing = TRUE;
+  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
+    //
+    // Get the number of events HW has written for this
+    //  interrupt line
+    //
+    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i));
+    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+    ProcessedEventCount = 0;
+
+    //
+    // Process interrupt line Buffer only if count is non-zero
+    //
+    if (eventCount) {
+      //
+      // Process events in this Buffer
+      //
+      DwcXdciProcessInterruptLineEvents (LocalCoreHandle, eventCount, &ProcessedEventCount);
+      //
+      // Write back the Processed number of events so HW decrements it from current
+      // event count
+      //
+      UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), ProcessedEventCount);
+    }
+  }
+  LocalCoreHandle->InterrupProcessing = FALSE;
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used as an interrupt service routine and it processes only one event at a time.
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutineTimerBased (
+  IN VOID     *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32              BaseAddr;
+  UINT32              eventCount;
+  UINT32              ProcessedEventCount;
+  UINT32              currentEventAddr;
+  UINT32              ProcessedEventSize = 0;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutineTimerBased: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (LocalCoreHandle->CurrentEventBuffer == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIsrRoutineTimerBased: INVALID event Buffer\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0)) & DWC_XDCI_EVNTCOUNT_MASK;
+
+  if (LocalCoreHandle->InterrupProcessing == TRUE) {
+    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
+    return EFI_SUCCESS;
+  }
+
+  LocalCoreHandle->InterrupProcessing = TRUE;
+
+  ProcessedEventCount = 0;
+  currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->CurrentEventBuffer);
+
+  if (LocalCoreHandle->CurrentEventBuffer->Event & DWC_XDCI_EVENT_DEV_MASK) {
+    DwcXdciProcessDeviceEvent (
+      LocalCoreHandle,
+      LocalCoreHandle->CurrentEventBuffer,
+      &ProcessedEventSize
+      );
+  } else {
+    DwcXdciProcessEpEvent (
+      LocalCoreHandle,
+      LocalCoreHandle->CurrentEventBuffer,
+      &ProcessedEventSize);
+  }
+
+  eventCount -= ProcessedEventSize;
+  ProcessedEventCount += ProcessedEventSize;
+  if ((currentEventAddr + ProcessedEventSize) >=
+      ((UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers) + (sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))
+     ) {
+    currentEventAddr = (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers);
+    DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event Buffer bound reached\n"));
+  } else {
+    currentEventAddr += ProcessedEventSize;
+  }
+
+  LocalCoreHandle->CurrentEventBuffer = (DWC_XDCI_EVENT_BUFFER *)(UINTN)currentEventAddr;
+  UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0), ProcessedEventCount);
+  LocalCoreHandle->InterrupProcessing = FALSE;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to enable xDCI to connect to the host
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreConnect (
+  IN VOID     *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE    *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32              MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32              BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreConnect: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Clear KeepConnect bit so we can allow disconnect and re-connect
+  // Also issue No action on state change to aVOID any link change
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
+    );
+
+  //
+  // Set Run bit to connect to the host
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_RUN_STOP_MASK
+    );
+
+  //
+  // Wait until core starts running
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK)) {
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to run the device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to disconnect xDCI from the host
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDisconnect (
+  IN VOID    *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32            BaseAddr;
+  UINT32            eventCount;
+  UINT32            dsts;
+  UINT32            i;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+  eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+
+  DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
+  while (eventCount) {
+    DwcXdciCoreIsrRoutine(LocalCoreHandle);
+    eventCount = UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0));
+    eventCount &= DWC_XDCI_EVNTCOUNT_MASK;
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=%d\n", eventCount));
+  }
+
+  //
+  // Issue DEPENDXFER for active transfers
+  //
+  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++){
+    if (LocalCoreHandle->EpHandles[i].CurrentXferRscIdx){
+      DwcXdciEndXfer(LocalCoreHandle, i);
+    }
+  }
+  //
+  // Clear Run bit to disconnect from host
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_RUN_STOP_MASK);
+
+  //
+  // Wait until core is halted
+  //
+  do {
+    dsts = UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG);
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: waiting halt: DSTS=0x%x\n", dsts));
+    if ((dsts & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK) != 0){
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: Failed to halt the device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to obtain current USB bus Speed
+  @CoreHandle: xDCI controller handle
+  @Speed: Address of variable to save the Speed
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreGetSpeed (
+  IN VOID         *CoreHandle,
+  IN USB_SPEED    *Speed
+  )
+{
+  XDCI_CORE_HANDLE *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (Speed == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID parameter\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Speed = UsbRegRead (LocalCoreHandle->BaseAddress, DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK;
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to obtain current USB bus Speed
+  @CoreHandle: xDCI controller handle
+  @address: USB address to set (assigned by USB host)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetAddress (
+  IN VOID      *CoreHandle,
+  IN UINT32    address
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress is 0x%x \n", address));
+  //
+  // Program USB device address
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DEV_ADDRESS_MASK) | (address << DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS)
+    );
+
+  LocalCoreHandle->DevState = UsbDevStateAddress;
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to set configuration
+  @CoreHandle: xDCI controller handle
+  @ConfigNum: config num to set (assigned by USB host)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetConfig (
+  IN VOID      *CoreHandle,
+  IN UINT32    ConfigNum
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Issue DEPSTARTCFG command on EP0 (new config for
+  // non-control EPs)
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+            LocalCoreHandle,
+            &LocalCoreHandle->EpHandles[0].EpInfo,
+            DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+            EPCMD_START_NEW_CONFIG,
+            &EpCmdParams
+            );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to init params for EPCMD_START_NEW_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             (EPCMD_START_NEW_CONFIG | (2 << DWC_XDCI_EPCMD_RES_IDX_BIT_POS)),
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to issue EPCMD_START_NEW_CONFIG command\n"));
+    return status;
+  }
+
+  return status;
+}
+
+
+/**
+  Interface:
+  This function is used to set link state
+  @CoreHandle: xDCI controller handle
+  @state: Desired link state
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciSetLinkState (
+  IN VOID                        *CoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE    state
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciSetLinkState: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Clear old mask
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
+    );
+
+  //
+  // Request new state
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | (state << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS)
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to initialize endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be initialized
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciInitEp (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+  UINT32                        EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Save EP properties
+  //
+  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].EpInfo), EpInfo, sizeof (USB_EP_INFO));
+
+  //
+  // Init CheckFlag
+  //
+  LocalCoreHandle->EpHandles[EpNum].CheckFlag = FALSE;
+
+  //
+  // Init DEPCFG cmd params for EP
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             CoreHandle,
+             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             CoreHandle,
+             EpNum,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue  EPCMD_SET_EP_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue a DEPXFERCFG command for endpoint
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for  EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             EpNum,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
+  }
+
+  return status;
+}
+
+
+/**
+  Interface:
+  This function is used to enable non-Ep0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpEnable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            EpNum;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpEnable: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Enable Physical Endpoint EpNum
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << EpNum)
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to disable non-Ep0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpDisable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            EpNum;
+  UINT32            BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpDisable: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Disable Physical Endpoint EpNum
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) & ~(1 << EpNum)
+    );
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to STALL and endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+  UINT32                        EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpStall: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Set Ep State Info
+  //
+  if (LocalCoreHandle->EpHandles[EpNum].State != USB_EP_STATE_STALLED) {
+    LocalCoreHandle->EpHandles[EpNum].OrgState = LocalCoreHandle->EpHandles[EpNum].State;
+    LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_STALLED;
+  }
+  //
+  // Issue a DWC_XDCI_EPCMD_SET_STALL for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+ //
+ // Issue the command
+ //
+ status = DwcXdciCoreIssueEpCmd (
+            LocalCoreHandle,
+            EpNum,
+            DWC_XDCI_EPCMD_SET_STALL,
+            &EpCmdParams
+            );
+
+ if (status) {
+   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP stall command\n"));
+ }
+
+ return status;
+}
+
+
+/**
+  Interface:
+  This function is used to clear endpoint STALL
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpClearStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  EFI_STATUS                    status;
+  UINT32                        EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpClearStall: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Set Ep State Info
+  //
+  LocalCoreHandle->EpHandles[EpNum].State = LocalCoreHandle->EpHandles[EpNum].OrgState;
+
+  //
+  // Issue a DWC_XDCI_EPCMD_CLEAR_STALL for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Issue the command
+  //
+ status = DwcXdciCoreIssueEpCmd (
+            LocalCoreHandle,
+            EpNum,
+            DWC_XDCI_EPCMD_CLEAR_STALL,
+            &EpCmdParams
+            );
+
+ if (status) {
+   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP clea stall command\n"));
+ }
+
+ return status;
+}
+
+
+/**
+  Interface:
+  This function is used to set endpoint in NOT READY state
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  to be enabled
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpSetNrdy (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  XDCI_CORE_HANDLE  *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  UINT32            EpNum;
+  UINT32            BaseAddr;
+  UINT32            MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpSetNrdy: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+
+  //
+  // Program the EP number in command's param reg
+  //
+  UsbRegWrite (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG, EpNum);
+
+  //
+  // Issue EP not ready generic device command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SET_EP_NRDY)
+    );
+
+  //
+  // Activate the command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Interface:
+  This function is used to queue receive SETUP packet request
+  @CoreHandle: xDCI controller handle
+  @Buffer: Address of Buffer to receive SETUP packet
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveSetupPkt (
+  IN VOID     *CoreHandle,
+  IN UINT8    *Buffer
+  )
+{
+  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      Status = EFI_DEVICE_ERROR;
+  DWC_XDCI_TRB                    *Trb;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
+  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_SETUP;
+  Trb = LocalCoreHandle->Trbs;
+  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveSetupPkt)\n"));
+
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TRBCTL_SETUP,
+             Buffer,
+             8
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: Init TRB Failed \n"));
+    return Status;
+  }
+
+  //
+  // Issue a DEPSTRTXFER for EP0
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "\nDwcXdciEp0ReceiveSetupPkt: Failed to issue Start Transfer command"));
+  }
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(LocalCoreHandle->BaseAddress, DWC_XDCI_EPCMD_REG(0)) &
+                                                         DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
+                                                         );
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to queue receive status packet on EP0
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveStatusPkt (
+  IN VOID    *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_TRB                    *Trb;
+  DWC_XDCI_TRB_CONTROL            TrbCtrl;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      Status;
+  UINT32                          BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // We are receiving on EP0 so physical EP is 0
+  //
+  Trb = LocalCoreHandle->Trbs;
+  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveStatusPkt)\n"));
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    DEBUG ((DEBUG_INFO, "statusPkt still not transferred.\n"));
+    return EFI_SUCCESS;
+  }
+
+  LocalCoreHandle->EpHandles[0].EpInfo.EpNum = 0;
+  LocalCoreHandle->EpHandles[0].EpInfo.EpDir = 0;
+
+  //
+  // OUT data phase for 3-phased control transfer
+  //
+  TrbCtrl = TRBCTL_3_PHASE;
+
+  //
+  // Init TRB for the transfer
+  //
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TrbCtrl,
+             LocalCoreHandle->AlignedSetupBuffer,
+             0
+             );
+
+  if (!Status) {
+    //
+    // Issue a DEPSTRTXFER for EP0
+    // Reset params
+    //
+    EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+    //
+    // Init the lower bits for TRB address
+    //
+    EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+    //
+    // Issue the command
+    //
+    Status = DwcXdciCoreIssueEpCmd (
+               LocalCoreHandle,
+               0,
+               EPCMD_START_XFER,
+               &EpCmdParams
+               );
+
+    if (Status) {
+      DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: Failed to issue Start Transfer command for EP0\n"));
+    }
+    //
+    // Save new resource index for this transfer
+    //
+    LocalCoreHandle->EpHandles[0].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(0)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+
+    //
+    // TODO: We are not using the EP state for control transfers
+    // right now simply because we're only supporting IN
+    // data phase. For the current use case, we don't
+    // need OUT data phase. We can add that later and we will
+    // add some of the state and SETUP packet awareness code
+    //
+    LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
+  }
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to send status packet on EP0
+  @CoreHandle: xDCI controller handle
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEp0SendStatusPkt (
+  IN VOID    *CoreHandle
+  )
+{
+  XDCI_CORE_HANDLE                *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_TRB                    *Trb;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  EFI_STATUS                      Status;
+  UINT32                          BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // We are sending on EP0 so physical EP is 1
+  //
+  Trb = (LocalCoreHandle->Trbs + (1 * DWC_XDCI_TRB_NUM));
+  DEBUG ((DEBUG_INFO, "(DwcXdciEp0SendStatusPkt)\n"));
+
+  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TRBCTL_2_PHASE,
+             LocalCoreHandle->AlignedMiscBuffer,
+             0
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: TRB failed during status phase\n"));
+    return Status;
+  }
+
+  //
+  // Issue a DEPSTRTXFER for EP1
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: Failed to issue Start Transfer on EP0\n"));
+  }
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[1].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(1)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+  LocalCoreHandle->EpHandles[0].State = USB_EP_STATE_STATUS;
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to send data on non-EP0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  @Buffer: Buffer containing data to transmit
+  @size: Size of transfer (in bytes)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpTxData (
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  DWC_XDCI_TRB                  *Trb;
+  DWC_XDCI_TRB_CONTROL          TrbCtrl;
+  EFI_STATUS                    Status;
+  UINT32                        EpNum;
+  UINT32                        BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (XferReq == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID transfer request\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (
+             XferReq->EpInfo.EpNum,
+             XferReq->EpInfo.EpDir
+             );
+
+  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
+  DEBUG ((DEBUG_INFO, "(DwcXdciEpTxData)EpNum is %d\n", EpNum));
+
+
+  if (EpNum > 1)
+    TrbCtrl = TRBCTL_NORMAL;
+  else
+    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
+
+  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
+    Status = DwcXdciEndXfer (LocalCoreHandle, EpNum);
+    if (Status) {
+      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
+    }
+
+    Status = DwcXdciCoreFlushEpTxFifo (LocalCoreHandle, EpNum);
+    if (Status) {
+      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous transfer\n"));
+    }
+  }
+
+  //
+  // Data phase
+  //
+  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
+  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
+
+  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
+
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TrbCtrl,
+             XferReq->XferBuffer,
+             XferReq->XferLen
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: TRB failed\n"));
+    return Status;
+  }
+
+  //
+  // Issue a DEPSTRTXFER for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             EpNum,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+
+  return Status;
+}
+
+
+/**
+  Interface:
+  This function is used to receive data on non-EP0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+  @Buffer: Buffer containing data to transmit
+  @size: Size of transfer (in bytes)
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpRxData (
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  )
+{
+  XDCI_CORE_HANDLE              *LocalCoreHandle = (XDCI_CORE_HANDLE *)CoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
+  DWC_XDCI_TRB                  *Trb;
+  DWC_XDCI_TRB_CONTROL          TrbCtrl;
+  EFI_STATUS                    Status;
+  UINT32                        EpNum;
+  UINT32                        BaseAddr;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (XferReq == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID transfer request\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  //
+  // Convert to physical endpoint
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (XferReq->EpInfo.EpNum, XferReq->EpInfo.EpDir);
+
+  Trb = (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
+  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)EpNum is %d\n", EpNum));
+
+  if (EpNum > 1)
+    TrbCtrl = TRBCTL_NORMAL;
+  else
+    TrbCtrl = TRBCTL_CTRL_DATA_PHASE;
+
+  //
+  // If CheckFlag didn't set to FALSE, means the previous transfer request didn't complete,
+  // need to wait the previous request done.
+  //
+  if (LocalCoreHandle->EpHandles[EpNum].CheckFlag == TRUE) {
+    return EFI_NOT_READY;
+  }
+
+  LocalCoreHandle->EpHandles[EpNum].CheckFlag = TRUE;
+
+  //
+  // Data phase
+  //
+  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle), XferReq, sizeof (USB_XFER_REQUEST));
+
+  LocalCoreHandle->EpHandles[EpNum].State = USB_EP_STATE_DATA;
+
+  LocalCoreHandle->EpHandles[EpNum].Trb = Trb;
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)XferReq->XferLen is 0x%x\n", XferReq->XferLen));
+
+  Status = DwcXdciCoreInitTrb (
+             LocalCoreHandle,
+             Trb,
+             TrbCtrl,
+             XferReq->XferBuffer,
+             XferReq->XferLen
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: TRB failed\n"));
+    return Status;
+  }
+  //
+  // Issue a DEPSTRTXFER for EP
+  // Reset params
+  //
+  EpCmdParams.Param0 = EpCmdParams.Param1 = EpCmdParams.Param2 = 0;
+
+  //
+  // Init the lower re-bits for TRB address
+  //
+  EpCmdParams.Param1 = (UINT32)(UINTN)Trb;
+
+  //
+  // Issue the command
+  //
+  Status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             EpNum,
+             EPCMD_START_XFER,
+             &EpCmdParams
+             );
+
+  if (Status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: Failed to start transfer\n"));
+  }
+
+  //
+  // Save new resource index for this transfer
+  //
+  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx = ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) & DWC_XDCI_EPCMD_RES_IDX_MASK) >> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
+
+  return Status;
+}
+
+
+
+STATIC
+EFI_STATUS
+DwcXdciCoreFlushEpFifo (
+  IN XDCI_CORE_HANDLE    *CoreHandle,
+  IN UINT32              EpNum
+  )
+{
+  UINT32 BaseAddr;
+  UINT32 MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT32 fifoNum;
+  UINT32 Param;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  BaseAddr = CoreHandle->BaseAddress;
+
+  //
+  // Translate to FIFOnum
+  // NOTE: Assuming this is a Tx EP
+  //
+  fifoNum = (EpNum >> 1);
+
+  //
+  // TODO: Currently we are only using TxFIFO 0. Later map these
+  // Write the FIFO num/dir param for the generic command.
+  //
+
+  Param = UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG);
+  Param &= ~(DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
+
+  if ((EpNum & 0x01) != 0) {
+    Param |= (fifoNum | DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
+  } else {
+    Param |= fifoNum;
+  }
+
+  DEBUG ((DEBUG_INFO, "USB FU Flash: CMD 0x%08x :: Param 0x%08x\n",
+        (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK),
+        Param));
+
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_PARAM_REG,
+    Param
+    );
+
+  //
+  // Write the command to flush all FIFOs
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DGCMD_REG,
+    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) | DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH | DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
+    );
+
+
+  //
+  // Wait until command completes
+  //
+  do {
+    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) & DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
+      break;
+    else
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Interface:
+  This function is used to cancel a transfer on non-EP0 endpoint
+  @CoreHandle: xDCI controller handle
+  @EpInfo: Address of structure describing properties of EP
+
+**/
+EFI_STATUS
+EFIAPI
+DwcXdciEpCancelTransfer (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+  UINT32      EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Get physical EP num
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+  Status = DwcXdciEndXfer(CoreHandle, EpNum);
+  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
+
+  return Status;
+}
+
+
+EFI_STATUS
+usbProcessDeviceResetDet (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+   return DwcXdciProcessDeviceResetDet (CoreHandle);
+}
+
+EFI_STATUS
+usbProcessDeviceResetDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  )
+{
+  return DwcXdciProcessDeviceResetDone (CoreHandle);
+}
+
+UINT32
+UsbGetPhysicalEpNum (
+  IN UINT32        EndpointNum,
+  IN USB_EP_DIR    EndpointDir
+  )
+{
+  return DwcXdciGetPhysicalEpNum(
+                            EndpointNum,
+                            EndpointDir
+                            );
+}
+
+
+EFI_STATUS
+EFIAPI
+UsbXdciCoreReinit (
+  IN VOID                     *CoreHandle
+  )
+{
+  EFI_STATUS                      status = EFI_DEVICE_ERROR;
+  UINT32                          BaseAddr;
+  XDCI_CORE_HANDLE                *LocalCoreHandle;
+  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
+  UINT32                          MaxDelayIter = DWC_XDCI_MAX_DELAY_ITERATIONS;
+  UINT8                           i;
+
+  LocalCoreHandle = CoreHandle;
+
+  if (CoreHandle == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (LocalCoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle for xDCI\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  BaseAddr = LocalCoreHandle->BaseAddress;
+
+  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | DWC_XDCI_DCTL_CSFTRST_MASK
+    );
+
+  //
+  // Wait until core soft reset completes
+  //
+  do {
+    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) & DWC_XDCI_DCTL_CSFTRST_MASK)) {
+      break;
+    } else {
+      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
+    }
+  } while (--MaxDelayIter);
+
+  if (!MaxDelayIter) {
+    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
+
+  LocalCoreHandle->DevState = UsbDevStateDefault;
+
+  //
+  // Clear KeepConnect bit so we can allow disconnect and
+  // re-connect. Stay in RX_DETECT state
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCTL_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
+    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
+    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
+    (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT << DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
+    );
+
+  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n", UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and GSBUSCFG1: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and GRXTHRCFG: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
+
+  //
+  // Clear ULPI auto-resume bit
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) & ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and GUSB3PIPECTL: %x, %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
+          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
+
+  //
+  // Only one RxFIFO
+  //
+  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
+          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
+
+  for (i = 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
+    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ %d: %x\n",
+            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
+  }
+
+  //
+  // TODO: Need to check if TxFIFO should start where RxFIFO ends
+  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
+  //
+
+  //
+  // Allocate and Initialize Event Buffers
+  //
+  LocalCoreHandle->MaxDevIntLines = ((UsbRegRead (BaseAddr, DWC_XDCI_GHWPARAMS1_REG) &
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
+                                           DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS);
+
+  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle->MaxDevIntLines));
+  //
+  // One event Buffer per interrupt line.
+  //  Need to align it to size of event Buffer
+  //  Buffer needs to be big enough. Otherwise the core
+  //  won't operate
+  //
+  LocalCoreHandle->AlignedEventBuffers = (DWC_XDCI_EVENT_BUFFER *)
+                                             ((UINT32)(UINTN)(LocalCoreHandle->EventBuffers) +
+                                             ((sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
+                                             (((UINT32)(UINTN)(LocalCoreHandle->EventBuffers)) %
+                                             (sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
+
+  for (i = 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GEVNTADR_REG (i),
+      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i * sizeof(DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER)
+      );
+
+    //
+    // Clear High 32bit address register, GEVNTADR register is 64-bit register
+    // default is 0xffffffffffffffff
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4, 0x00000000);
+
+    LocalCoreHandle->CurrentEventBuffer = LocalCoreHandle->AlignedEventBuffers;
+    //
+    // Write size and clear the mask
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_EVNTSIZ_REG (i),
+      sizeof (DWC_XDCI_EVENT_BUFFER) * DWC_XDCI_MAX_EVENTS_PER_BUFFER
+      );
+
+    //
+    // Write 0 to the event count register as the last step
+    // for event configuration
+    //
+    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
+
+    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x, Count: %x\n",
+                        i,
+                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)),
+                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i))));
+  }
+
+    //
+    // Program Global Control Register to disable scaledown,
+    // disable clock gating
+    //
+    UsbRegWrite (
+      BaseAddr,
+      DWC_XDCI_GCTL_REG,
+      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
+                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK + DWC_XDCI_GCTL_RAMCLKSEL_MASK + DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
+                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
+                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
+
+    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
+
+
+  //
+  // TODO: Program desired Speed and set LPM capable
+  // We will do this when SuperSpeed works. For now,
+  // force into High-Speed mode to aVOID anyone trying this
+  // on Super Speed port
+  //
+#ifdef SUPPORT_SUPER_SPEED
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle->DesiredSpeed
+    );
+#else
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DCFG_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) & ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | DWC_XDCI_DCFG_DESIRED_HS_SPEED
+    );
+#endif
+
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
+  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
+
+  //
+  // Enable Device Interrupt Events
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_DEVTEN_REG,
+    DWC_XDCI_DEVTEN_DEVICE_INTS
+    );
+
+  //
+  // Program the desired role
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GCTL_REG,
+    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) & ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role << DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
+    );
+
+  //
+  // Clear USB2 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB2PHYCFG_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) & ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
+    );
+  //
+  // Clear USB3 suspend for start new config command
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_GUSB3PIPECTL_REG (0),
+    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) & ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
+    );
+  //
+  // Issue DEPSTARTCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_START_NEW_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue START_NEW_CONFIG EP command on xDCI\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams);
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue SET_EP_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP0
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[0].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             0,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
+    return status;
+  }
+
+  //
+  // Issue DEPXFERCFG command for EP1
+  //
+  status = DwcXdciCoreInitEpCmdParams (
+             LocalCoreHandle,
+             &LocalCoreHandle->EpHandles[1].EpInfo,
+             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Issue the command
+  //
+  status = DwcXdciCoreIssueEpCmd (
+             LocalCoreHandle,
+             1,
+             EPCMD_SET_EP_XFER_RES_CONFIG,
+             &EpCmdParams
+             );
+
+  if (status) {
+    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
+    return status;
+  }
+
+  //
+  // Prepare a Buffer for SETUP packet
+  //
+  LocalCoreHandle->Trbs = (DWC_XDCI_TRB *)((UINTN)
+                            LocalCoreHandle->UnalignedTrbs +
+                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
+                            ((UINT32)(UINTN)LocalCoreHandle->UnalignedTrbs %
+                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
+
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
+  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB address is 0x%x\n", LocalCoreHandle->Trbs));
+
+  //
+  // Allocate Setup Buffer that is 8-byte aligned
+  //
+  LocalCoreHandle->AlignedSetupBuffer = LocalCoreHandle->DefaultSetupBuffer +
+                                            (DWC_XDCI_SETUP_BUFF_SIZE -
+                                            ((UINT32)(UINTN)(LocalCoreHandle->DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+  //
+  // Aligned Buffer for status phase
+  //
+  LocalCoreHandle->AlignedMiscBuffer = LocalCoreHandle->MiscBuffer +
+                                           (DWC_XDCI_SETUP_BUFF_SIZE -
+                                           ((UINT32)(UINTN)(LocalCoreHandle->AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
+
+  //
+  // We will queue SETUP request when we see bus reset
+  //
+
+  //
+  // Enable Physical Endpoints 0
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
+    );
+
+  //
+  // Enable Physical Endpoints 1
+  //
+  UsbRegWrite (
+    BaseAddr,
+    DWC_XDCI_EP_DALEPENA_REG,
+    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
+    );
+
+  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG: 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
+  return status;
+
+
+}
+
+
+EFI_STATUS
+UsbXdciCoreFlushEpFifo (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  )
+{
+  EFI_STATUS  Status = EFI_DEVICE_ERROR;
+  UINT32      EpNum;
+
+  if (CoreHandle == NULL) {
+    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID handle\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Get physical EP num
+  //
+  EpNum = DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
+  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
+
+  return Status;
+}
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
new file mode 100644
index 0000000000..9c1b2d1d85
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
@@ -0,0 +1,741 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 _XDCI_DWC_H_
+#define _XDCI_DWC_H_
+
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+
+#define DWC_XDCI_MAX_ENDPOINTS                             (16)
+#define DWC_XDCI_SS_CTRL_EP_MPS                            (512)
+#define DWC_XDCI_HS_CTRL_EP_MPS                            (64)
+#define DWC_XDCI_FS_CTRL_EP_MPS                            (64)
+#define DWC_XDCI_LS_CTRL_EP_MPS                            (8)
+#define DWC_XDCI_SS_CTRL_BUF_SIZE                          (512)
+#define DWC_XDCI_SETUP_BUFF_SIZE                           (8)
+#define DWC_XDCI_MAX_EVENTS_PER_BUFFER                     (16)
+#define DWC_XDCI_TRB_BYTE_ALIGNMENT                        (16)
+#define DWC_XDCI_DEFAULT_TX_FIFO_SIZE                      (1024)
+#define DWC_XDCI_TRB_NUM                                   (32)
+#define DWC_XDCI_MASK                                      (DWC_XDCI_TRB_NUM - 1)
+
+#define DWC_XDCI_MAX_DELAY_ITERATIONS                      (1000)
+
+#define DWC_XDCI_GSBUSCFG0_REG                             (0xC100)
+#define DWC_XDCI_GSBUSCFG1_REG                             (0xC104)
+#define DWC_XDCI_GTXTHRCFG_REG                             (0xC108)
+#define DWC_XDCI_GRXTHRCFG_REG                             (0xC10C)
+
+//
+// Global Control Register and bit definitions
+//
+#define DWC_XDCI_GCTL_REG                                  (0xC110)
+#define DWC_XDCI_GCTL_PWRDNSCALE_MASK                      (0xFFF80000)
+#define DWC_XDCI_GCTL_PWRDNSCALE_VAL                       (0x13880000)
+#define DWC_XDCI_GCTL_U2RSTECN_MASK                        (0x00010000)
+#define DWC_XDCI_GCTL_PRT_CAP_DIR_MASK                     (0x00003000)
+#define DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS                  (12)
+#define DWC_XDCI_GCTL_PRT_CAP_HOST                         (1)
+#define DWC_XDCI_GCTL_PRT_CAP_DEVICE                       (2)
+#define DWC_XDCI_GCTL_PRT_CAP_OTG                          (3)
+#define DWC_XDCI_GCTL_RAMCLKSEL_MASK                       (0x000000C0)
+#define DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK                 (0x00000030)
+#define DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK              (0x00000001)
+#define DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK                  (0x00000008)
+
+#define DWC_XDCI_GSTS_REG                                  (0xC118)
+#define DWC_XDCI_GSNPSID_REG                               (0xC120)
+#define DWC_XDCI_GGPIO_REG                                 (0xC124)
+#define DWC_XDCI_GUID_REG                                  (0xC128)
+#define DWC_XDCI_GUCTL_REG                                 (0xC12C)
+#define DWC_XDCI_GBUSERRADDR                               (0xC130)
+
+//
+// Global Hardware Parameters Registers
+//
+#define DWC_XDCI_GHWPARAMS0_REG                            (0xC140)
+#define DWC_XDCI_GHWPARAMS1_REG                            (0xC144)
+#define DWC_XDCI_GHWPARAMS1_NUM_INT_MASK                   (0x1F8000)
+#define DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS                (15)
+
+#define DWC_XDCI_GHWPARAMS2_REG                            (0xC148)
+#define DWC_XDCI_GHWPARAMS3_REG                            (0xC14C)
+#define DWC_XDCI_GHWPARAMS4_REG                            (0xC150)
+#define DWC_XDCI_GHWPARAMS4_CACHE_TRBS_PER_XFER_MASK       (0x0000003F)
+#define DWC_XDCI_GHWPARAMS5_REG                            (0xC154)
+#define DWC_XDCI_GHWPARAMS6_REG                            (0xC158)
+#define DWC_XDCI_GHWPARAMS7_REG                            (0xC15C)
+#define DWC_XDCI_GHWPARAMS8_REG                            (0xC600)
+
+#define DWC_XDCI_GDBGFIFOSPACE_REG                         (0xC160)
+
+#define DWC_XDCI_GUSB2PHYCFG_REG(n)                        (0xC200 + (n << 2))
+#define DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK         (0x00008000)
+#define DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK              (0x00000040)
+
+#define DWC_XDCI_GUSB3PIPECTL_REG(n)                       (0xC2C0 + (n << 2))
+#define DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK             (0x00020000)
+
+#define DWC_XDCI_GTXFIFOSIZ_REG(n)                         (0xC300 + (n << 2))
+#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_MASK             (0xFFFF0000)
+#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_BIT_POS          (16)
+#define DWC_XDCI_GRXFIFOSIZ_REG(n)                         (0xC380 + (n << 2))
+
+//
+// Global Event Buffer Registers
+//
+#define DWC_XDCI_GEVNTADR_REG(n)                           (0xC400 + (n << 4))
+#define DWC_XDCI_EVNTSIZ_REG(n)                            (0xC408 + (n << 4))
+#define DWC_XDCI_EVNTSIZ_MASK                              (0x0000FFFF)
+#define DWC_XDCI_EVNT_INTR_MASK                            (0x80000000)
+#define DWC_XDCI_EVNTCOUNT_REG(n)                          (0xC40C + (n << 4))
+#define DWC_XDCI_EVNTCOUNT_MASK                            (0x0000FFFF)
+
+//
+// Device Configuration Register and Bit Definitions
+//
+#define DWC_XDCI_DCFG_REG                                  (0xC700)
+#define DWC_XDCI_DCFG_LPM_CAPABLE_MASK                     (0x00400000)
+#define DWC_XDCI_DCFG_DEV_ADDRESS_MASK                     (0x000003F8)
+#define DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS                  (3)
+#define DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK               (0x00000007)
+#define DWC_XDCI_DCFG_DESIRED_SS_SPEED                     (0x00000004)
+#define DWC_XDCI_DCFG_DESIRED_FS_SPEED                     (0x00000001)
+#define DWC_XDCI_DCFG_DESIRED_HS_SPEED                     (0x00000000)
+
+//
+// Device Control Register
+//
+#define DWC_XDCI_DCTL_REG                                  (0xC704)
+#define DWC_XDCI_DCTL_RUN_STOP_MASK                        (0x80000000)
+#define DWC_XDCI_DCTL_RUN_STOP_BIT_POS                     (31)
+#define DWC_XDCI_DCTL_CSFTRST_MASK                         (0x40000000)
+#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
+#define DWC_XDCI_DCTL_KEEP_CONNECT_MASK                    (0x00080000)
+#define DWC_XDCI_DCTL_KEEP_CONNECT_BIT_POS                 (19)
+#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK                (0x000001E0)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS             (5)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_NO_ACTION           (1)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_DISABLED         (4)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT           (5)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_INACTIVE         (6)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RECOVERY            (8)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_COMPLIANCE          (10)
+#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_REMOTE_WAKEUP       (8)
+
+//
+// Device Event Enable Register
+//
+#define DWC_XDCI_DEVTEN_REG                                (0xC708)
+#define DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK                (0x00000001)
+#define DWC_XDCI_DEVTEN_RESET_DET_EN_MASK                  (0x00000002)
+#define DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK              (0x00000004)
+#define DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK      (0x00000008)
+#define DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK          (0x00000010)
+#define DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK            (0x00000020)
+#define DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK                 (0x00000040)
+#define DWC_XDCI_DEVTEN_SOF_DET_EN_MASK                    (0x00000080)
+#define DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK            (0x00000200)
+#define DWC_XDCI_DEVTEN_VNDR_DEV_TST_RX_DET_EN_MASK        (0x00001000)
+
+#define DWC_XDCI_DEVTEN_DEVICE_INTS                        (DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_RESET_DET_EN_MASK | DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK | DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK | DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK | \
+        DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK)
+
+#define DWC_XDCI_EVENT_BUFF_BULK_STREAM_ID_MASK            (0xFFFF0000)
+#define DWC_XDCI_EVENT_BUFF_ISOCH_UFRAME_NUM_MASK          (0xFFFF0000)
+#define DWC_XDCI_EVENT_BUFF_EP_CMD_TYPE_MASK               (0x0F000000)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_RES_INDEX_MASK         (0x007F0000)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK            (0x00008000)
+#define DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK          (0x00001000)
+#define DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK        (0x00002000)
+#define DWC_XDCI_EVENT_BUFF_EP_LST_MASK                    (0x00008000)
+#define DWC_XDCI_EVENT_BUFF_EP_MISSED_ISOCH_MASK           (0x00008000)
+#define DWC_XDCI_EVENT_BUFF_EP_IOC_MASK                    (0x00004000)
+#define DWC_XDCI_EVENT_BUFF_EP_LAST_PKT_MASK               (0x00002000)
+#define DWC_XDCI_EVENT_BUFF_EP_STREAM_NOT_FND_MASK         (0x00002000)
+#define DWC_XDCI_EVENT_BUFF_EP_STREAM_FND_MASK             (0x00001000)
+#define DWC_XDCI_EVENT_BUFF_EP_ERR_NO_RES_MASK             (0x00001000)
+#define DWC_XDCI_EVENT_BUFF_EP_INVALID_RES_MASK            (0x00001000)
+
+#define DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK                  (0x000003C0)
+#define DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS               (6)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT                  (1)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS            (2)
+#define DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY              (3)
+#define DWC_XDCI_EVENT_BUFF_EP_STREAM_EVENT                (6)
+#define DWC_XDCI_EVENT_BUFF_EP_CMD_CMPLT                   (7)
+
+#define DWC_XDCI_EVENT_BUFF_EP_NUM_MASK                    (0x0000003E)
+#define DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS                 (1)
+
+#define DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK           (0x0000F000)
+
+
+#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK                  (0x01E00000)
+#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS               (21)
+#define DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK              (0x00100000)
+#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK            (0x000F0000)
+#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS         (16)
+
+#define DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK                   (0x00000F00)
+#define DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS                (8)
+#define DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT           (12)
+#define DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT            (11)
+#define DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT            (10)
+#define DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT          (9)
+#define DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT                  (7)
+#define DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT           (5)
+#define DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT                 (4)
+#define DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT         (3)
+#define DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT            (2)
+#define DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT            (1)
+#define DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT              (0)
+
+#define DWC_XDCI_EVENT_DEV_MASK                            (0x00000001)
+
+//
+// Device Status Register and Bit Definitions
+//
+#define DWC_XDCI_DSTS_REG                                  (0xC70C)
+#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK                 (0x00400000)
+#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_BIT_POS              (22)
+#define DWC_XDCI_DSTS_CORE_IDLE                            (1 << 23)
+#define DWC_XDCI_DSTS_CONN_SPEED_MASK                      (0x00000007)
+#define DWC_XDCI_DSTS_LINK_STATE_MASK                      (0x003C0000)
+#define DWC_XDCI_DSTS_LINK_STATE_DISCONNECT                (0x00100000)
+
+//
+// Device Generic Command Parameter Register
+//
+#define DWC_XDCI_DGCMD_PARAM_REG                           (0xC710)
+#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK              (0x0000001F)
+#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK              (0x00000020)
+#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_BIT_POS           (5)
+
+//
+// Device Generic Command Register
+//
+#define DWC_XDCI_DGCMD_REG                                 (0xC714)
+#define DWC_XDCI_DGCMD_CMD_STATUS_MASK                     (0x00008000)
+#define DWC_XDCI_DGCMD_CMD_ACTIVE_MASK                     (0x00000400)
+#define DWC_XDCI_DGCMD_CMD_IOC_MASK                        (0x00000100)
+#define DWC_XDCI_DGCMD_CMD_TYPE_MASK                       (0x000000FF)
+#define DWC_XDCI_DGCMD_CMD_SET_PERIODIC_PARAMS             (0x2)
+#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_LO     (0x4)
+#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_HI     (0x5)
+#define DWC_XDCI_DGCMD_CMD_XMIT_DEVICE_NOTIFICATION        (0x7)
+#define DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH                  (0x9)
+#define DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH                  (0xA)
+#define DWC_XDCI_DGCMD_CMD_SET_EP_NRDY                     (0xC)
+#define DWC_XDCI_DGCMD_CMD_RUN_SOC_BUS_LPBK                (0x10)
+
+//
+// Device Active USB EP Enable Register
+//
+#define DWC_XDCI_EP_DALEPENA_REG                           (0xC720)
+
+//
+// Device Physical EP CMD Param 2 Register. Value is 32-bit
+//
+#define DWC_XDCI_EPCMD_PARAM2_REG(n)                       (0xC800 + (n << 4))
+
+//
+// Device Physical EP CMD Param 1 Register. Value is 32-bit
+//
+#define DWC_XDCI_EPCMD_PARAM1_REG(n)                       (0xC804 + (n << 4))
+
+//
+// Device Physical EP CMD Param 0 Register. Value is 32-bit
+//
+#define DWC_XDCI_EPCMD_PARAM0_REG(n)                       (0xC808 + (n << 4))
+
+//
+// Device Physical EP Command Registers and Bit Definitions
+//
+#define DWC_XDCI_EPCMD_REG(n)                              (0xC80C + (n << 4))
+#define DWC_XDCI_EPCMD_RES_IDX_MASK                        (0x007F0000)
+#define DWC_XDCI_EPCMD_RES_IDX_BIT_POS                     (16)
+#define DWC_XDCI_EPCMD_CMDTYPE_MASK                        (0x0000000F)
+#define DWC_XDCI_EPCMD_SET_EP_CONFIG                       (0x1)
+#define DWC_XDCI_EPCMD_SET_EP_XFER_RES_CONFIG              (0x2)
+#define DWC_XDCI_EPCMD_GET_EP_STATE                        (0x3)
+#define DWC_XDCI_EPCMD_SET_STALL                           (0x4)
+#define DWC_XDCI_EPCMD_CLEAR_STALL                         (0x5)
+#define DWC_XDCI_EPCMD_START_XFER                          (0x6)
+#define DWC_XDCI_EPCMD_UPDATE_XFER                         (0x7)
+#define DWC_XDCI_EPCMD_END_XFER                            (0x8)
+#define DWC_XDCI_EPCMD_START_NEW_CONFIG                    (0x9)
+
+#define DWC_XDCI_EPCMD_CMD_IOC_MASK                        (0x00000100)
+#define DWC_XDCI_EPCMD_CMD_ACTIVE_MASK                     (0x00000400)
+#define DWC_XDCI_EPCMD_HIGH_PRIO_MASK                      (0x00000800)
+#define DWC_XDCI_EPCMD_FORCE_RM_MASK                       (0x00000800)
+
+//
+// Command status and parameter values same as event status and parameters values
+//
+#define DWC_XDCI_EPCMD_CMD_STATUS_MASK                     (0x0000F000)
+
+//
+// Command Params bit masks
+//
+#define DWC_XDCI_PARAM1_SET_EP_CFG_FIFO_BASED_MASK         (0x80000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
+
+//
+// CMD 1 param 0
+//
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK               (0xC0000000)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS            (30)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE         (0)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_RESTORE_ST         (1)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE         (2)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE               (3)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK          (0x03C00000)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS       (22)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK           (0x003E0000)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS        (17)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK                (0x00003FF8)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS             (3)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK            (0x00000006)
+#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS         (1)
+#define DWC_XDCI_PARAM0_EP_TYPE_CTRL                       (0)
+#define DWC_XDCI_PARAM0_EP_TYPE_ISOCH                      (1)
+#define DWC_XDCI_PARAM0_EP_TYPE_BULK                       (2)
+#define DWC_XDCI_PARAM0_EP_TYPE_INTR                       (3)
+
+//
+// CMD 1 param 1
+//
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK         (0x40000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK             (0x3C000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS          (26)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK             (0x02000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS          (25)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK           (0x01000000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK             (0x00FF0000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK                (0x00008000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK             (0x00003F00)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK           (0x00002000)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK      (0x00000400)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK    (0x00000200)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK     (0x00000100)
+#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK           (0x0000001F)
+
+//
+// CMD 2 param 0
+//
+#define DWC_XDCI_PARAM0_SET_EP_XFER_RES_NUM_MASK           (0x0000FFFF)
+
+//
+// CMD 3 param 2
+//
+#define DWC_XDCI_PARAM2_GET_EP_STATE_MASK                  (0xFFFFFFFF)
+
+//
+// CMD 6 param 1
+//
+#define DWC_XDCI_PARAM1_STRT_XFER_TD_ADDR_LO_MASK          (0xFFFFFFFF)
+
+//
+// CMD 6 param 0
+//
+#define DWC_XDCI_PARAM0_STRT_XFER_TD_ADDR_HI_MASK          (0xFFFFFFFF)
+
+//
+// Transfer Request Block Fields' Bit Definitions
+//
+#define DWC_XDCI_TRB_BUFF_SIZE_MASK                        (0x00FFFFFF)
+#define DWC_XDCI_TRB_PCM1_MASK                             (0x03000000)
+#define DWC_XDCI_TRB_PCM1_BIT_POS                          (24)
+#define DWC_XDCI_TRB_STATUS_MASK                           (0xF0000000)
+#define DWC_XDCI_TRB_STATUS_BIT_POS                        (28)
+#define DWC_XDCI_TRB_STATUS_OK                             (0)
+#define DWC_XDCI_TRB_STATUS_MISSED_ISOCH                   (1)
+#define DWC_XDCI_TRB_STATUS_SETUP_PENDING                  (2)
+
+#define DWC_XDCI_TRB_CTRL_HWO_MASK                         (0x00000001)
+#define DWC_XDCI_TRB_CTRL_LST_TRB_MASK                     (0x00000002)
+#define DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS                  (1)
+#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_MASK                  (0x00000004)
+#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS               (2)
+#define DWC_XDCI_TRB_CTRL_CSP_MASK                         (0x00000008)
+#define DWC_XDCI_TRB_CTRL_CSP_BIT_POS                      (3)
+#define DWC_XDCI_TRB_CTRL_TYPE_MASK                        (0x000003F0)
+#define DWC_XDCI_TRB_CTRL_TYPE_BIT_POS                     (4)
+#define DWC_XDCI_TRB_CTRL_TYPE_NORMAL                      (1)
+#define DWC_XDCI_TRB_CTRL_TYPE_SETUP                       (2)
+#define DWC_XDCI_TRB_CTRL_TYPE_STATUS2                     (3)
+#define DWC_XDCI_TRB_CTRL_TYPE_STATUS3                     (4)
+#define DWC_XDCI_TRB_CTRL_TYPE_DATA                        (5)
+#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH_FIRST                 (6)
+#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH                       (7)
+#define DWC_XDCI_TRB_CTRL_TYPE_LINK_TRB                    (8)
+#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK                 (0x00000400)
+#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_BIT_POS              (10)
+#define DWC_XDCI_TRB_CTRL_IOC_MASK                         (0x00000800)
+#define DWC_XDCI_TRB_CTRL_IOC_BIT_POS                      (11)
+#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_NUM_MASK             (0x3FFFC000)
+#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_BIT_POS              (14)
+
+#define DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES           (4)
+#define DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES           (12)
+
+typedef enum {
+  EPCMD_SET_EP_CONFIG = 1,
+  EPCMD_SET_EP_XFER_RES_CONFIG,
+  EPCMD_GET_EP_STATE,
+  EPCMD_SET_STALL,
+  EPCMD_CLEAR_STALL,
+  EPCMD_START_XFER,
+  EPCMD_UPDATE_XFER,
+  EPCMD_END_XFER,
+  EPCMD_START_NEW_CONFIG = 9
+} DWC_XDCI_ENDPOINT_CMD;
+
+typedef enum {
+  ON = 0,
+  SLEEP = 2,
+  SUSPEND,
+  DISCONNECTED,
+  EARLY_SUSPEND,
+  RESET = 14,
+  RESUME = 15
+} DWC_XDCI_HS_LINK_STATE;
+
+typedef enum {
+  TRBCTL_NORMAL = 1,
+  TRBCTL_SETUP,
+  TRBCTL_2_PHASE,
+  TRBCTL_3_PHASE,
+  TRBCTL_CTRL_DATA_PHASE,
+  TRBCTL_ISOCH_FIRST,
+  TRBCTL_ISOCH,
+  TRBCTL_LINK
+} DWC_XDCI_TRB_CONTROL;
+
+//
+// DWC XDCI Endpoint Commands Parameters struct
+//
+typedef struct {
+  UINT32 Param2;
+  UINT32 Param1;
+  UINT32 Param0;
+} DWC_XDCI_ENDPOINT_CMD_PARAMS;
+
+//
+// Event Buffer Struct
+//
+typedef struct {
+  UINT32 Event;
+  UINT32 DevTstLmp1;
+  UINT32 DevTstLmp2;
+  UINT32 Reserved;
+} DWC_XDCI_EVENT_BUFFER;
+
+//
+// Transfer Request Block
+//
+typedef struct {
+  UINT32 BuffPtrLow;
+  UINT32 BuffPtrHigh;
+  UINT32 LenXferParams;
+  UINT32 TrbCtrl;
+} DWC_XDCI_TRB;
+
+typedef struct  {
+  USB_EP_INFO       EpInfo;
+  DWC_XDCI_TRB      *Trb;
+  USB_XFER_REQUEST  XferHandle;
+  UINT32            CurrentXferRscIdx;
+  VOID              *CoreHandle;
+  USB_EP_STATE      State;
+  USB_EP_STATE      OrgState;
+  BOOLEAN           CheckFlag;
+} DWC_XDCI_ENDPOINT;
+
+typedef struct {
+  //
+  // CbEventParams must be copied over by upper layer if
+  // it defers event processing
+  //
+  USB_DEVICE_CALLBACK_PARAM CbEventParams;
+
+  //
+  // Callback function list
+  //
+  USB_DEVICE_CALLBACK_FUNC  DevDisconnectCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevBusResetCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevResetDoneCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevLinkStateCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevWakeupCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevHibernationCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevSofCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevErraticErrCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevCmdCmpltCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevBuffOvflwCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevTestLmpRxCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevSetupPktReceivedCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevXferNrdyCallback;
+  USB_DEVICE_CALLBACK_FUNC  DevXferDoneCallback;
+} USB_DEV_CALLBACK_LIST;
+
+typedef struct {
+  VOID                     *ParentHandle;                                       // Pointer to the parent this driver is associated
+  USB_CONTROLLER_ID        Id;                                                  // ID of the controllers supported in our DCD
+  USB_SPEED                DesiredSpeed;                                        // Desired SS, HS, FS or LS Speeds for the core
+  USB_ROLE                 Role;                                                // Desired role i.e. host, Device or OTG
+  USB_SPEED                ActualSpeed;                                         // Actual Speed
+  USB_DEVICE_STATE         DevState;                                            // Device state
+  UINT32                   BaseAddress;                                         // Register Base address
+  UINT32                   Flags;                                               // Init flags
+  UINT32                   MaxDevIntLines;                                      // One event Buffer per interrupt line
+  DWC_XDCI_EVENT_BUFFER    EventBuffers [DWC_XDCI_MAX_EVENTS_PER_BUFFER * 2];   // Event Buffer pool
+  DWC_XDCI_EVENT_BUFFER    *AlignedEventBuffers;                                // Aligned event Buffer pool
+  DWC_XDCI_EVENT_BUFFER    *CurrentEventBuffer;                                 // Current event Buffer address
+  DWC_XDCI_TRB             UnalignedTrbs [(DWC_XDCI_MAX_ENDPOINTS + 1) * DWC_XDCI_TRB_NUM];    // TRBs.
+  DWC_XDCI_TRB             *Trbs;                                               // 16-bytes aligned TRBs.
+  DWC_XDCI_ENDPOINT        EpHandles [DWC_XDCI_MAX_ENDPOINTS];                  // EPs
+  UINT8                    DefaultSetupBuffer [DWC_XDCI_SETUP_BUFF_SIZE * 2];   // Unaligned setup Buffer
+  UINT8                    *AlignedSetupBuffer;                                 // Aligned setup Buffer. Aligned to 8-byte boundary
+  UINT8                    MiscBuffer [528];                                    // Unaligned misc Buffer
+  UINT8                    *AlignedMiscBuffer;                                  // Aligned misc Buffer
+  UINT32                   LinkState;                                           // Link state
+  UINT32                   HirdVal;                                             // HIRD value
+  USB_DEV_CALLBACK_LIST    EventCallbacks;
+  volatile BOOLEAN         InterrupProcessing;
+} XDCI_CORE_HANDLE;
+
+//
+// DWC XDCI API prototypes
+//
+EFI_STATUS
+EFIAPI
+DwcXdciCoreInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN VOID                     *ParentHandle,
+  IN VOID                     **CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDeinit (
+  IN VOID      *CoreHandle,
+  IN UINT32    flags
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreRegisterCallback (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreUnregisterCallback (
+  IN VOID                   *CoreHandle,
+  IN USB_DEVICE_EVENT_ID    Event
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutine (
+  IN VOID *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreIsrRoutineTimerBased (
+  IN VOID *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreConnect (
+  IN VOID    *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreDisconnect (
+  IN VOID *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreGetSpeed (
+  IN VOID         *CoreHandle,
+  IN USB_SPEED    *Speed
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetAddress (
+  IN VOID      *CoreHandle,
+  IN UINT32    Address
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciCoreSetConfig (
+  IN VOID      *CoreHandle,
+  IN UINT32    ConfigNum
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciSetLinkState (
+  IN VOID                        *CoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE    State
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciInitEp (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpEnable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpDisable (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpClearStall (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpSetNrdy (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveSetupPkt (
+  IN VOID     *CoreHandle,
+  IN UINT8    *Buffer
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEp0ReceiveStatusPkt (
+  IN VOID    *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEp0SendStatusPkt (
+  IN VOID    *CoreHandle
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpTxData (
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpRxData(
+  IN VOID                *CoreHandle,
+  IN USB_XFER_REQUEST    *XferReq
+  );
+
+EFI_STATUS
+EFIAPI
+DwcXdciEpCancelTransfer (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+
+EFI_STATUS
+usbProcessDeviceResetDet (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  );
+
+EFI_STATUS
+usbProcessDeviceResetDone (
+  IN XDCI_CORE_HANDLE    *CoreHandle
+  );
+
+UINT32
+UsbGetPhysicalEpNum (
+  IN UINT32        EndpointNum,
+  IN USB_EP_DIR    EndpointDir
+  );
+
+UINT32
+UsbRegRead (
+  IN UINT32    Base,
+  IN UINT32    Offset
+  );
+
+VOID
+UsbRegWrite (
+  IN UINT32    Base,
+  IN UINT32    Offset,
+  IN UINT32    val
+  );
+
+EFI_STATUS
+UsbXdciCoreFlushEpFifo (
+  IN VOID           *CoreHandle,
+  IN USB_EP_INFO    *EpInfo
+  );
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
new file mode 100644
index 0000000000..7c94de0a60
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
@@ -0,0 +1,695 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 <Library/UsbDeviceLib.h>
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+#include "XdciInterface.h"
+#include "UsbDeviceMode.h"
+
+/**
+  This function is used to initialize the device controller
+  @configParams: Parameters from app to configure the core
+  @DevCoreHandle: Return parameter for upper layers to use
+  for all HW-independent APIs
+
+**/
+EFI_STATUS
+UsbDeviceInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN OUT VOID                 **DevCoreHandle
+  )
+{
+  USB_DEV_CORE    *DevCorePtr;
+  EFI_STATUS      Status = EFI_INVALID_PARAMETER;
+
+  DEBUG ((DEBUG_INFO, "Call UsbDeviceInit start\n"));
+
+  //
+  // Allocate device handle
+  //
+  DevCorePtr = AllocateZeroPool (sizeof (USB_DEV_CORE));
+  DEBUG ((DEBUG_INFO, "device handle = 0x%x\n", DevCorePtr));
+
+  if (DevCorePtr == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Failed to allocate memory\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "call UsbDeviceGetCoreDriver, ID=%x, \n", ConfigParams->ControllerId));
+
+  //
+  // Get the driver for this USB device core
+  //
+  DevCorePtr->CoreDriver = UsbDeviceGetCoreDriver(ConfigParams->ControllerId);
+  if (DevCorePtr->CoreDriver != NULL) {
+    DEBUG ((DEBUG_INFO, "call DevCoreInit\n"));
+    Status = DevCorePtr->CoreDriver->DevCoreInit(
+                                        ConfigParams,
+                                        (VOID*)DevCorePtr,
+                                        &DevCorePtr->ControllerHandle);
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Driver not found\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *DevCoreHandle = (VOID *)DevCorePtr;
+  return Status;
+}
+
+/**
+  This function is used to de-initialize the device controller
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @flags: Flags indicating what type of de-initialization is required
+
+**/
+EFI_STATUS
+UsbDeviceDeinit (
+  IN VOID      *DevCoreHandle,
+  IN UINT32    Flags
+  )
+{
+  USB_DEV_CORE    *Core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS      Status = EFI_DEVICE_ERROR;
+
+  if (Core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (Core->CoreDriver != NULL) {
+      Status = Core->CoreDriver->DevCoreDeinit(
+                                    Core->ControllerHandle,
+                                    Flags
+                                    );
+      FreePool(DevCoreHandle);
+    } else {
+      DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: Driver not found\n"));
+      Status = EFI_INVALID_PARAMETER;
+    }
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to register callback function for
+  specified event
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @event: Event for which callback is to be registered
+  @callbackFn: Callback function to be called by the
+  controller driver for above event after critical processing
+
+**/
+EFI_STATUS
+UsbDeviceRegisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+
+  DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback start\n"));
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      DEBUG ((DEBUG_INFO, "Call DevCoreRegisterCallback\n"));
+      Status = core->CoreDriver->DevCoreRegisterCallback (
+                                    core->ControllerHandle,
+                                    EventId,
+                                    CallbackFunc
+                                    );
+    }
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to register callback function for
+  specified event
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @eventId: Event for which callback is to be unregistered
+
+**/
+EFI_STATUS
+UsbDeviceUnregisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId
+  )
+{
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceUnregisterCallback: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      Status = core->CoreDriver->DevCoreUnregisterCallback(
+                                    core->ControllerHandle,
+                                    EventId
+                                    );
+    }
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to service interrupt events on device
+  controller. Use this API in your OS/stack-specific ISR framework
+  In polled mode scenario, invoke this API in a loop to service the
+  events
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceIsrRoutine (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      Status = core->CoreDriver->DevCoreIsrRoutine (core->ControllerHandle);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  This function is used to service interrupt events on device
+  controller. Use this API in your OS/stack-specific ISR framework
+  In polled mode scenario, invoke this API in a loop to service the
+  events
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceIsrRoutineTimerBased (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID HANDLE\n"));
+  } else {
+    if (core->CoreDriver != NULL) {
+      Status = core->CoreDriver->DevCoreIsrRoutineTimerBased (core->ControllerHandle);
+    }
+  }
+
+  return Status;
+}
+
+
+/**
+  This function is used to enable device controller to connect
+  to USB host
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbXdciDeviceConnect (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect: ERROR: INVALID HANDLE\n"));
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect\n"));
+    Status = core->CoreDriver->DevCoreConnect (core->ControllerHandle);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to disconnect device controller
+  from USB host
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceDisconnect (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core =(USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect: ERROR: INVALID HANDLE\n"));
+  } else {
+    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect\n"));
+    Status = core->CoreDriver->DevCoreDisconnect(core->ControllerHandle);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to obtain USB bus Speed after bus reset complete
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @Speed: negotiated Speed
+
+**/
+EFI_STATUS
+UsbDeviceGetSpeed (
+  IN VOID                      *DevCoreHandle,
+  IN USB_SPEED                 *Speed
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceGetSpeed: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreGetSpeed(core->ControllerHandle, Speed);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to set USB device address
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @address: USB device address to set
+
+**/
+EFI_STATUS
+UsbDeviceSetAddress (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    Address
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: enter......\n"));
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreSetAddress(core->ControllerHandle, Address);
+  }
+  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: exit......\n"));
+
+  return Status;
+}
+
+/**
+  This function is used to do device controller-specific processing
+  of set configuration device framework request
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @ConfigNum: configuration number selected by USB host
+
+**/
+EFI_STATUS
+UsbDeviceSetConfiguration (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    ConfigNum
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceSetConfiguration: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreSetConfig (core->ControllerHandle, ConfigNum);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to set desired link state in device controller
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @state: Desired link state
+
+**/
+EFI_STATUS
+UsbDeviceSetLinkState (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE  State
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceSetLinkState: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreSetLinkState (core->ControllerHandle, State);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to initialize non-EP0 endpoints
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be initialized
+
+**/
+EFI_STATUS
+UsbDeviceInitEp (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceInitEp: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreInitEp (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to enable an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be enabled
+
+**/
+EFI_STATUS
+UsbDeviceEpEnable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable: ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpEnable (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to disable an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be disabled
+
+**/
+EFI_STATUS
+UsbDeviceEpDisable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpDisable ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpDisable (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to STALL an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP to be stalled
+
+**/
+EFI_STATUS
+UsbDeviceEpStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpStall ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpStall (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to clear STALL on an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for which STALL needs to be cleared
+
+**/
+EFI_STATUS
+UsbDeviceEpClearStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpClearStall ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpClearStall (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to set EP not ready state
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint information for EP that needs to be
+  set in not ready state
+
+**/
+EFI_STATUS
+UsbDeviceEpSetNrdy (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpSetNrdy ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpSetNrdy (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue request to receive SETUP packet
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @Buffer: Buffer (bus-width aligned) where SETUP packet
+  needs to be received
+
+**/
+EFI_STATUS
+UsbDeviceEp0RxSetup (
+  IN VOID                      *DevCoreHandle,
+  IN UINT8                     *Buffer
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxSetup ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEp0RxSetupPkt (core->ControllerHandle, Buffer);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue request to receive status phase
+  for control transfer on EP0
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceEp0RxStatus (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxStatus ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEp0RxStatusPkt (core->ControllerHandle);
+  }
+  return Status;
+}
+
+/**
+  This function is used to queue request to send status phase for
+  control transfer on EP0
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+
+**/
+EFI_STATUS
+UsbDeviceEp0TxStatus (
+  IN VOID                      *DevCoreHandle
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEp0TxStatus ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEp0TxStatusPkt (core->ControllerHandle);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue a single request to transmit data on
+  an endpoint. If more than one request need to be queued before
+  previous requests complete then a request queue needs to be
+  implemented in upper layers. This API should be not be invoked until
+  current request completes.
+  Callback for transfer completion is invoked when requested transfer length
+  is reached or if a short packet is received
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @XferReq: Address to transfer request describing this transfer
+
+**/
+EFI_STATUS
+UsbXdciDeviceEpTxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpTxData ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpTxData (core->ControllerHandle, XferReq);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to queue a single request to receive data on
+  an endpoint. If more than one request need to be queued before
+  previous requests complete then a request queue needs to be implemented
+  in upper layers. This API should be not be invoked until current request
+  completes.
+  Callback for transfer completion is invoked when requested transfer length
+  is reached or if a short packet is received
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @XferReq: Address to transfer request describing this transfer
+
+**/
+EFI_STATUS
+UsbXdciDeviceEpRxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpRxData ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpRxData (core->ControllerHandle, XferReq);
+  }
+
+  return Status;
+}
+
+/**
+  This function is used to cancel a transfer request that was
+  previously queued on an endpoint
+  @DevCoreHandle: Handle to HW-independent APIs for device
+  controller
+  @EpInfo: Endpoint info where transfer needs to be cancelled
+
+**/
+EFI_STATUS
+UsbDeviceEpCancelTransfer (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  )
+{
+  USB_DEV_CORE  *core = (USB_DEV_CORE *)DevCoreHandle;
+  EFI_STATUS    Status = EFI_DEVICE_ERROR;
+
+  if (core == NULL) {
+    DEBUG ((DEBUG_INFO, "UsbDeviceEpCancelTransfer ERROR: INVALID HANDLE\n"));
+  } else {
+    Status = core->CoreDriver->DevCoreEpCancelTransfer (core->ControllerHandle, EpInfo);
+  }
+
+  return Status;
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
new file mode 100644
index 0000000000..a10ec61732
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
@@ -0,0 +1,184 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 _USB_DEVICE_H_
+#define _USB_DEVICE_H_
+
+//
+// @USB_DEV_CONFIG_PARAMS: Struct to be filled in with configuration
+// parameters and passed to the init routine for device controller
+//
+typedef struct {
+  USB_CONTROLLER_ID  ControllerId; // Controller ID of the core
+  UINT32             BaseAddress;  // Base address of the controller registers and on-chip memory
+  UINT32             Flags;        // Initialization flags
+  USB_SPEED          Speed;        // Desired USB bus Speed
+  USB_ROLE           Role;         // Default USB role
+} USB_DEV_CONFIG_PARAMS;
+
+//
+// @USB_DEV_CORE: Struct used as a handle for all
+// hardware-independent APIs
+//
+typedef struct {
+  const struct UsbDeviceCoreDriver *CoreDriver;
+  VOID                                *ControllerHandle;
+} USB_DEV_CORE;
+
+typedef
+EFI_STATUS
+(EFIAPI *USB_DEVICE_CALLBACK_FUNC) (
+  IN USB_DEVICE_CALLBACK_PARAM  *Param
+  );
+
+EFI_STATUS
+UsbDeviceInit (
+  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
+  IN OUT VOID                 **DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceDeinit (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    Flags
+  );
+
+EFI_STATUS
+UsbDeviceRegisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
+  );
+
+EFI_STATUS
+UsbDeviceUnregisterCallback (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_EVENT_ID       EventId
+  );
+
+EFI_STATUS
+UsbDeviceIsrRoutine (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceIsrRoutineTimerBased (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbXdciDeviceConnect (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceDisconnect (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceGetSpeed (
+  IN VOID                      *DevCoreHandle,
+  IN USB_SPEED                 *Speed
+  );
+
+EFI_STATUS
+UsbDeviceSetLinkState (
+  IN VOID                      *DevCoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE  State
+  );
+
+EFI_STATUS
+UsbDeviceSetAddress (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    Address
+  );
+
+EFI_STATUS
+UsbDeviceSetConfiguration (
+  IN VOID                      *DevCoreHandle,
+  IN UINT32                    ConfigNum
+  );
+
+EFI_STATUS
+UsbDeviceInitEp (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpEnable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpDisable (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpClearStall (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEpSetNrdy (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+EFI_STATUS
+UsbDeviceEp0RxSetup (
+  IN VOID                      *DevCoreHandle,
+  IN UINT8                     *Buffer
+  );
+
+EFI_STATUS
+UsbDeviceEp0RxStatus (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbDeviceEp0TxStatus (
+  IN VOID                      *DevCoreHandle
+  );
+
+EFI_STATUS
+UsbXdciDeviceEpTxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  );
+
+EFI_STATUS
+UsbXdciDeviceEpRxData (
+  IN VOID                      *DevCoreHandle,
+  IN USB_XFER_REQUEST          *XferReq
+  );
+
+EFI_STATUS
+UsbDeviceEpCancelTransfer (
+  IN VOID                      *DevCoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
new file mode 100644
index 0000000000..75ce0ecab3
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
@@ -0,0 +1,241 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 _USB_DCD_IF_H_
+#define _USB_DCD_IF_H_
+
+/* Core driver for device controller
+ * @DevCoreInit: Intializes device controller
+ * @DevCoreDeinit: De-initializes device controller
+ * @DevCoreRegisterCallback: Registers callback function for
+ * an event to be called by the controller driver
+ * @DevCoreUnregisterCallback: Unregisters callback function
+ * for an event
+ * @DevCoreIsrRoutine: core interrupt service routine for
+ * device controller to be used by OS/stack-i/f layer
+ * @DevCoreConnect: Enable device controller to connect to USB host
+ * @DevCoreDisconnect: Soft disconnect device controller from
+ * USB host
+ * @DevCoreGetSpeed: Get USB bus Speed on which device controller
+ * is attached
+ * @DevCoreSetAddress: Set USB device address in device controller
+ * @DevCoreSetConfig: Set configuration number for device controller
+ * @DevCoreSetLinkState: Set link state for device controller
+ * @DevCoreInitEp: Initialize non-EP0 endpoint
+ * @DevCoreEpEnable: Enable endpoint
+ * @DevCoreEpDisable: Disable endpoint
+ * @DevCoreEpStall: Stall/Halt endpoint
+ * @DevCoreEpClearStall: Clear Stall/Halt on endpoint
+ * @DevCoreEpSetNrdy: Set endpoint to not ready state
+ * @DevCoreEp0RxSetupPkt: Receive SETUP packet on EP0
+ * @DevCoreEp0RxStatusPkt: Receive status packet on EP0
+ * @DevCoreEp0TxStatusPkt: Transmit status packet from EP0
+ * @DevCoreEpTxData: Transmit data from EP
+ * @DevCoreEpRxData: Received data on EP
+ * @DevCoreEpCancelTransfer: Cancel transfer on EP
+ */
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_INIT) (
+  IN USB_DEV_CONFIG_PARAMS     *ConfigParams,
+  IN VOID                      *ParentHandle,
+  IN VOID                      **CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_DEINIT) (
+  IN VOID                      *CoreHandle,
+  IN UINT32                    Flags
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_REG_CALLBACK) (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event,
+  IN USB_DEVICE_CALLBACK_FUNC  CallbackFn
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_UNREG_CALLBACK) (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_EVENT_ID       Event
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_ISR_ROUTINE) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_CONNECT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_DISCONNECT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_GET_SPEED) (
+  IN VOID                      *CoreHandle,
+  IN USB_SPEED                 *Speed
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_SET_ADDRESS) (
+  IN VOID                      *CoreHandle,
+  IN UINT32                    Address
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_SET_CONFIG) (
+  IN VOID                      *CoreHandle,
+  IN UINT32                    ConfigNum
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_SET_LINK_STATE) (
+  IN VOID                      *CoreHandle,
+  IN USB_DEVICE_SS_LINK_STATE  State
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_INIT_EP) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_ENABLE) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_DISABLE) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_STALL) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_CLEAR_STALL) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_SET_NRDY) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP0_RX_SETUP_PKT) (
+  IN VOID                      *CoreHandle,
+  IN UINT8                     *Buffer
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP0_RX_STATUS_PKT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP0_TX_STATUS_PKT) (
+  IN VOID                      *CoreHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_TX_DATA) (
+  IN VOID                      *CoreHandle,
+  IN USB_XFER_REQUEST          *XferHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_RX_DATA) (
+  IN VOID                      *CoreHandle,
+  IN USB_XFER_REQUEST          *XferHandle
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEV_CORE_EP_CANCEL_TRANSFER) (
+  IN VOID                      *CoreHandle,
+  IN USB_EP_INFO               *EpInfo
+  );
+
+struct UsbDeviceCoreDriver {
+  DEV_CORE_INIT                 DevCoreInit;
+  DEV_CORE_DEINIT               DevCoreDeinit;
+  DEV_CORE_REG_CALLBACK         DevCoreRegisterCallback;
+  DEV_CORE_UNREG_CALLBACK       DevCoreUnregisterCallback;
+  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutine;
+  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutineTimerBased;
+  DEV_CORE_CONNECT              DevCoreConnect;
+  DEV_CORE_DISCONNECT           DevCoreDisconnect;
+  DEV_CORE_GET_SPEED            DevCoreGetSpeed;
+  DEV_CORE_SET_ADDRESS          DevCoreSetAddress;
+  DEV_CORE_SET_CONFIG           DevCoreSetConfig;
+  DEV_CORE_SET_LINK_STATE       DevCoreSetLinkState;
+  DEV_CORE_INIT_EP              DevCoreInitEp;
+  DEV_CORE_EP_ENABLE            DevCoreEpEnable;
+  DEV_CORE_EP_DISABLE           DevCoreEpDisable;
+  DEV_CORE_EP_STALL             DevCoreEpStall;
+  DEV_CORE_EP_CLEAR_STALL       DevCoreEpClearStall;
+  DEV_CORE_EP_SET_NRDY          DevCoreEpSetNrdy;
+  DEV_CORE_EP0_RX_SETUP_PKT     DevCoreEp0RxSetupPkt;
+  DEV_CORE_EP0_RX_STATUS_PKT    DevCoreEp0RxStatusPkt;
+  DEV_CORE_EP0_TX_STATUS_PKT    DevCoreEp0TxStatusPkt;
+  DEV_CORE_EP_TX_DATA           DevCoreEpTxData;
+  DEV_CORE_EP_RX_DATA           DevCoreEpRxData;
+  DEV_CORE_EP_CANCEL_TRANSFER   DevCoreEpCancelTransfer;
+};
+
+//
+// This API is used to obtain the driver handle for HW-independent API
+// @id: The ID of the core for which this driver is requested
+//
+const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(
+  USB_CONTROLLER_ID id);
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
new file mode 100644
index 0000000000..97a97db3db
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
@@ -0,0 +1,55 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 <Library/UsbDeviceLib.h>
+#include "XdciCommon.h"
+#include "XdciDevice.h"
+#include "XdciInterface.h"
+#include "XdciDWC.h"
+#include "UsbDeviceMode.h"
+
+static const struct UsbDeviceCoreDriver CoreDriverTbl[USB_CORE_ID_MAX] = {
+  DwcXdciCoreInit,
+  DwcXdciCoreDeinit,
+  DwcXdciCoreRegisterCallback,
+  DwcXdciCoreUnregisterCallback,
+  DwcXdciCoreIsrRoutine,
+  DwcXdciCoreIsrRoutineTimerBased,
+  DwcXdciCoreConnect,
+  DwcXdciCoreDisconnect,
+  DwcXdciCoreGetSpeed,
+  DwcXdciCoreSetAddress,
+  DwcXdciCoreSetConfig,
+  DwcXdciSetLinkState,
+  DwcXdciInitEp,
+  DwcXdciEpEnable,
+  DwcXdciEpDisable,
+  DwcXdciEpStall,
+  DwcXdciEpClearStall,
+  DwcXdciEpSetNrdy,
+  DwcXdciEp0ReceiveSetupPkt,
+  DwcXdciEp0ReceiveStatusPkt,
+  DwcXdciEp0SendStatusPkt,
+  DwcXdciEpTxData,
+  DwcXdciEpRxData,
+  DwcXdciEpCancelTransfer
+};
+
+const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(USB_CONTROLLER_ID id)
+{
+  if (id >= USB_CORE_ID_MAX)
+    return NULL;
+
+  return &CoreDriverTbl[id];
+}
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
new file mode 100644
index 0000000000..2e02475cd0
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
@@ -0,0 +1,148 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 "XdciUtility.h"
+
+VOID
+PrintDeviceDescriptor (
+  IN USB_DEVICE_DESCRIPTOR    *DevDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Device Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", DevDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", DevDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "BcdUSB            : 0x%x\n", DevDesc->BcdUSB));
+  DEBUG ((DEBUG_INFO, "DeviceClass       : 0x%x\n", DevDesc->DeviceClass));
+  DEBUG ((DEBUG_INFO, "DeviceSubClass    : 0x%x\n", DevDesc->DeviceSubClass));
+  DEBUG ((DEBUG_INFO, "DeviceProtocol    : 0x%x\n", DevDesc->DeviceProtocol));
+  DEBUG ((DEBUG_INFO, "MaxPacketSize0    : 0x%x\n", DevDesc->MaxPacketSize0));
+  DEBUG ((DEBUG_INFO, "IdVendor          : 0x%x\n", DevDesc->IdVendor));
+  DEBUG ((DEBUG_INFO, "IdProduct         : 0x%x\n", DevDesc->IdProduct));
+  DEBUG ((DEBUG_INFO, "BcdDevice         : 0x%x\n", DevDesc->BcdDevice));
+  DEBUG ((DEBUG_INFO, "StrManufacturer   : 0x%x\n", DevDesc->StrManufacturer));
+  DEBUG ((DEBUG_INFO, "StrProduct        : 0x%x\n", DevDesc->StrProduct));
+  DEBUG ((DEBUG_INFO, "StrSerialNumber   : 0x%x\n", DevDesc->StrSerialNumber));
+  DEBUG ((DEBUG_INFO, "NumConfigurations : 0x%x\n", DevDesc->NumConfigurations));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintConfigDescriptor (
+  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Configuration Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length             : 0x%x\n", ConfigDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType     : 0x%x\n", ConfigDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "TotalLength        : 0x%x\n", ConfigDesc->TotalLength));
+  DEBUG ((DEBUG_INFO, "NumInterfaces      : 0x%x\n", ConfigDesc->NumInterfaces));
+  DEBUG ((DEBUG_INFO, "ConfigurationValue : 0x%x\n", ConfigDesc->ConfigurationValue));
+  DEBUG ((DEBUG_INFO, "Configuration      : 0x%x\n", ConfigDesc->Configuration));
+  DEBUG ((DEBUG_INFO, "Attributes         : 0x%x\n", ConfigDesc->Attributes));
+  DEBUG ((DEBUG_INFO, "MaxPower           : 0x%x\n", ConfigDesc->MaxPower));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintInterfaceDescriptor (
+  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Interface Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", IfDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", IfDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "InterfaceNumber   : 0x%x\n", IfDesc->InterfaceNumber));
+  DEBUG ((DEBUG_INFO, "AlternateSetting  : 0x%x\n", IfDesc->AlternateSetting));
+  DEBUG ((DEBUG_INFO, "NumEndpoints      : 0x%x\n", IfDesc->NumEndpoints));
+  DEBUG ((DEBUG_INFO, "InterfaceClass    : 0x%x\n", IfDesc->InterfaceClass));
+  DEBUG ((DEBUG_INFO, "InterfaceSubClass : 0x%x\n", IfDesc->InterfaceSubClass));
+  DEBUG ((DEBUG_INFO, "InterfaceProtocol : 0x%x\n", IfDesc->InterfaceProtocol));
+  DEBUG ((DEBUG_INFO, "Interface         : 0x%x\n", IfDesc->Interface));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintEpDescriptor (
+  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Endpoint Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length          : 0x%x\n", EpDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType  : 0x%x\n", EpDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "EndpointAddress : 0x%x\n", EpDesc->EndpointAddress));
+  DEBUG ((DEBUG_INFO, "Attributes      : 0x%x\n", EpDesc->Attributes));
+  DEBUG ((DEBUG_INFO, "MaxPacketSize   : 0x%x\n", EpDesc->MaxPacketSize));
+  DEBUG ((DEBUG_INFO, "Interval        : 0x%x\n", EpDesc->Interval));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintEpCompDescriptor (
+  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Endpoint Companion Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", EpDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", EpDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "MaxBurst         : 0x%x\n", EpDesc->MaxBurst));
+  DEBUG ((DEBUG_INFO, "Attributes       : 0x%x\n", EpDesc->Attributes));
+  DEBUG ((DEBUG_INFO, "BytesPerInterval : 0x%x\n", EpDesc->BytesPerInterval));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintStringDescriptor (
+  IN USB_STRING_DESCRIPTOR    *StrDesc
+  )
+{
+  UINT16 StrLen = 0;
+
+  if (StrDesc->Length > 2) {
+    StrLen = ((StrDesc->Length - 2) >> 1);
+    DEBUG ((DEBUG_INFO, "--- String Descriptor ---\n"));
+    DEBUG ((DEBUG_INFO, "Length         : 0x%x\n", StrDesc->Length));
+    DEBUG ((DEBUG_INFO, "DescriptorType : 0x%x\n", StrDesc->DescriptorType));
+    DEBUG ((DEBUG_INFO, "String         : %s\n",   StrDesc->LangID));
+  }
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+VOID
+PrintDeviceRequest (
+  IN EFI_USB_DEVICE_REQUEST    *DevReq
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- Device Request ---\n"));
+  DEBUG ((DEBUG_INFO, "RequestType : 0x%x\n", DevReq->RequestType));
+  DEBUG ((DEBUG_INFO, "Request     : 0x%x\n", DevReq->Request));
+  DEBUG ((DEBUG_INFO, "Value       : 0x%x\n", DevReq->Value));
+  DEBUG ((DEBUG_INFO, "Index       : 0x%x\n", DevReq->Index));
+  DEBUG ((DEBUG_INFO, "Length      : 0x%x\n", DevReq->Length));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+
+#ifdef SUPPORT_SUPER_SPEED
+VOID
+PrintBOSDescriptor (
+  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
+  )
+{
+  DEBUG ((DEBUG_INFO, "--- BOS Descriptor ---\n"));
+  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", BosDesc->Length));
+  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", BosDesc->DescriptorType));
+  DEBUG ((DEBUG_INFO, "TotalLength      : 0x%x\n", BosDesc->TotalLength));
+  DEBUG ((DEBUG_INFO, "NumDeviceCaps    : 0x%x\n", BosDesc->NumDeviceCaps));
+  DEBUG ((DEBUG_INFO, "\n"));
+}
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
new file mode 100644
index 0000000000..e3d004e579
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
@@ -0,0 +1,62 @@
+/** @file
+  Copyright (c) 2006 - 2017, Intel Corporation. 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 _XDCI_UTILITY_H_
+#define _XDCI_UTILITY_H_
+
+#include <Library/UsbDeviceLib.h>
+
+VOID
+PrintDeviceDescriptor (
+  IN USB_DEVICE_DESCRIPTOR    *DevDesc
+  );
+
+VOID
+PrintConfigDescriptor (
+  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
+  );
+
+VOID
+PrintInterfaceDescriptor (
+  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
+  );
+
+VOID
+PrintEpDescriptor (
+  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
+  );
+
+VOID
+PrintEpCompDescriptor (
+  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
+  );
+
+VOID
+PrintStringDescriptor (
+  IN USB_STRING_DESCRIPTOR    *StrDesc
+  );
+
+VOID
+PrintDeviceRequest (
+  IN EFI_USB_DEVICE_REQUEST    *DevReq
+  );
+
+#ifdef SUPPORT_SUPER_SPEED
+VOID
+PrintBOSDescriptor (
+  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
+  );
+#endif
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
new file mode 100644
index 0000000000..fe5f3bcd03
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
@@ -0,0 +1,323 @@
+/** @file
+  Copyright (c) 2009 - 2016, Intel Corporation. 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 _EFI_XDCI_LIB_H_
+#define _EFI_XDCI_LIB_H_
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/UsbIo.h>
+
+#define MAX_DESCRIPTOR_SIZE         64
+#define STRING_ARR_SIZE             (MAX_DESCRIPTOR_SIZE - 2)
+#define USB_ADDRESS_TABLE_SIZE      16  //4
+
+//
+// Endpoint Zero
+//
+#define USB_EP0_MAX_PKT_SIZE_HS     0x40 // High Speed mode is explicitly set as 64 bytes
+#define USB_EP0_MAX_PKT_SIZE_SS     0x9  // Must be 0x9 (2^9 = 512 Bytes) in SuperSpeed mode
+#define USB_EPO_MAX_PKT_SIZE_ALL    512  // Overall max bytes for any type
+
+//
+// Bulk Endpoints
+//
+#define USB_BULK_EP_PKT_SIZE_HS     0x200 // Bulk-Endpoint HighSpeed
+#define USB_BULK_EP_PKT_SIZE_SS     0x400 // Bulk-Endpoint SuperSpeed
+#define USB_BULK_EP_PKT_SIZE_MAX    USB_BULK_EP_PKT_SIZE_SS
+
+//
+// Transmit Direction Bits
+//
+#define USB_ENDPOINT_DIR_OUT                 0x00
+
+//
+// Endpoint Companion Bulk Attributes
+//
+#define USB_EP_BULK_BM_ATTR_MASK    0x1F
+
+//
+// Configuration Modifiers (Attributes)
+//
+#define USB_BM_ATTR_RESERVED        0x80
+#define USB_BM_ATTR_SELF_POWERED    0x40
+#define USB_BM_ATTR_REMOTE_WAKE     0X20
+
+//
+// USB BCD version
+//
+#define USB_BCD_VERSION_LS          0x0110
+#define USB_BCD_VERSION_HS          0x0200
+#define USB_BCD_VERSION_SS          0x0300
+
+//
+// Device RequestType Flags
+//
+#define USB_RT_TX_DIR_H_TO_D        (0x0)       // Tx direction Host to Device
+#define USB_RT_TX_DIR_D_TO_H        (0x1 << 7)  // Tx direction Device to Host
+#define USB_RT_TX_DIR_MASK          (0x80)
+
+//
+// USB request type
+//
+#define USB_REQ_TYPE_MASK           (0x60)
+
+//
+// Usb control transfer target
+//
+#define USB_TARGET_MASK             (0x1F)
+
+//
+// Device GetStatus bits
+//
+#define USB_STATUS_SELFPOWERED      (0x01)
+#define USB_STATUS_REMOTEWAKEUP     (0x02)
+
+//
+// USB Device class identifiers
+//
+#define USB_DEVICE_MS_CLASS         (0x08)
+#define USB_DEVICE_VENDOR_CLASS     (0xFF)
+
+//
+// USB Descriptor types
+//
+#define USB_DESC_TYPE_BOS                    0x0F
+#define USB_DESC_TYPE_DEVICE_CAPABILITY      0x10
+#define USB_DESC_TYPE_SS_ENDPOINT_COMPANION  0x30
+
+#ifdef SUPPORT_SUPER_SPEED
+//
+// USB device capability Type Codes
+// USB3 Table 9-13
+//
+typedef enum {
+  WirelessUSB = 0x01,
+  USB2Extension,
+  SuperSpeedUSB,
+  ContainerID,
+  SuperSpeedPlusUSB = 0x0A
+} USB_DEVICE_CAP_TYPE_CODE;
+#endif
+
+//
+// USB device states from USB spec sec 9.1
+//
+typedef enum {
+  UsbDevStateOff = 0,
+  UsbDevStateInit,
+  UsbDevStateAttached,
+  UsbDevStatePowered,
+  UsbDevStateDefault,
+  UsbDevStateAddress,
+  UsbDevStateConfigured,
+  UsbDevStateSuspended,
+  UsbDevStateError
+} USB_DEVICE_STATE;
+
+//
+// The following set of structs are used during USB data transaction
+// operatitions, including requests and completion events.
+//
+#pragma pack(1)
+
+typedef struct {
+  UINT32     EndpointNum;
+  UINT8      EndpointDir;
+  UINT8      EndpointType;
+  UINT32     Length;
+  VOID       *Buffer;
+} EFI_USB_DEVICE_XFER_INFO;
+
+//
+// SuperSpeed Endpoint companion descriptor
+// USB3 table 9-22
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      MaxBurst;
+  UINT8      Attributes;
+  UINT16     BytesPerInterval;
+} EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR;
+
+typedef struct {
+  EFI_USB_ENDPOINT_DESCRIPTOR              *EndpointDesc;
+  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EndpointCompDesc;
+} USB_DEVICE_ENDPOINT_INFO, USB_DEVICE_ENDPOINT_OBJ;
+
+typedef struct {
+  VOID        *Buffer;
+  UINT32      Length;
+} USB_DEVICE_IO_INFO;
+
+typedef struct {
+  USB_DEVICE_IO_INFO           IoInfo;
+  USB_DEVICE_ENDPOINT_INFO     EndpointInfo;
+} USB_DEVICE_IO_REQ;
+
+//
+// Optional string descriptor
+//
+typedef struct {
+  UINT8           Length;
+  UINT8           DescriptorType;
+  UINT16          LangID[STRING_ARR_SIZE];
+} USB_STRING_DESCRIPTOR;
+
+//
+// The following structures abstract the device descriptors a class
+// driver needs to provide to the USBD core.
+// These structures are filled & owned by the class/function layer.
+//
+typedef struct {
+  EFI_USB_INTERFACE_DESCRIPTOR         *InterfaceDesc;
+  USB_DEVICE_ENDPOINT_OBJ              *EndpointObjs;
+} USB_DEVICE_INTERFACE_OBJ;
+
+typedef struct {
+  EFI_USB_CONFIG_DESCRIPTOR     *ConfigDesc;
+  VOID                          *ConfigAll;
+  USB_DEVICE_INTERFACE_OBJ      *InterfaceObjs;
+} USB_DEVICE_CONFIG_OBJ;
+
+#ifdef SUPPORT_SUPER_SPEED
+//
+// SuperSpeed Binary Device Object Store(BOS) descriptor
+// USB3 9.6.2
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT16     TotalLength;
+  UINT8      NumDeviceCaps;
+} EFI_USB_BOS_DESCRIPTOR;
+
+//
+// Generic Header of Device Capability descriptor
+// USB3 9.6.2.2
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DevCapabilityType;
+  UINT8      CapDependent;
+} EFI_USB_SS_DEVICE_CAP_DESCRIPTOR;
+
+//
+// USB2.0 Extension descriptor
+// USB3 Table 9-14
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT32     Attributes;
+} EFI_USB_USB2_EXT_CAP_DESCRIPTOR;
+
+//
+// SuperSpeed USB Device Capability descriptor
+// USB3 Table 9-15
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT8      Attributes;
+  UINT16     SpeedSupported;
+  UINT8      FunctionalitySupport;
+  UINT8      U1DevExitLat;
+  UINT16     U2DevExitLat;
+} EFI_USB_SS_USB_DEV_CAP_DESCRIPTOR;
+
+//
+// Container ID descriptor
+// USB3 Table 9-16
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT8      Reserved;
+  UINT8      UUID[16];
+} EFI_USB_CONTAINER_ID_DESCRIPTOR;
+
+//
+// Container ID descriptor
+// USB3 Table 9-16
+//
+typedef struct {
+  UINT8      Length;
+  UINT8      DescriptorType;
+  UINT8      DeviceCapabilityType;
+  UINT8      ReservedByte;
+  UINT32     Attributes;
+  UINT16     FunctionalitySupport;
+  UINT16     ReservedWord;
+  UINT32     SublinkSpeedAttr[2];
+} EFI_USB_SS_PLUS_USB_DEV_CAP_DESCRIPTOR;
+
+#endif
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_CONFIG_CALLBACK) (
+  IN UINT8                      CfgVal
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_SETUP_CALLBACK) (
+  IN EFI_USB_DEVICE_REQUEST     *CtrlRequest,
+  IN USB_DEVICE_IO_INFO         *IoInfo
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DATA_CALLBACK) (
+  IN EFI_USB_DEVICE_XFER_INFO   *XferInfo
+  );
+
+typedef struct {
+  USB_DEVICE_DESCRIPTOR       *DeviceDesc;
+  USB_DEVICE_CONFIG_OBJ       *ConfigObjs;
+  USB_STRING_DESCRIPTOR       *StringTable;
+#ifdef SUPPORT_SUPER_SPEED
+  EFI_USB_BOS_DESCRIPTOR      *BosDesc;
+#endif
+  UINT8                       StrTblEntries;
+  EFI_USB_CONFIG_CALLBACK     ConfigCallback;
+  EFI_USB_SETUP_CALLBACK      SetupCallback;
+  EFI_USB_DATA_CALLBACK       DataCallback;
+} USB_DEVICE_OBJ;
+
+//
+// Main USBD driver object structure containing all data necessary
+// for USB device mode processing at this layer
+//
+typedef struct {
+  USB_DEVICE_OBJ              *UsbdDevObj;      /* pointer to a Device Object */
+  VOID                        *XdciDrvObj;      /* Opaque handle to XDCI driver */
+  BOOLEAN                     XdciInitialized;  /* flag to specify if the XDCI driver is initialized */
+  USB_DEVICE_CONFIG_OBJ       *ActiveConfigObj; /* pointer to currently active configuraiton */
+  USB_DEVICE_STATE            State;            /* current state of the USB Device state machine */
+  UINT8                       Address;          /* configured device address */
+} USB_DEVICE_DRIVER_OBJ;
+
+#pragma pack()
+
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
new file mode 100644
index 0000000000..97f276f1cc
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
@@ -0,0 +1,430 @@
+/** @file
+  EFI USB function IO Protocol
+  This protocol supports Usb Function IO API.
+  Copyright (c) 1999 - 2017, Intel Corporation. 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 __EFI_USB_FUNC_IO_H__
+#define __EFI_USB_FUNC_IO_H__
+
+#include <IndustryStandard/Usb.h>
+
+#define EFI_USBFN_IO_PROTOCOL_REVISION   0x00010001
+
+//
+// {32D2963A-FE5D-4f30-B633-6E5DC55803CC}
+// #define EFI_USBFN_IO_PROTOCOL_GUID  {0x32d2963a, 0xfe5d, 0x4f30, 0xb6, 0x33, 0x6e, 0x5d, 0xc5, 0x58, 0x3, 0xcc };
+//
+
+typedef struct _EFI_USBFN_IO_PROTOCOL   EFI_USBFN_IO_PROTOCOL;
+
+//
+// USB standard descriptors and reqeust
+//
+typedef USB_DEVICE_REQUEST        EFI_USB_DEVICE_REQUEST;
+typedef USB_DEVICE_DESCRIPTOR     EFI_USB_DEVICE_DESCRIPTOR;
+typedef USB_CONFIG_DESCRIPTOR     EFI_USB_CONFIG_DESCRIPTOR;
+typedef USB_INTERFACE_DESCRIPTOR  EFI_USB_INTERFACE_DESCRIPTOR;
+typedef USB_ENDPOINT_DESCRIPTOR   EFI_USB_ENDPOINT_DESCRIPTOR;
+
+typedef enum _EFI_USBFN_PORT_TYPE {
+  EfiUsbUnknownPort = 0,
+  EfiUsbStandardDownstreamPort,
+  EfiUsbChargingDownstreamPort,
+  EfiUsbDedicatedChargingPort,
+  EfiUsbInvalidDedicatedChargingPort
+} EFI_USBFN_PORT_TYPE;
+
+/**
+ USB_DEVICE_DESCRIPTOR, USB_CONFIG_DESCRIPTOR, USB_INTERFACE_DESCRIPTOR, and
+ USB_ENDPOINT_DESCRIPTOR are already defined
+ in UEFI spec 2.3, as par USB 2.0 spec.
+**/
+
+typedef struct {
+  EFI_USB_INTERFACE_DESCRIPTOR        *InterfaceDescriptor;
+  EFI_USB_ENDPOINT_DESCRIPTOR         **EndpointDescriptorTable;
+} EFI_USB_INTERFACE_INFO;
+
+typedef struct {
+  EFI_USB_CONFIG_DESCRIPTOR           *ConfigDescriptor;
+  EFI_USB_INTERFACE_INFO              **InterfaceInfoTable;
+} EFI_USB_CONFIG_INFO;
+
+typedef struct {
+  EFI_USB_DEVICE_DESCRIPTOR           *DeviceDescriptor;
+  EFI_USB_CONFIG_INFO                 **ConfigInfoTable;
+} EFI_USB_DEVICE_INFO;
+
+
+typedef enum _EFI_USB_ENDPOINT_TYPE {
+  UsbEndpointControl     = 0x00,
+  UsbEndpointIsochronous = 0x01,
+  UsbEndpointBulk        = 0x02,
+  UsbEndpointInterrupt   = 0x03
+} EFI_USB_ENDPOINT_TYPE;
+
+
+typedef enum _EFI_USBFN_DEVICE_INFO_ID {
+  EfiUsbDeviceInfoUnknown = 0,
+  EfiUsbDeviceInfoSerialNumber,
+  EfiUsbDeviceInfoManufacturerName,
+  EfiUsbDeviceInfoProductName
+} EFI_USBFN_DEVICE_INFO_ID;
+
+
+typedef enum _EFI_USBFN_ENDPOINT_DIRECTION {
+  EfiUsbEndpointDirectionHostOut  = 0,
+  EfiUsbEndpointDirectionHostIn,
+  EfiUsbEndpointDirectionDeviceTx = EfiUsbEndpointDirectionHostIn,
+  EfiUsbEndpointDirectionDeviceRx = EfiUsbEndpointDirectionHostOut
+} EFI_USBFN_ENDPOINT_DIRECTION;
+
+
+typedef enum _EFI_USBFN_MESSAGE {
+  //
+  // Nothing
+  //
+  EfiUsbMsgNone = 0,
+  //
+  // SETUP packet is received, returned Buffer contains
+  // EFI_USB_DEVICE_REQUEST struct
+  //
+  EfiUsbMsgSetupPacket,
+  //
+  // Indicates that some of the requested data has been received from the
+  // host. It is the responsibility of the class driver to determine if it
+  // needs to wait for any remaining data. Returned Buffer contains
+  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
+  // status and count of bytes received.
+  //
+  EfiUsbMsgEndpointStatusChangedRx,
+  //
+  // Indicates that some of the requested data has been transmitted to the
+  // host. It is the responsibility of the class driver to determine if any
+  // remaining data needs to be resent. Returned Buffer contains
+  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number, transfer
+  // status and count of bytes sent.
+  //
+  EfiUsbMsgEndpointStatusChangedTx,
+  //
+  // DETACH bus event signaled
+  //
+  EfiUsbMsgBusEventDetach,
+  //
+  // ATTACH bus event signaled
+  //
+  EfiUsbMsgBusEventAttach,
+  //
+  // RESET bus event signaled
+  //
+  EfiUsbMsgBusEventReset,
+  //
+  // SUSPEND bus event signaled
+  //
+  EfiUsbMsgBusEventSuspend,
+  //
+  // RESUME bus event signaled
+  //
+  EfiUsbMsgBusEventResume,
+  //
+  // Bus speed updated, returned buffer indicated bus speed using
+  // following enumeration named EFI_USB_BUS_SPEED
+  //
+  EfiUsbMsgBusEventSpeed
+} EFI_USBFN_MESSAGE;
+
+
+typedef enum _EFI_USBFN_TRANSFER_STATUS {
+  UsbTransferStatusUnknown = 0,
+  UsbTransferStatusComplete,
+  UsbTransferStatusAborted,
+  UsbTransferStatusActive,
+  UsbTransferStatusNone
+} EFI_USBFN_TRANSFER_STATUS;
+
+
+typedef struct _EFI_USBFN_TRANSFER_RESULT {
+  UINTN                         BytesTransferred;
+  EFI_USBFN_TRANSFER_STATUS     TransferStatus;
+  UINT8                         EndpointIndex;
+  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
+  VOID                          *Buffer;
+} EFI_USBFN_TRANSFER_RESULT;
+
+typedef enum _EFI_USB_BUS_SPEED {
+  UsbBusSpeedUnknown = 0,
+  UsbBusSpeedLow,
+  UsbBusSpeedFull,
+  UsbBusSpeedHigh,
+  UsbBusSpeedSuper,
+  UsbBusSpeedMaximum = UsbBusSpeedSuper
+} EFI_USB_BUS_SPEED;
+
+typedef union _EFI_USBFN_MESSAGE_PAYLOAD {
+  EFI_USB_DEVICE_REQUEST      udr;
+  EFI_USBFN_TRANSFER_RESULT   utr;
+  EFI_USB_BUS_SPEED           ubs;
+} EFI_USBFN_MESSAGE_PAYLOAD;
+
+typedef enum _EFI_USBFN_POLICY_TYPE {
+  EfiUsbPolicyUndefined = 0,
+  EfiUsbPolicyMaxTransactionSize,
+  EfiUsbPolicyZeroLengthTerminationSupport,
+  EfiUsbPolicyZeroLengthTermination
+} EFI_USBFN_POLICY_TYPE;
+
+
+/**
+
+ Allocates transfer buffer of the specified size that satisfies
+ controller requirements.
+
+ The AllocateTransferBuffer function allocates a memory region of Size bytes and
+ returns the address of the allocated memory that satisfies underlying
+ controller requirements in the location referenced by Buffer.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER) (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN UINTN                    Size,
+  OUT VOID                    **Buffer
+  );
+
+/**
+
+  Deallocates the memory allocated for the transfer buffer by AllocateTransferBuffer function.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_FREE_TRANSFER_BUFFER) (
+  IN EFI_USBFN_IO_PROTOCOL    *This,
+  IN VOID                     *Buffer
+  );
+
+/**
+  Returns information about what type of device was attached.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_DETECT_PORT) (
+  IN EFI_USBFN_IO_PROTOCOL   *This,
+  OUT EFI_USBFN_PORT_TYPE    *PortType
+  );
+
+/**
+  Configure endpoints based on supplied device and configuration descriptors.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS) (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN EFI_USB_DEVICE_INFO           *DeviceInfo
+  );
+
+
+/**
+  Returns the maximum packet size of the specified endpoint type for the supplied bus speed.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE) (
+  IN EFI_USBFN_IO_PROTOCOL       *This,
+  IN EFI_USB_ENDPOINT_TYPE       EndpointType,
+  IN EFI_USB_BUS_SPEED           BusSpeed,
+  OUT UINT16                     *MaxPacketSize
+  );
+
+/**
+  Returns the maximum supported transfer size.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_MAXTRANSFER_SIZE) (
+  IN EFI_USBFN_IO_PROTOCOL     *This,
+  OUT UINTN                    *MaxTransferSize
+  );
+
+/**
+  Returns device specific information based on the supplied identifier as a
+  Unicode string.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_DEVICE_INFO) (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  IN EFI_USBFN_DEVICE_INFO_ID   Id,
+  IN OUT UINTN                  *BufferSize,
+  OUT VOID                      *Buffer OPTIONAL
+  );
+
+/**
+  Returns vendor-id and product-id of the device.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID) (
+  IN EFI_USBFN_IO_PROTOCOL      *This,
+  OUT UINT16                    *Vid,
+  OUT UINT16                    *Pid
+  );
+
+/**
+  Aborts transfer on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_ABORT_TRANSFER) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
+  );
+
+/**
+  Returns the stall state on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN OUT BOOLEAN                  *State
+  );
+
+/**
+  Sets or clears the stall state on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN BOOLEAN                      State
+  );
+
+
+/**
+  This function is called repeatedly to receive updates on USB bus states,
+  receive, transmit status changes on endpoints and setup packet on endpoint 0.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_EVENTHANDLER) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  OUT EFI_USBFN_MESSAGE           *Message,
+  IN OUT UINTN                    *PayloadSize,
+  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
+  );
+
+/**
+  Primary function to handle transfer in either direction based on specified
+  direction and on the specified endpoint.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USBFN_IO_TRANSFER) (
+  IN EFI_USBFN_IO_PROTOCOL         *This,
+  IN UINT8                         EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
+  IN OUT UINTN                     *BufferSize,
+  IN OUT VOID                      *Buffer
+  );
+
+/**
+  This function supplies power to the USB controller if needed,
+  initialize hardware and internal data structures, and then return.
+
+  The port must not be activated by this function.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_START_CONTROLLER) (
+    IN EFI_USBFN_IO_PROTOCOL    *This
+    );
+
+/**
+  This function disables the hardware device by resetting the run/stop bit and
+  power off the USB controller if needed.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_STOP_CONTROLLER) (
+    IN EFI_USBFN_IO_PROTOCOL    *This
+    );
+
+/**
+  This function sets the configuration policy for the specified non-control endpoint.
+
+  Refer to the description for calling restrictions.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_POLICY) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN UINTN                        BufferSize,
+  IN VOID                         *Buffer
+  );
+
+/**
+  This function retrieves the configuration policy for the specified non-control endpoint.
+
+  There are no associated calling restrictions for this function.
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_POLICY) (
+  IN EFI_USBFN_IO_PROTOCOL        *This,
+  IN UINT8                        EndpointIndex,
+  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
+  IN EFI_USBFN_POLICY_TYPE        PolicyType,
+  IN OUT UINTN                    *BufferSize,
+  IN OUT VOID                     *Buffer
+  );
+
+
+struct _EFI_USBFN_IO_PROTOCOL {
+  UINT32                                      Revision;
+  EFI_USBFN_IO_DETECT_PORT                    DetectPort;
+  EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS     ConfigureEnableEndpoints;
+  EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE    GetEndpointMaxPacketSize;
+  EFI_USBFN_IO_GET_DEVICE_INFO                GetDeviceInfo;
+  EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID       GetVendorIdProductId;
+  EFI_USBFN_IO_ABORT_TRANSFER                 AbortTransfer;
+  EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE       GetEndpointStallState;
+  EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE       SetEndpointStallState;
+  EFI_USBFN_IO_EVENTHANDLER                   EventHandler;
+  EFI_USBFN_IO_TRANSFER                       Transfer;
+  EFI_USBFN_IO_GET_MAXTRANSFER_SIZE           GetMaxTransferSize;
+  EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER       AllocateTransferBuffer;
+  EFI_USBFN_IO_FREE_TRANSFER_BUFFER           FreeTransferBuffer;
+  //
+  // Valid for version EFI_USBFN_IO_PROTOCOL_REVISION2 and above
+  //
+  EFI_USBFN_IO_START_CONTROLLER               StartController;
+  EFI_USBFN_IO_STOP_CONTROLLER                StopController;
+  EFI_USBFN_IO_SET_ENDPOINT_POLICY            SetEndpointPolicy;
+  EFI_USBFN_IO_GET_ENDPOINT_POLICY            GetEndpointPolicy;
+};
+
+
+extern EFI_GUID gEfiUsbFnIoProtocolGuid;
+#endif
+
diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
new file mode 100644
index 0000000000..c301fa00d3
--- /dev/null
+++ b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
@@ -0,0 +1,104 @@
+/** @file
+  Copyright (c) 1999 - 2017, Intel Corporation. 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 _USB_DEVICE_MODE_PROTOCOL_H_
+#define _USB_DEVICE_MODE_PROTOCOL_H_
+
+#include <Library/UsbDeviceLib.h>
+
+///
+/// UsbDeviceMode Protocol GUID.
+///
+#define EFI_USB_DEVICE_MODE_PROTOCOL_GUID \
+  {0xC9923F7E, 0x1746, 0x4802, { 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 } }
+
+typedef struct _EFI_USB_DEVICE_MODE_PROTOCOL EFI_USB_DEVICE_MODE_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_INIT_XDCI) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_CONNECT) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_DISCONNECT) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_EP_TX_DATA) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_EP_RX_DATA) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_IO_REQ                          *IoRequest
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_BIND) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN USB_DEVICE_OBJ                             *UsbdDevObj
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_UNBIND) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_STOP) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_USB_DEVICE_MODE_RUN) (
+  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
+  IN UINT32                                     TimeoutMs
+  );
+
+///
+/// Usb Device Mode Protocol Structure.
+///
+struct _EFI_USB_DEVICE_MODE_PROTOCOL {
+  EFI_USB_DEVICE_MODE_INIT_XDCI            InitXdci;
+  EFI_USB_DEVICE_MODE_CONNECT              Connect;
+  EFI_USB_DEVICE_MODE_DISCONNECT           DisConnect;
+  EFI_USB_DEVICE_EP_TX_DATA                EpTxData;
+  EFI_USB_DEVICE_EP_RX_DATA                EpRxData;
+  EFI_USB_DEVICE_MODE_BIND                 Bind;
+  EFI_USB_DEVICE_MODE_UNBIND               UnBind;
+  EFI_USB_DEVICE_MODE_RUN                  Run;
+  EFI_USB_DEVICE_MODE_STOP                 Stop;
+};
+
+extern EFI_GUID gEfiUsbDeviceModeProtocolGuid;
+
+#endif
+
-- 
2.27.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#62768): https://edk2.groups.io/g/devel/message/62768
Mute This Topic: https://groups.io/mt/75608954/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list