Thanks to Feng pointing me in the right direction, I've got this starting to
work but I have encountered some strangeness.

I wrote the PEIM below to configure the xHCI controller and install the
PEI_USB_CONTROLLER_PPI.  
I was seeing some problems reading device and config descriptors and found
that if the memory locations I was reading descriptors into aren't at least
16 byte aligned, I wasn't getting all the data in memory.  I know PCIe
accesses are dword aligned and use byte enables for the first/last dword to
handle byte alignment but I don't understand why it would be sensitive to
alignment larger than dwords.  

I'm currently stuck trying to read a 272 byte config descriptor.  I'm
reading it into a page aligned chunk of memory but I'm still getting an
exception in the debugger when I execute the request on the xHCI host.  What
I see in the xHCI event ring after the doorbell ring are event TRBs for the
setup and data stages of the control transfer but no event for the status
stage.  After that things seem wedged.  My USB analyzer shows the Setup and
data stages happening over USB but the host doesn't initiate the Status
stage.

I'm using PeiServicesAllocatePages to allocate memory to read the descriptor
into.  Do I need to use a specific type of memory to allow DMA transfers
from the xHCI host to function properly?

Thanks for any ideas,
Eric

Here is the Xhci initialization code, the Base address I'm using is the same
as the system uses in the Dxe phase per Feng's suggestion.

