public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch][edk2-platforms/devel-MinnowBoard3] Add USB peripheral mode
@ 2017-01-22  3:12 Guo, Mang
  2017-01-22  3:33 ` Wei, David
  0 siblings, 1 reply; 2+ messages in thread
From: Guo, Mang @ 2017-01-22  3:12 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Wei, David, Guo, Mang

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Guo Mang <mang.guo@intel.com>
---
 .../Common/Features/UsbDeviceDxe/ComponentName.c   |  305 ++
 .../Common/Features/UsbDeviceDxe/UsbDeviceDxe.c    |  395 ++
 .../Common/Features/UsbDeviceDxe/UsbDeviceDxe.h    |  159 +
 .../Common/Features/UsbDeviceDxe/UsbDeviceDxe.inf  |   74 +
 .../Common/Features/UsbDeviceDxe/UsbDeviceMode.c   | 1489 ++++++++
 .../Common/Features/UsbDeviceDxe/UsbDeviceMode.h   |   39 +
 .../Common/Features/UsbDeviceDxe/UsbFuncIo.c       | 2219 +++++++++++
 .../Common/Features/UsbDeviceDxe/UsbFuncIo.h       |  234 ++
 .../Common/Features/UsbDeviceDxe/UsbIoNode.c       |  177 +
 .../Common/Features/UsbDeviceDxe/UsbIoNode.h       |   90 +
 .../Common/Features/UsbDeviceDxe/XdciCommon.h      |  156 +
 .../Common/Features/UsbDeviceDxe/XdciDWC.c         | 4033 ++++++++++++++++++++
 .../Common/Features/UsbDeviceDxe/XdciDWC.h         |  741 ++++
 .../Common/Features/UsbDeviceDxe/XdciDevice.c      |  695 ++++
 .../Common/Features/UsbDeviceDxe/XdciDevice.h      |  184 +
 .../Common/Features/UsbDeviceDxe/XdciInterface.h   |  241 ++
 .../Common/Features/UsbDeviceDxe/XdciTable.c       |   55 +
 .../Common/Features/UsbDeviceDxe/XdciUtility.c     |  148 +
 .../Common/Features/UsbDeviceDxe/XdciUtility.h     |   62 +
 .../Common/Include/Protocol/EfiUsbFnIo.h           |  430 +++
 .../Include/Protocol/UsbDeviceModeProtocol.h       |  104 +
 .../Common/Library/PmicLib/PmicDummy.c             |  142 +
 .../Common/Library/PmicLib/PmicLibNull.c           |  658 ++++
 .../Common/Library/PmicLib/PmicLibNull.inf         |   44 +
 .../Common/Library/PmicLib/PmicPrivate.h           |   82 +
 .../PlatformSetupDxe/SouthClusterConfig.vfi        |    6 +-
 .../BroxtonPlatformPkg/PlatformDsc/Components.dsc  |    2 +
 .../PlatformDsc/LibraryClasses.dsc                 |    4 +-
 Platform/BroxtonPlatformPkg/PlatformPkg.fdf        |    2 +
 .../SouthCluster/Include/ScRegs/RegsUsb.h          |   10 +-
 30 files changed, 12975 insertions(+), 5 deletions(-)
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/ComponentName.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.inf
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceMode.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceMode.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbFuncIo.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbFuncIo.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbIoNode.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbIoNode.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciCommon.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDWC.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDWC.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDevice.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDevice.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciInterface.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciTable.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciUtility.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciUtility.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Include/Protocol/EfiUsbFnIo.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Include/Protocol/UsbDeviceModeProtocol.h
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicDummy.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.c
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.inf
 create mode 100644 Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicPrivate.h

diff --git a/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/ComponentName.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/ComponentName.c
new file mode 100644
index 0000000..9495806
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.c
new file mode 100644
index 0000000..03bf27d
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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,
+                  &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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.h
new file mode 100644
index 0000000..e300fbf
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.inf b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceDxe.inf
new file mode 100644
index 0000000..46c499a
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceMode.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceMode.c
new file mode 100644
index 0000000..d0358b9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceMode.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbDeviceMode.h
new file mode 100644
index 0000000..5445974
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbFuncIo.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbFuncIo.c
new file mode 100644
index 0000000..9a156ba
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbFuncIo.c
@@ -0,0 +1,2219 @@
+/** @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, &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
+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
+StopController (
+  IN EFI_USBFN_IO_PROTOCOL        *This
+  )
+{
+  return UsbFnDeInitDevice(This);
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbFuncIo.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbFuncIo.h
new file mode 100644
index 0000000..711be07
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbIoNode.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbIoNode.c
new file mode 100644
index 0000000..c51ced5
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbIoNode.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/UsbIoNode.h
new file mode 100644
index 0000000..0ff569b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciCommon.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciCommon.h
new file mode 100644
index 0000000..468e8a8
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDWC.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDWC.c
new file mode 100644
index 0000000..47c5b80
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDWC.c
@@ -0,0 +1,4033 @@
+/** @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"
+
+#pragma optimize ("", off)
+
+UINT32
+UsbRegRead (
+  IN UINT32    Base,
+  IN UINT32    Offset
+  )
+{
+  volatile UINT32 *addr = (volatile UINT32 *)(UINTN)(Base + Offset);
+  return *addr;
+}
+
+VOID
+UsbRegWrite (
+  IN UINT32    Base,
+  IN UINT32    Offset,
+  IN UINT32    val
+  )
+{
+  volatile UINT32 *addr = (volatile UINT32 *)(UINTN)(Base + 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)((UINT32)(UINTN)
+                            LocalCoreHandle->UnalignedTrbs +
+                            (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)((UINT32)(UINTN)
+                            LocalCoreHandle->UnalignedTrbs +
+                            (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;
+}
+#pragma optimize ("", on)
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDWC.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDWC.h
new file mode 100644
index 0000000..3470cfd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDevice.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDevice.c
new file mode 100644
index 0000000..2dcd448
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDevice.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciDevice.h
new file mode 100644
index 0000000..aee6bde
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciInterface.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciInterface.h
new file mode 100644
index 0000000..90264e8
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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 EFI_STATUS                (*callbackFn)(IN USB_DEVICE_CALLBACK_PARAM *CbEventParams)
+  );
+
+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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciTable.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciTable.c
new file mode 100644
index 0000000..31990ae
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciUtility.c b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciUtility.c
new file mode 100644
index 0000000..2a756b9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciUtility.h b/Platform/BroxtonPlatformPkg/Common/Features/UsbDeviceDxe/XdciUtility.h
new file mode 100644
index 0000000..c243a5b
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Features/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/Platform/BroxtonPlatformPkg/Common/Include/Protocol/EfiUsbFnIo.h b/Platform/BroxtonPlatformPkg/Common/Include/Protocol/EfiUsbFnIo.h
new file mode 100644
index 0000000..7b1d4a9
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/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/Platform/BroxtonPlatformPkg/Common/Include/Protocol/UsbDeviceModeProtocol.h b/Platform/BroxtonPlatformPkg/Common/Include/Protocol/UsbDeviceModeProtocol.h
new file mode 100644
index 0000000..bd8d85f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/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
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicDummy.c b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicDummy.c
new file mode 100644
index 0000000..570bc21
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicDummy.c
@@ -0,0 +1,142 @@
+/** @file
+  Dxe library for accessing dummy PMIC registers.
+
+  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.
+
+**/
+
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/PmicLib.h>
+#include "PmicPrivate.h"
+
+/**
+  Reads an 8-bit PMIC register.
+
+  Reads the 8-bit PMIC register specified by Register.
+  The 8-bit read value is returned.
+
+  @param[in]  BaseAddress     - IPC operation address for target PMIC device.
+  @param[in]  Register        - The PMIC register to read.
+
+  @retval 0                   - Function not supported yet.
+**/
+UINT8
+EFIAPI
+DmPmicRead8 (
+  IN UINT8                     BaseAddress,
+  IN UINT8                     Register
+  )
+{
+  return 0x0;
+}
+
+/**
+  Writes an 8-bit PMIC register with a 8-bit value.
+
+  Writes the 8-bit PMIC register specified by Register with the value specified
+  by Value and return the operation status.
+
+  @param[in]  BaseAddress     - IPC operation address for target PMIC device.
+  @param[in]  Register        - The PMIC register to write.
+  @param[in]  Value           - The value to write to the PMIC register.
+
+  @retval EFI_SUCCESS         - Function not supported yet.
+**/
+EFI_STATUS
+EFIAPI
+DmPmicWrite8 (
+  IN UINT8                     BaseAddress,
+  IN UINT8                     Register,
+  IN UINT8                     Value
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  AC/DC Adapter Detection Status
+
+  @retval TRUE                - Connected
+**/
+BOOLEAN
+EFIAPI
+DmPmicIsACOn (
+  VOID
+  )
+{
+  return TRUE;
+}
+
+/**
+  Probe to find the correct PMIC object.
+
+  After probling, g_pmic_obj points to correct PMIC object
+  This routine is invoked when library is loaded .
+
+  @retval TRUE                - Always return true to indicate dummy PMIC existed.
+**/
+BOOLEAN
+EFIAPI
+DmPmicProbe (
+  VOID
+  )
+{
+  DEBUG ((DEBUG_ERROR, "Dummy PMIC detected\n"));
+  return TRUE;
+}
+
+struct PmicObject DmObj = {
+  PMIC_I2C_BUSNO,
+  PMIC_PAGE_0_I2C_ADDR,
+  PMIC_PAGE_0_I2C_ADDR,
+  PMIC_TYPE_DUMMY,
+  DmPmicRead8,
+  DmPmicWrite8,
+
+  DmPmicProbe,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  
+  //
+  //PUPDR interfaces
+  //
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  DmPmicIsACOn,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+};
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.c b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.c
new file mode 100644
index 0000000..b0abe48
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.c
@@ -0,0 +1,658 @@
+/** @file
+  Dxe Library for PMIC public 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.
+
+**/
+
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include "PmicPrivate.h"
+
+
+struct PmicObject *gPmicObj = NULL;
+
+extern struct PmicObject DmObj;
+
+
+struct PmicObject *gPmicSupportList[] = {
+  &DmObj,  //dummy
+};
+
+
+PMIC_TYPE gPmicType = PMIC_TYPE_NONE;   //global flag to record current probed PMIC type. We could use it to avoid probe HW every time in API.
+
+/**
+  Reads an 8-bit PMIC register.
+
+  Reads the 8-bit PMIC register specified by Register.
+  The 8-bit read value is returned.
+
+  @param[in]  BaseAddress     - IPC operation address for target PMIC device.
+  @param[in]  Register        - The PMIC register to read.
+
+  @retval UINT8               - The value read.
+**/
+UINT8
+EFIAPI
+PmicRead8 (
+  IN UINT8                     BaseAddress,
+  IN UINT8                     Register
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicRead8, 0xff)
+  return gPmicObj->PmicRead8(BaseAddress, Register);
+}
+
+/**
+  Writes an 8-bit PMIC register with a 8-bit value.
+
+  Writes the 8-bit PMIC register specified by Register with the value specified
+  by Value and return the operation status.
+
+  @param[in]  BaseAddress     - IPC operation address for target PMIC device.
+  @param[in]  Register        - The PMIC register to write.
+  @param[in]  Value           - The value to write to the PMIC register.
+
+  @retval EFI_SUCCESS         - Write bytes to PMIC device successfully
+  @retval Others              - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicWrite8 (
+  IN UINT8                     BaseAddress,
+  IN UINT8                     Register,
+  IN UINT8                     Value
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicWrite8, EFI_UNSUPPORTED)
+  return gPmicObj->PmicWrite8(BaseAddress, Register, Value);
+}
+
+/**
+  Get previous shutdown root cause.
+
+  @param[in, out]  ShutdownCause - The data to store shutdown root cause.
+
+  @retval EFI_SUCCESS            - Get shutdown root cause successfully.
+  @retval Others                 - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicGetShutdownCause (
+  IN OUT UINT32    *ShutdownCause
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicGetShutdownCause, EFI_UNSUPPORTED)
+  return gPmicObj->PmicGetShutdownCause(ShutdownCause);
+}
+
+/**
+  Get previous reset root cause
+
+  @param[in, out]  ResetSrc     - The data to store reset root cause
+
+  @retval EFI_SUCCESS           - Get reset root cause successfully.
+  @retval EFI_INVALID_PARAMETER - ResetSrc is NULL.
+**/
+EFI_STATUS
+EFIAPI
+PmicGetResetSrc (UINT32 *ResetSrc)
+{
+  RETURN_IF_POINTER_NULL(PmicGetResetSrc, EFI_UNSUPPORTED)
+  return gPmicObj->PmicGetResetSrc(ResetSrc);
+}
+
+/**
+  Get the cause of system wake event.
+
+  @param[in, out]  WakeCause   - The data to store the cause of wake event.
+
+  @retval EFI_SUCCESS          - Get wake cause successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicGetWakeCause (
+  IN OUT UINT32    *WakeCause
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicGetWakeCause, EFI_UNSUPPORTED)
+  return gPmicObj->PmicGetWakeCause(WakeCause);
+}
+
+/**
+  Get power source detection result.
+
+  @param[in, out]  PowerSrcIrq   - The data to the cause of wake event.
+
+  @retval EFI_SUCCESS            - Get power source successfully.
+  @retval Others                 - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicGetPwrSrcIrq (
+  IN OUT UINT32    *PowerSrcIrq
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicGetPwrSrcIrq, EFI_UNSUPPORTED)
+  return gPmicObj->PmicGetPwrSrcIrq(PowerSrcIrq);
+}
+
+/**
+  Battery Detection Status
+
+  @retval TRUE                - Connected
+  @retval FALSE               - Disconnected
+**/
+BOOLEAN
+EFIAPI
+PmicIsBatOn (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicIsBatOn, TRUE)
+  return gPmicObj->PmicIsBatOn();
+}
+
+/**
+  AC/DC Adapter Detection Status
+
+  @retval TRUE                - Connected
+  @retval FALSE               - Disconnected
+**/
+BOOLEAN
+EFIAPI
+PmicIsACOn (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicIsACOn, TRUE)
+  return gPmicObj->PmicIsACOn();
+}
+
+/**
+  VBUS Detection Status
+
+  It can be used to detect whether USB charger is connected.
+
+  @retval TRUE                - Connected
+  @retval FALSE               - Disconnected
+**/
+BOOLEAN
+EFIAPI
+PmicVbusStatus (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicVbusStatus, TRUE)
+  return gPmicObj->PmicVbusStatus();
+}
+
+/**
+  USB ID Detection Status
+
+  @retval UINT8               - Value depends on each PMIC operation.
+**/
+UINT8
+EFIAPI
+PmicUSBIDStatus (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicUSBIDStatus, TRUE)
+  return gPmicObj->PmicUSBIDStatus();
+}
+
+/**
+  Clear previous shutdown root cause.
+
+  @retval EFI_SUCCESS          - Clear shutdown root cause successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicClearShutdownCause (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicClearShutdownCause, EFI_UNSUPPORTED)
+
+  return gPmicObj->PmicClearShutdownCause();
+}
+
+/**
+  Clear the cause of system wake event.
+
+  @retval EFI_SUCCESS          - Clear wake cause successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicClearWakeCause (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicClearWakeCause, EFI_UNSUPPORTED)
+  return gPmicObj->PmicClearWakeCause();
+}
+
+/**
+  Clear the cause of system reset.
+
+  @retval EFI_SUCCESS          - Clear reset cause successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicClearResetSrc (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicClearResetSrc, EFI_UNSUPPORTED)
+  return gPmicObj->PmicClearResetSrc();
+}
+
+/**
+  Initialize PMIC thermal detection capability.
+
+  @retval EFI_SUCCESS          - Initialize thermal detection successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicThermInit (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicThermInit, EFI_UNSUPPORTED)
+  return gPmicObj->PmicThermInit();
+}
+
+/**
+  Initialize PMIC GPIO pin.
+
+  Initialize PMIC GPIO pin in order to get boardid/memcfgid/.. etc later
+
+  @param[in] PlatformInfo      - Platform information with GPIO setting.
+
+  @retval EFI_SUCCESS          - Initialize GPIO pin successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicGpioInit (
+  IN VOID    *PlatformInfo
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicGpioInit, EFI_UNSUPPORTED)
+  return gPmicObj->PmicGpioInit(PlatformInfo);
+}
+
+/**
+  Initializes PMIC device.
+
+  @retval EFI_SUCCESS          - Initialize PMIC successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicIntrInit (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicIntrInit, EFI_UNSUPPORTED)
+  return gPmicObj->PmicIntrInit();
+}
+
+/**
+  Initializes Burst Control Unit (BCU) hardware.
+
+  The BCU has several different knobs (input stimuli configuration, interrupts,
+  and output actions) that allow the Software and Firmware to change the BCU response
+  behavior once these events occur. These BCU control knobs allow for a change in the
+  BCU behavior in responding to these triggers and can be completely customized as
+  necessary by the specific system implementation.
+
+  @retval EFI_SUCCESS          - Initializes BCU hardware successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicBcuInit (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicBcuInit, EFI_UNSUPPORTED)
+  return gPmicObj->PmicBcuInit();
+}
+
+/**
+  Initializes other miscellaneous functions on PMIC device.
+
+  @retval EFI_SUCCESS          - Initializes miscellaneous functions successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicMiscInit (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicMiscInit, EFI_UNSUPPORTED)
+  return gPmicObj->PmicMiscInit ();
+}
+
+/**
+  Turn on or off VBUS for OTG
+
+  @param[in]  Enable           - TRUE : turn on VBUS
+                                 FALSE: turn off VBUS
+
+  @retval EFI_SUCCESS          - Turn on/off VBUS successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicVbusControl (
+  IN BOOLEAN    Enable
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicVbusControl, EFI_UNSUPPORTED)
+  return gPmicObj->PmicVbusControl(Enable);
+}
+
+/**
+  Turn on or off 5V VBUS for USB2/3 HOST
+
+  @param[in]  Enable           - TRUE : turn on V5P0S
+                                 FALSE: turn off V5P0S
+
+  @retval EFI_SUCCESS          - Turn on/off V5P0S successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicVhostControl (
+  IN BOOLEAN    Enable
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicVhostControl, EFI_UNSUPPORTED)
+  return gPmicObj->PmicVhostControl(Enable);
+}
+
+/**
+  Get PMIC Vendor ID and Device ID
+
+  @param[in, out] VenId        - Vendor ID
+  @param[in, out] DevId        - Device ID
+
+  @retval EFI_SUCCESS          - Get Vendor ID and Device ID successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicGetDevID (
+  IN OUT UINT8    *VenId,
+  IN OUT UINT8    *DevId
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicGetDevID, EFI_UNSUPPORTED)
+  return gPmicObj->PmicGetDevID(VenId, DevId);
+}
+
+/**
+  This procedure will get PMIC Stepping
+
+  @retval PMIC Stepping
+**/
+UINT8
+EFIAPI
+PmicStepping (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicStepping, 0xff);
+
+  return gPmicObj->PmicStepping();
+}
+
+/**
+  Get PMIC device instance
+
+  @retval PMIC_TYPE            - Device type is defined in PMIC_TYPE.
+**/
+PMIC_TYPE
+EFIAPI
+PmicGetDeviceType (
+  VOID
+  )
+{
+  return gPmicObj->PmicType;
+}
+
+/**
+  Get battery voltage.
+
+  @retval UINT16               - ADC result for battery voltage.
+**/
+UINT16
+EFIAPI
+PmicGetVBAT (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicGetVBAT, 0xff)
+  return gPmicObj->PmicGetVBAT();
+}
+
+/**
+  Get battery capacity.
+
+  @retval UINT16               - Remaining percentage of battery capacity.
+**/
+UINT16
+EFIAPI
+PmicGetBatteryCap (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicGetBatteryCap, 0xff)
+  return gPmicObj->PmicGetBatteryCap();
+}
+
+/**
+  Get power button status
+
+  @retval TRUE                  - Power button pressed.
+  @retval FALSE                 - Power button released.
+**/
+BOOLEAN
+EFIAPI
+PmicIsPwrBtnPressed (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicIsPwrBtnPressed, TRUE)
+
+  return gPmicObj->PmicIsPwrBtnPressed();
+}
+
+/**
+  Disable the capability to shutdown platform using power button.
+
+  @param[out] ButtonHoldTime   - If the power button is disabled successfully,
+                                 this contains the time in seconds need to hold power button to shutdown platform.
+
+  @retval EFI_SUCCESS          - Succeed to disable power button
+  @retval Others               - Failed to disable power button
+**/
+EFI_STATUS
+EFIAPI
+PmicDisablePowerButton (
+  OUT UINT8    *ButtonHoldTime
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicDisablePowerButton, EFI_UNSUPPORTED)
+  return gPmicObj->PmicDisablePowerButton(ButtonHoldTime);
+}
+
+/**
+  Enable the capability to shutdown platform using power button.
+
+  @param[in] ButtonHoldTime    - Time in seconds to shut down the platform if power button is enabled and hold
+
+  @retval EFI_SUCCESS          - Succeed to enable power button
+  @retval Others               - Filed to enable power button
+**/
+EFI_STATUS
+EFIAPI
+PmicEnablePowerButton (
+  IN UINT8    ButtonHoldTime
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicEnablePowerButton, EFI_UNSUPPORTED)
+  return gPmicObj->PmicEnablePowerButton(ButtonHoldTime);
+}
+
+/**
+  Set VDDQ to 1.35V for DDR3L
+
+  @retval EFI_SUCCESS          - Succeed to Set VDDQ
+  @retval Others               - Filed to Set VDDQ
+**/
+EFI_STATUS
+EFIAPI
+PmicSetVDDQ (
+  VOID
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicSetVDDQ, EFI_UNSUPPORTED)
+  return gPmicObj->PmicSetVDDQ();
+}
+
+/**
+  Probe to find the correct PMIC object.
+
+  After probling, g_pmic_obj points to correct PMIC object
+  This routine is invoked when library is loaded .
+
+  @retval TRUE                - There is one PMIC object found.
+  @retval FALSE               - No PMIC object found.
+**/
+BOOLEAN
+EFIAPI
+PmicProbe (
+  VOID
+  )
+{
+  gPmicObj = &DmObj;
+  return FALSE;
+}
+
+/**
+  Read charger's register provided by PMIC.
+
+  @param[in]  Offset           - The charger's register to read.
+  @param[out] Value            - The value read.
+
+  @retval EFI_SUCCESS          - Read charger's register successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicChargerRead (
+  IN  UINT8     Offset,
+  OUT UINT8     *Value
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicChargerRead, EFI_UNSUPPORTED)
+  return gPmicObj->PmicChargerRead(Offset, Value);
+}
+
+/**
+  Write charger's register provided by PMIC.
+
+  @param[in] Offset            - The charger's register to write.
+  @param[in] Value             - The value written.
+
+  @retval EFI_SUCCESS          - Write charger's register successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicChargerWrite (
+  IN UINT8    Offset,
+  IN UINT8    Value
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicChargerWrite, EFI_UNSUPPORTED)
+  return gPmicObj->PmicChargerWrite(Offset, Value);
+}
+
+/**
+  Detect charger type and charger presence.
+
+  @param[out] ChargerPresent   - TRUE : Charger present.
+                                 FALSE: Charger not present.
+  @param[out] ChargerType      - Charger type - SDP/DCP/CDP... etc.
+
+  @retval EFI_SUCCESS          - Detect charger type and charger presence successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicDetectCharger (
+  OUT BOOLEAN    *ChargerPresent,
+  OUT UINT8      *ChargerType
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicDetectCharger, EFI_UNSUPPORTED)
+  return gPmicObj->PmicDetectCharger(ChargerPresent, ChargerType);
+}
+
+/**
+  Controls external USB PHY reset
+
+  @param[in] Enable            - TRUE : OUTOFRESET - external PHY is out of reset
+                                 FALSE: INRESET - external PHY is in reset
+
+  @retval EFI_SUCCESS          - Controls external USB PHY successfully.
+  @retval Others               - Status depends on each PMIC operation.
+**/
+EFI_STATUS
+EFIAPI
+PmicUSBSwitchControl (
+  IN BOOLEAN    Enable
+  )
+{
+  RETURN_IF_POINTER_NULL(PmicUSBSwitchControl, EFI_UNSUPPORTED)
+  return gPmicObj->PmicUSBSwitchControl(Enable);
+}
+
+/**
+  Pmic library constructor
+
+  PMIC type is probed in this function. It is invoked every time Pmiclib is loaded.
+
+  @retval  EFI_SUCCESS         - Construct PMIC instance successfully.
+**/
+RETURN_STATUS
+EFIAPI
+PmicLibConstructor (
+  VOID
+  )
+{
+  PmicProbe();
+  return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.inf b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.inf
new file mode 100644
index 0000000..35ceb79
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicLibNull.inf
@@ -0,0 +1,44 @@
+## @file
+# Dxe Library for accessing PMIC registers.
+#
+#
+#  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.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = PmicLibNull
+  FILE_GUID                      = 90c0faf8-cb8b-4726-a69c-c38a5b110c30
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PmicLib
+  CONSTRUCTOR                    = PmicLibConstructor
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+  PmicLibNull.c
+  PmicDummy.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  BroxtonPlatformPkg/PlatformPkg.dec
+
+[LibraryClasses]
+#Althogh PMIClib does not use gBS(provided by UefiBootServicesTableLib),
+#but libconstructor use i2c routine which uses gBS.
+#UefiBootServicesTableLib is a must here.
+  UefiBootServicesTableLib
+  DebugLib
diff --git a/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicPrivate.h b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicPrivate.h
new file mode 100644
index 0000000..c173b38
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/Library/PmicLib/PmicPrivate.h
@@ -0,0 +1,82 @@
+/** @file
+  Private Header file for PMIC Dxe Driver
+
+  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 _PMIC_REG_PV_H_
+#define _PMIC_REG_PV_H_
+
+#include <Uefi/UefiBaseType.h>
+#include <Base.h>
+#include <Library/PmicLib.h>
+
+///
+/// PMIC device object
+///
+struct PmicObject {
+  UINT8      I2cbus;
+  UINT8      I2cSlaveAddr0;     ///< page0
+  UINT8      I2cSlaveAddr1;     ///< page1
+  PMIC_TYPE  PmicType;
+  UINT8      (EFIAPI* PmicRead8)              (IN UINT8 BaseAddress, IN UINT8 Register);
+  EFI_STATUS (EFIAPI* PmicWrite8)             (IN UINT8 BaseAddress, IN UINT8 Register, IN UINT8 Value);
+
+  BOOLEAN    (EFIAPI* PmicProbe)              (VOID);
+  EFI_STATUS (EFIAPI* PmicGetDevID)           (IN OUT UINT8 *VenId, IN OUT UINT8 *DevId);
+  UINT8      (EFIAPI* PmicStepping)           (VOID);
+  EFI_STATUS (EFIAPI* PmicThermInit)          (VOID);
+  EFI_STATUS (EFIAPI* PmicGpioInit)           (IN VOID *PlatformInfo);
+  EFI_STATUS (EFIAPI* PmicIntrInit)           (VOID);
+  EFI_STATUS (EFIAPI* PmicBcuInit)            (VOID);
+  EFI_STATUS (EFIAPI* PmicMiscInit)           (VOID);
+  EFI_STATUS (EFIAPI* PmicVbusControl)        (IN BOOLEAN Enable);
+  EFI_STATUS (EFIAPI* PmicVhostControl)       (IN BOOLEAN Enable);
+  EFI_STATUS (EFIAPI* PmicBatchRegisterInit)  (IN RegInit_st *RegInit, IN UINT32 length);
+
+  ///
+  /// PUPDR interfaces
+  ///
+  EFI_STATUS (EFIAPI* PmicGetWakeCause)       (IN OUT UINT32 *WakeCause);
+  EFI_STATUS (EFIAPI* PmicGetShutdownCause)   (IN OUT UINT32 *ShutdownCause);
+  EFI_STATUS (EFIAPI* PmicGetResetSrc)        (IN OUT UINT32 *ResetSrc);
+  EFI_STATUS (EFIAPI* PmicGetPwrSrcIrq)       (IN OUT UINT32 *PowerSrcIrq);
+  BOOLEAN    (EFIAPI* PmicIsBatOn)            (VOID);
+  BOOLEAN    (EFIAPI* PmicIsACOn)             (VOID);
+  BOOLEAN    (EFIAPI* PmicVbusStatus)         (VOID);
+  EFI_STATUS (EFIAPI* PmicClearShutdownCause) (VOID);
+  EFI_STATUS (EFIAPI* PmicClearWakeCause)     (VOID);
+  EFI_STATUS (EFIAPI* PmicClearResetSrc)      (VOID);
+  UINT16     (EFIAPI* PmicGetVBAT)            (VOID);
+  BOOLEAN    (EFIAPI* PmicIsPwrBtnPressed)    (VOID);
+  EFI_STATUS (EFIAPI* PmicDisablePowerButton) (OUT UINT8 *ButtonHoldTime);
+  EFI_STATUS (EFIAPI* PmicEnablePowerButton)  (IN UINT8  ButtonHoldTime);
+  UINT16     (EFIAPI* PmicGetBatteryCap)      (VOID);
+  EFI_STATUS (EFIAPI* PmicSetVDDQ)            (VOID);
+  EFI_STATUS (EFIAPI* PmicChargerRead)        (IN UINT8 Offset, OUT UINT8 *Value);
+  EFI_STATUS (EFIAPI* PmicChargerWrite)       (IN UINT8 Offset, IN UINT8 Value);
+  EFI_STATUS (EFIAPI* PmicDetectCharger)      (OUT BOOLEAN *ChargerPresent, OUT UINT8 *ChargerType);
+  EFI_STATUS (EFIAPI* PmicUSBSwitchControl)   (IN BOOLEAN Enable);
+  UINT8      (EFIAPI* PmicUSBIDStatus)        (VOID);
+};
+
+#define RETURN_IF_POINTER_NULL(method, value)  { if ((NULL == gPmicObj) || (NULL == gPmicObj->method)) \
+                                                 {\
+                                                   DEBUG ((DEBUG_ERROR, "null function pointer\n")); \
+                                                   return value; \
+                                                 }\
+                                               }
+
+#endif
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/SouthClusterConfig.vfi b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/SouthClusterConfig.vfi
index 84ae466..411006b 100644
--- a/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/SouthClusterConfig.vfi
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSettings/PlatformSetupDxe/SouthClusterConfig.vfi
@@ -1,7 +1,7 @@
 // /** @file
 //  South Cluster Setup formset.
 //
-//  Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+//  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
@@ -2416,8 +2416,8 @@ form formid     = USB_OPTIONS_FORM_ID,
   oneof varid   = Setup.ScUsbOtg,
     prompt      = STRING_TOKEN(STR_USB_XDCI_PROMPT),
     help        = STRING_TOKEN(STR_USB_XDCI_HELP),
-    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
-    option text = STRING_TOKEN(STR_PCI_MODE_STRING), value = 1, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;
+    option text = STRING_TOKEN(STR_PCI_MODE_STRING), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
 //  option text = STRING_TOKEN(STR_ACPI_MODE_STRING), value = 2, flags = RESET_REQUIRED;
   endoneof;
 
diff --git a/Platform/BroxtonPlatformPkg/PlatformDsc/Components.dsc b/Platform/BroxtonPlatformPkg/PlatformDsc/Components.dsc
index 53658cf..da61f84 100644
--- a/Platform/BroxtonPlatformPkg/PlatformDsc/Components.dsc
+++ b/Platform/BroxtonPlatformPkg/PlatformDsc/Components.dsc
@@ -455,6 +455,8 @@
   #
   PcAtChipsetPkg/8259InterruptControllerDxe/8259.inf
 
+  $(PLATFORM_PACKAGE_COMMON)/Features/UsbDeviceDxe/UsbDeviceDxe.inf
+  
   #
   # USB TypeC
   #
diff --git a/Platform/BroxtonPlatformPkg/PlatformDsc/LibraryClasses.dsc b/Platform/BroxtonPlatformPkg/PlatformDsc/LibraryClasses.dsc
index c7e8d76..9af21aa 100644
--- a/Platform/BroxtonPlatformPkg/PlatformDsc/LibraryClasses.dsc
+++ b/Platform/BroxtonPlatformPkg/PlatformDsc/LibraryClasses.dsc
@@ -1,7 +1,7 @@
 ## @file
 #  Library classes Description.
 #
-#  Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 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
@@ -242,6 +242,8 @@
 
    BasePlatformCmosLib|$(PLATFORM_PACKAGE_COMMON)/Library/PlatformCmosLib/PlatformCmosLib.inf
 
+   PmicLib|$(PLATFORM_PACKAGE_COMMON)/Library/PmicLib/PmicLibNull.inf
+
    #
    # Reference code Libraries
    #
diff --git a/Platform/BroxtonPlatformPkg/PlatformPkg.fdf b/Platform/BroxtonPlatformPkg/PlatformPkg.fdf
index 0d9a087..e190dca 100644
--- a/Platform/BroxtonPlatformPkg/PlatformPkg.fdf
+++ b/Platform/BroxtonPlatformPkg/PlatformPkg.fdf
@@ -705,6 +705,8 @@ APRIORI DXE {
     SECTION PE32 = ShellBinPkg/UefiShell/$(IA32_X64_LC)/Shell.efi
   }
 
+  INF $(PLATFORM_PACKAGE_COMMON)/Features/UsbDeviceDxe/UsbDeviceDxe.inf  
+
   #
   # USB TypeC
   #
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsUsb.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsUsb.h
index eeb03e2..bc55746 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsUsb.h
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsUsb.h
@@ -17,7 +17,7 @@
   - Registers / bits of new devices introduced in a SC generation will be just named
     as "_SC_" without <generation_name> inserted.
 
-  Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+  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
@@ -563,6 +563,14 @@
 #define B_XDCI_POW_PG_CONF_D3HEN        BIT18   ///< D3-Hot Enable
 #define B_XDCI_POW_PG_CONF_DEVIDLEN     BIT17   ///< DEVIDLE Enable
 
+
+#define R_OTG_BAR0                      0x10  ///< BAR 0
+#define B_OTG_BAR0_BA                   0xFFE00000 ///< Base Address
+#define V_OTG_BAR0_SIZE                 0x200000
+#define N_OTG_BAR0_ALIGNMENT            21
+#define B_OTG_BAR0_PREF                 BIT3  ///< Prefetchable
+#define B_OTG_BAR0_ADDRNG               (BIT2 | BIT1) ///< Address Range
+#define B_OTG_BAR0_SPTYP                BIT0  ///< Space Type (Memory)
 #define R_OTG_GEN_INPUT_REGRW           0xC0
 #define B_OTG_GEN_INPUT_REGRW_CPSU3     (BIT11 | BIT10) ///< Current Power State u3pmu
 #define B_OTG_GEN_INPUT_REGRW_CPSU2     (BIT9 | BIT8) ///< Current Power State u2pmu
-- 
2.10.1.windows.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2017-01-22  3:33 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-01-22  3:12 [Patch][edk2-platforms/devel-MinnowBoard3] Add USB peripheral mode Guo, Mang
2017-01-22  3:33 ` Wei, David

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox