/** @file | |
Private Header file for Usb Host Controller PEIM | |
Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
#ifndef _RECOVERY_XHC_H_ | |
#define _RECOVERY_XHC_H_ | |
#include <PiPei.h> | |
#include <Ppi/UsbController.h> | |
#include <Ppi/Usb2HostController.h> | |
#include <Ppi/IoMmu.h> | |
#include <Ppi/EndOfPeiPhase.h> | |
#include <Library/DebugLib.h> | |
#include <Library/PeimEntryPoint.h> | |
#include <Library/PeiServicesLib.h> | |
#include <Library/BaseMemoryLib.h> | |
#include <Library/TimerLib.h> | |
#include <Library/IoLib.h> | |
#include <Library/MemoryAllocationLib.h> | |
typedef struct _PEI_XHC_DEV PEI_XHC_DEV; | |
typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT; | |
#include "UsbHcMem.h" | |
#include "XhciReg.h" | |
#include "XhciSched.h" | |
#define CMD_RING_TRB_NUMBER 0x100 | |
#define TR_RING_TRB_NUMBER 0x100 | |
#define ERST_NUMBER 0x01 | |
#define EVENT_RING_TRB_NUMBER 0x200 | |
#define XHC_1_MICROSECOND 1 | |
#define XHC_1_MILLISECOND (1000 * XHC_1_MICROSECOND) | |
#define XHC_1_SECOND (1000 * XHC_1_MILLISECOND) | |
// | |
// XHC reset timeout experience values. | |
// The unit is millisecond, setting it as 1s. | |
// | |
#define XHC_RESET_TIMEOUT (1000) | |
// | |
// TRSTRCY delay requirement in usb 2.0 spec chapter 7.1.7.5. | |
// The unit is microsecond, setting it as 10ms. | |
// | |
#define XHC_RESET_RECOVERY_DELAY (10 * 1000) | |
// | |
// Wait for root port state stable. | |
// | |
#define XHC_ROOT_PORT_STATE_STABLE (200 * XHC_1_MILLISECOND) | |
// | |
// XHC generic timeout experience values. | |
// The unit is millisecond, setting it as 10s. | |
// | |
#define XHC_GENERIC_TIMEOUT (10 * 1000) | |
#define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0XFFFFFFFF)) | |
#define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) | |
#define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit))) | |
#define XHC_REG_BIT_IS_SET(XHC, Offset, Bit) \ | |
(XHC_BIT_IS_SET(XhcPeiReadOpReg ((XHC), (Offset)), (Bit))) | |
#define USB_DESC_TYPE_HUB 0x29 | |
#define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a | |
// | |
// The RequestType in EFI_USB_DEVICE_REQUEST is composed of | |
// three fields: One bit direction, 2 bit type, and 5 bit | |
// target. | |
// | |
#define USB_REQUEST_TYPE(Dir, Type, Target) \ | |
((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target))) | |
struct _USB_DEV_CONTEXT { | |
// | |
// Whether this entry in UsbDevContext array is used or not. | |
// | |
BOOLEAN Enabled; | |
// | |
// The slot id assigned to the new device through XHCI's Enable_Slot cmd. | |
// | |
UINT8 SlotId; | |
// | |
// The route string presented an attached usb device. | |
// | |
USB_DEV_ROUTE RouteString; | |
// | |
// The route string of parent device if it exists. Otherwise it's zero. | |
// | |
USB_DEV_ROUTE ParentRouteString; | |
// | |
// The actual device address assigned by XHCI through Address_Device command. | |
// | |
UINT8 XhciDevAddr; | |
// | |
// The requested device address from UsbBus driver through Set_Address standard usb request. | |
// As XHCI spec replaces this request with Address_Device command, we have to record the | |
// requested device address and establish a mapping relationship with the actual device address. | |
// Then UsbBus driver just need to be aware of the requested device address to access usb device | |
// through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual | |
// device address and access the actual device. | |
// | |
UINT8 BusDevAddr; | |
// | |
// The pointer to the input device context. | |
// | |
VOID *InputContext; | |
// | |
// The pointer to the output device context. | |
// | |
VOID *OutputContext; | |
// | |
// The transfer queue for every endpoint. | |
// | |
VOID *EndpointTransferRing[31]; | |
// | |
// The device descriptor which is stored to support XHCI's Evaluate_Context cmd. | |
// | |
EFI_USB_DEVICE_DESCRIPTOR DevDesc; | |
// | |
// As a usb device may include multiple configuration descriptors, we dynamically allocate an array | |
// to store them. | |
// Note that every configuration descriptor stored here includes those lower level descriptors, | |
// such as Interface descriptor, Endpoint descriptor, and so on. | |
// These information is used to support XHCI's Config_Endpoint cmd. | |
// | |
EFI_USB_CONFIG_DESCRIPTOR **ConfDesc; | |
}; | |
#define USB_XHC_DEV_SIGNATURE SIGNATURE_32 ('x', 'h', 'c', 'i') | |
struct _PEI_XHC_DEV { | |
UINTN Signature; | |
PEI_USB2_HOST_CONTROLLER_PPI Usb2HostControllerPpi; | |
EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; | |
UINT32 UsbHostControllerBaseAddress; | |
USBHC_MEM_POOL *MemPool; | |
// | |
// EndOfPei callback is used to stop the XHC DMA operation | |
// after exit PEI phase. | |
// | |
EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList; | |
// | |
// XHCI configuration data | |
// | |
UINT8 CapLength; ///< Capability Register Length | |
XHC_HCSPARAMS1 HcSParams1; ///< Structural Parameters 1 | |
XHC_HCSPARAMS2 HcSParams2; ///< Structural Parameters 2 | |
XHC_HCCPARAMS HcCParams; ///< Capability Parameters | |
UINT32 DBOff; ///< Doorbell Offset | |
UINT32 RTSOff; ///< Runtime Register Space Offset | |
UINT32 PageSize; | |
UINT32 MaxScratchpadBufs; | |
UINT64 *ScratchBuf; | |
VOID *ScratchMap; | |
UINT64 *ScratchEntry; | |
UINTN *ScratchEntryMap; | |
UINT64 *DCBAA; | |
UINT32 MaxSlotsEn; | |
// | |
// Cmd Transfer Ring | |
// | |
TRANSFER_RING CmdRing; | |
// | |
// EventRing | |
// | |
EVENT_RING EventRing; | |
// | |
// Store device contexts managed by XHCI device | |
// The array supports up to 255 devices, entry 0 is reserved and should not be used. | |
// | |
USB_DEV_CONTEXT UsbDevContext[256]; | |
}; | |
#define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS(a) CR (a, PEI_XHC_DEV, Usb2HostControllerPpi, USB_XHC_DEV_SIGNATURE) | |
#define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS_NOTIFY(a) CR (a, PEI_XHC_DEV, EndOfPeiNotifyList, USB_XHC_DEV_SIGNATURE) | |
/** | |
Initialize the memory management pool for the host controller. | |
@return Pointer to the allocated memory pool or NULL if failed. | |
**/ | |
USBHC_MEM_POOL * | |
UsbHcInitMemPool ( | |
VOID | |
) | |
; | |
/** | |
Release the memory management pool. | |
@param Pool The USB memory pool to free. | |
**/ | |
VOID | |
UsbHcFreeMemPool ( | |
IN USBHC_MEM_POOL *Pool | |
) | |
; | |
/** | |
Allocate some memory from the host controller's memory pool | |
which can be used to communicate with host controller. | |
@param Pool The host controller's memory pool. | |
@param Size Size of the memory to allocate. | |
@return The allocated memory or NULL. | |
**/ | |
VOID * | |
UsbHcAllocateMem ( | |
IN USBHC_MEM_POOL *Pool, | |
IN UINTN Size | |
) | |
; | |
/** | |
Free the allocated memory back to the memory pool. | |
@param Pool The memory pool of the host controller. | |
@param Mem The memory to free. | |
@param Size The size of the memory to free. | |
**/ | |
VOID | |
UsbHcFreeMem ( | |
IN USBHC_MEM_POOL *Pool, | |
IN VOID *Mem, | |
IN UINTN Size | |
) | |
; | |
/** | |
Initialize IOMMU. | |
**/ | |
VOID | |
IoMmuInit ( | |
VOID | |
); | |
/** | |
Provides the controller-specific addresses required to access system memory from a | |
DMA bus master. | |
@param Operation Indicates if the bus master is going to read or write to system memory. | |
@param HostAddress The system memory address to map to the PCI controller. | |
@param NumberOfBytes On input the number of bytes to map. On output the number of bytes | |
that were mapped. | |
@param DeviceAddress The resulting map address for the bus master PCI controller to use to | |
access the hosts HostAddress. | |
@param Mapping A resulting value to pass to Unmap(). | |
@retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. | |
@retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. | |
@retval EFI_INVALID_PARAMETER One or more parameters are invalid. | |
@retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. | |
@retval EFI_DEVICE_ERROR The system hardware could not map the requested address. | |
**/ | |
EFI_STATUS | |
IoMmuMap ( | |
IN EDKII_IOMMU_OPERATION Operation, | |
IN VOID *HostAddress, | |
IN OUT UINTN *NumberOfBytes, | |
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, | |
OUT VOID **Mapping | |
); | |
/** | |
Completes the Map() operation and releases any corresponding resources. | |
@param Mapping The mapping value returned from Map(). | |
@retval EFI_SUCCESS The range was unmapped. | |
@retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map(). | |
@retval EFI_DEVICE_ERROR The data was not committed to the target system memory. | |
**/ | |
EFI_STATUS | |
IoMmuUnmap ( | |
IN VOID *Mapping | |
); | |
/** | |
Allocates pages that are suitable for an OperationBusMasterCommonBuffer or | |
OperationBusMasterCommonBuffer64 mapping. | |
@param Pages The number of pages to allocate. | |
@param HostAddress A pointer to store the base system memory address of the | |
allocated range. | |
@param DeviceAddress The resulting map address for the bus master PCI controller to use to | |
access the hosts HostAddress. | |
@param Mapping A resulting value to pass to Unmap(). | |
@retval EFI_SUCCESS The requested memory pages were allocated. | |
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are | |
MEMORY_WRITE_COMBINE and MEMORY_CACHED. | |
@retval EFI_INVALID_PARAMETER One or more parameters are invalid. | |
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. | |
**/ | |
EFI_STATUS | |
IoMmuAllocateBuffer ( | |
IN UINTN Pages, | |
OUT VOID **HostAddress, | |
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, | |
OUT VOID **Mapping | |
); | |
/** | |
Frees memory that was allocated with AllocateBuffer(). | |
@param Pages The number of pages to free. | |
@param HostAddress The base system memory address of the allocated range. | |
@param Mapping The mapping value returned from Map(). | |
@retval EFI_SUCCESS The requested memory pages were freed. | |
@retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages | |
was not allocated with AllocateBuffer(). | |
**/ | |
EFI_STATUS | |
IoMmuFreeBuffer ( | |
IN UINTN Pages, | |
IN VOID *HostAddress, | |
IN VOID *Mapping | |
); | |
/** | |
Allocates aligned pages that are suitable for an OperationBusMasterCommonBuffer or | |
OperationBusMasterCommonBuffer64 mapping. | |
@param Pages The number of pages to allocate. | |
@param Alignment The requested alignment of the allocation. Must be a power of two. | |
@param HostAddress A pointer to store the base system memory address of the | |
allocated range. | |
@param DeviceAddress The resulting map address for the bus master PCI controller to use to | |
access the hosts HostAddress. | |
@param Mapping A resulting value to pass to Unmap(). | |
@retval EFI_SUCCESS The requested memory pages were allocated. | |
@retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are | |
MEMORY_WRITE_COMBINE and MEMORY_CACHED. | |
@retval EFI_INVALID_PARAMETER One or more parameters are invalid. | |
@retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. | |
**/ | |
EFI_STATUS | |
IoMmuAllocateAlignedBuffer ( | |
IN UINTN Pages, | |
IN UINTN Alignment, | |
OUT VOID **HostAddress, | |
OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, | |
OUT VOID **Mapping | |
); | |
#endif |