Index: Vlv2TbltDevicePkg/XhciPpi/XhciPpi.inf
===================================================================
--- Vlv2TbltDevicePkg/XhciPpi/XhciPpi.inf       (revision 0)
+++ Vlv2TbltDevicePkg/XhciPpi/XhciPpi.inf       (revision 29801)
@@ -0,0 +1,49 @@
+#  Copyright (c) 2015, Fresco Logic, Inc. All rights reserved.<BR>
+
+#  This program and the accompanying materials are licensed and made
available under
+#  the terms and conditions of the BSD License that 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.    
+
+# Module Name:
+
+#  XhciPpi.h
+
+# Abstract:
+
+#  For Minnowboard Max set the xHCI controller memory BAR address and
+#  configure the usb ports to connect to the xhci controller instead 
+#  of the EHCI controller. 
+#  Implement and install the PEI_USB_CONTROLLER_PPI during the Pei phase 
+#  for use in recovery.
+
+[defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = XhciPpi
+  FILE_GUID                      = 340188CF-27A4-417E-8285-758AFF34F91C
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  PI_SPECIFICATION_VERSION       = 0x0001000A
+  ENTRY_POINT                    = XhciPpiEntry
+
+[sources.common]
+  XhciPpi.c
+  XhciPpi.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+  PeimEntryPoint
+  DebugLib
+  PciLib
+
+[Ppis]
+  gPeiUsbControllerPpiGuid                 ## PRODUCES
+
+[Depex]
+  TRUE
Index: Vlv2TbltDevicePkg/XhciPpi/XhciPpi.c
===================================================================
--- Vlv2TbltDevicePkg/XhciPpi/XhciPpi.c (revision 0)
+++ Vlv2TbltDevicePkg/XhciPpi/XhciPpi.c (revision 29801)
@@ -0,0 +1,149 @@
+/*++
+
+Copyright (c) 2015, Fresco Logic, Inc. All rights reserved.<BR>
+
+This program and the accompanying materials are licensed and made available
under
+the terms and conditions of the BSD License that 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.
+
+Module Name:
+  XhciPpi.c
+
+Abstract:
+
+For Minnowboard Max set the xHCI controller memory BAR address and
+configure the usb ports to connect to the xhci controller instead
+of the EHCI controller.
+Implement and install the PEI_USB_CONTROLLER_PPI during the Pei phase
+for use in recovery.
+
+--*/
+
+
+#include "XhciPpi.h"
+
+static PEI_USB_CONTROLLER_PPI mEfiGetUsbController = {
+  GetUsbController
+};
+
+  EFI_PEI_PPI_DESCRIPTOR  mPpiUsbController = {
+  ( EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST ),
+  &gPeiUsbControllerPpiGuid,
+  &mEfiGetUsbController
+};
+
+EFI_STATUS
+GetUsbController (
+IN  EFI_PEI_SERVICES        **PeiServices,
+IN  PEI_USB_CONTROLLER_PPI  *This,
+IN  UINT8                   UsbControllerId,
+OUT UINTN                   *ControllerType,
+OUT UINTN                   *BaseAddress
+)
+{
+  if ( UsbControllerId > 0 ) {
+    return( EFI_INVALID_PARAMETER );
+  }
+
+  *ControllerType = PEI_XHCI_CONTROLLER;
+
+  *BaseAddress = XHCI_BASE_ADDRESS;
+
+  return ( EFI_SUCCESS );
+}
+
+/**
+Program and eanble XHCI MMIO base address.
+
+@return XHCI MMIO base address.
+
+**/
+EFI_PHYSICAL_ADDRESS
+ProgramXhciBaseAddress (
+VOID
+)
+{
+  UINT16                      PciCmd;
+  UINT32                      Low;
+  UINT32                      High;
+  EFI_PHYSICAL_ADDRESS        XhciMmioBase;
+  UINT32                      UsbXhciPciAddress = 0x000A0000;
+
+  Low = PciRead32 ( UsbXhciPciAddress + PCI_BASE_ADDRESSREG_OFFSET );
+  High = PciRead32 ( UsbXhciPciAddress + PCI_BASE_ADDRESSREG_OFFSET + 4 );
+  XhciMmioBase = ( EFI_PHYSICAL_ADDRESS )( LShiftU64 ( ( UINT64 )High, 32 )
| Low );
+  XhciMmioBase &= XHCI_BASE_ADDRESS_64_BIT_MASK;
+
+  //
+  // Set xHCI controller memory BAR.
+  //
+  if ( ( XhciMmioBase == 0 ) || ( XhciMmioBase ==
XHCI_BASE_ADDRESS_64_BIT_MASK ) ) {
+    XhciMmioBase = XHCI_BASE_ADDRESS;
+    PciWrite32 ( UsbXhciPciAddress + PCI_BASE_ADDRESSREG_OFFSET,
XhciMmioBase & 0xFFFFFFFF );
+    PciWrite32 ( UsbXhciPciAddress + PCI_BASE_ADDRESSREG_OFFSET + 4, (
RShiftU64 ( XhciMmioBase, 32 ) & 0xFFFFFFFF ) );
+  }
+
+  //
+  // Enable memory Space and set Bus Master Enable in the PCI Command
Register.
+  //
+  PciCmd = PciRead16 ( UsbXhciPciAddress + PCI_COMMAND_OFFSET );
+  if ( ( ( PciCmd & EFI_PCI_COMMAND_MEMORY_SPACE ) == 0 ) || ( ( PciCmd &
EFI_PCI_COMMAND_BUS_MASTER ) == 0 ) ) {
+    PciCmd |= EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER;
+    PciWrite16 ( UsbXhciPciAddress + PCI_COMMAND_OFFSET, PciCmd );
+  }
+
+  //
+  // Connect all USB ports to the xHCI controller.
+  //
+  PciWrite8 ( UsbXhciPciAddress + 0xD0, 0x3F );
+  PciWrite8 ( UsbXhciPciAddress + 0xD4, 0x3F );
+  PciWrite8 ( UsbXhciPciAddress + 0xD8, 0x01 );
+  PciWrite8 ( UsbXhciPciAddress + 0xDC, 0x01 );
+
+  return XhciMmioBase;
+}
+
+/**
+  Platform specific xHCI host initialization.
+
+  @param FfsHeader         Pointer to the PEIM FFS file header.
+  @param PeiServices       General purpose services available to every
PEIM.
+
+  @retval EFI_SUCCESS       Operation completed successfully.
+  @retval Otherwise         xHCI initialization failed.
+**/
+EFI_STATUS
+EFIAPI
+XhciPpiEntry (
+
+  IN       EFI_PEI_FILE_HANDLE  FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  EFI_STATUS                  Status;
+
+  DEBUG ( ( EFI_D_INFO, "XhciPpiEntry: Setting Xhci Bar\n" ) );
+
+  ProgramXhciBaseAddress ( );
+
+  DEBUG ( ( EFI_D_INFO, "XhciPpiEntry: Installing PEI_USB_CONTROLLER_PPI\n"
) );
+
+  Status = ( *PeiServices )->InstallPpi (
+    PeiServices,
+    &mPpiUsbController
+  );
+
+  DEBUG ( ( EFI_D_INFO, "XhciPpiEntry: completed with %r\n", Status ) );
+
+  return Status;
+}
+
+#ifdef __GNUC__
+#pragma GCC pop_options
+#else
+#pragma optimize ("", on)
+#endif
Index: Vlv2TbltDevicePkg/XhciPpi/XhciPpi.h
===================================================================
--- Vlv2TbltDevicePkg/XhciPpi/XhciPpi.h (revision 0)
+++ Vlv2TbltDevicePkg/XhciPpi/XhciPpi.h (revision 29801)
@@ -0,0 +1,52 @@
+/*++
+
+Copyright (c) 2015, Fresco Logic, Inc. All rights reserved.<BR>
+
+This program and the accompanying materials are licensed and made available
under
+the terms and conditions of the BSD License that 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.
+
+Module Name:
+XhciPpi.h
+
+Abstract:
+
+For Minnowboard Max set the xHCI controller memory BAR address and
+configure the usb ports to connect to the xhci controller instead
+of the EHCI controller.
+Implement and install the PEI_USB_CONTROLLER_PPI during the Pei phase
+for use in recovery.
+
+--*/
+
+#ifndef _EFI_XHCI_PPI_H_
+#define _EFI_XHCI_PPI_H_
+
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PciLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#include <IndustryStandard/Pci22.h>
+#include <Ppi/UsbController.h>
+
+#define XHCI_BASE_ADDRESS             0x90800000
+#define XHCI_BASE_ADDRESS_64_BIT_MASK 0xFFFFFFFFFFFF0000ULL
+#define XHCI_BASE_ADDRESS_32_BIT_MASK 0xFFFF0000
+
+EFI_STATUS
+GetUsbController (
+  IN  EFI_PEI_SERVICES        **PeiServices,
+  IN  PEI_USB_CONTROLLER_PPI  *This,
+  IN  UINT8                   UsbControllerId,
+  OUT UINTN                   *ControllerType,
+  OUT UINTN                   *BaseAddress
+);
+
+#endif


> -----Original Message-----
> From: Tian, Feng [mailto:[email protected]]
> Sent: Wednesday, August 19, 2015 6:01 PM
> To: Eric Wittmayer; [email protected]
> Cc: Tian, Feng
> Subject: RE: [edk2] Help debugging PEIM on Minnowboard Max
> 
> EDKII mass storage PEIM drivers were developed for recovery mode, that's
> why you can see a gEfiPeiBootInRecoveryModePpiGuid dependency in their
> INF files.
> 
> So they don't meet your usage model and you need make some code
> changes and introduce a usb host controller PEIM driver like I said
before.
> 
> As for the BAR, a simple way is booting to shell and see which bar is used
in
> DXE phase and then hardcode it in your usb host controller PEIM driver.
> 
> Last, as far as I know there is no reference platform enabling pure xhci
pei
> support.
> 
> -----Original Message-----
> From: edk2-devel [mailto:[email protected]] On Behalf Of
> Eric Wittmayer
> Sent: Tuesday, August 18, 2015 13:00
> To: Tian, Feng; [email protected]
> Subject: Re: [edk2] Help debugging PEIM on Minnowboard Max
> 
> Hi Feng,
>    Now I understand the concept.  I was expecting that PEIM would already
be
> available for the Minnowboard Max.  Is Usb in the PEI phase not supported
in
> Minnowboard?
> 
> From my digging in the code today, it seems to enable the xhci controller,
it's
> PCI BAR needs to be set and enabled for memory access.  I found memory
> base addresses for some devices in
> Vlv2DeviceRefCodePkg\ValleyView2Soc\NorthCluster\Include\PlatformBase
> Address
> es.h but not for XHCI.  From looking at the Atom E3800 datasheet, the xhci
> memory base doesn't have a fixed location so I believe I need to pick an
> unused range in the Low MMIO space to set as the xhci BAR.
> 
> If you or someone else on the list can recommend a different platform that
> already supports xhci in the PEI phase to use as a development platform
that
> might be a better option for me.
> 
> Thank you again for your patience and prompt responses.
> 
> Eric
> 
> > -----Original Message-----
> > From: Tian, Feng [mailto:[email protected]]
> > Sent: Sunday, August 16, 2015 10:20 PM
> > To: Eric Wittmayer; [email protected]
> > Cc: Tian, Feng
> > Subject: RE: [edk2] Help debugging PEIM on Minnowboard Max
> >
> > Do you look into the UsbController.h in MdeModulePkg/Include/Ppi
> > directory?
> >
> > typedef
> > EFI_STATUS
> > (EFIAPI *PEI_GET_USB_CONTROLLER)(
> >   IN  EFI_PEI_SERVICES        **PeiServices,
> >   IN  PEI_USB_CONTROLLER_PPI  *This,
> >   IN  UINT8                   UsbControllerId,
> >   OUT UINTN                   *ControllerType,
> >   OUT UINTN                   *BaseAddress
> >   );
> >
> > You need write a PEIM to produce this PPI and implement the above
> > interface according to your platform setting.
> >
> > For how to write a PEIM module, you can refer to EDKII Module Writer's
> > Guide in edk2.sourceforge.net
> >
> > Thanks
> > Feng
> >
> > -----Original Message-----
> > From: Eric Wittmayer [mailto:[email protected]]
> > Sent: Monday, August 17, 2015 11:50
> > To: Tian, Feng; [email protected]
> > Subject: RE: [edk2] Help debugging PEIM on Minnowboard Max
> >
> > Hi Feng,
> >    I see now that XhciPei needs gPeiUsbControllerPpiGuid and creates
> > gPeiUsbHostControllerPpiGuid  which UsbBusPei needs.
> >
> > I can't seem to figure out what creates gPeiUsbControllerPpiGuid?  I
> > see
> it
> > listed in the .dec file I'm using but that apparently isn't enough to
> > install the Ppi.   What should be installing the
gPeiUsbControllerPpiGuid?
> >
> > Thanks,
> > Eric
> >
> > > -----Original Message-----
> > > From: Tian, Feng [mailto:[email protected]]
> > > Sent: Sunday, August 16, 2015 6:09 PM
> > > To: Eric Wittmayer; [email protected]
> > > Cc: Tian, Feng
> > > Subject: RE: [edk2] Help debugging PEIM on Minnowboard Max
> > >
> > > Eric,
> > >
> > > I must agree the naming of these usb pei related ppi guids are not
> > > good, which misleads you.
> > >
> > > There is no the chicken and egg problem.
> > > gPeiUsbHostControllerPpiGuid and gPeiUsbControllerPpiGuid are two
> > > different ppis. The former is consumed by UsbPei and the latter is
> > > consumed by XhciPei. You need write a pei module to produce
> > > PeiUsbControllerPpi (see MdeModulePkg/Include/Ppi for
> > > definitions) at first.
> > >
> > > Thanks
> > > Feng
> > >
> > > -----Original Message-----
> > > From: edk2-devel [mailto:[email protected]] On Behalf
> > > Of Eric Wittmayer
> > > Sent: Saturday, August 15, 2015 08:12
> > > To: [email protected]
> > > Subject: [edk2] Help debugging PEIM on Minnowboard Max
> > >
> > > I'm writing a PEIM for a USB3 device but having trouble even getting
> > > the UsbBusPie and XhciPei modules to load during boot.
> > >
> > > I thought getting the existing Usb Peims to load would be a good
> > > first
> > step.
> > > I looked at the DEPEX for both of the above modules and tried
> > > removing "gEfiPeiBootInRecoveryModePpiGuid" but I didn't see them
> > > load.  If I set both of their DEPEX == TRUE then I see some print
> > > statements that show they are at least trying to load but then I
> > > have a chicken and egg problem
> > in
> > > that UsbBusPie needs either gPeiUsbHostControllerPpiGuid or
> > > gPeiUsb2HostControllerPpiGuid which come from XhciPei.  However,
> > > XhciPei needs gPeiUsbControllerPpiGuid which comes from UsbBusPei
> > > before  it will install the gPeiUsb2HostControllerPpiGuid.  The same
> > > cross dependency is shown in the DEPEX for these two modules.
> > >
> > > I feel like I'm missing something simple and fundamental and I'm
> > > hoping someone will point me in the right direction.
> > >
> > > Thanks,
> > > Eric W
> > >
> > > _______________________________________________
> > > edk2-devel mailing list
> > > [email protected]
> > > https://lists.01.org/mailman/listinfo/edk2-devel
> 
> 
> _______________________________________________
> edk2-devel mailing list
> [email protected]
> https://lists.01.org/mailman/listinfo/edk2-devel

_______________________________________________
edk2-devel mailing list
[email protected]
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to