1 /** @file 2 Private Header file for Usb Host Controller PEIM 3 4 Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> 5 6 SPDX-License-Identifier: BSD-2-Clause-Patent 7 8 **/ 9 10 #ifndef _RECOVERY_XHC_H_ 11 #define _RECOVERY_XHC_H_ 12 13 #include <PiPei.h> 14 15 #include <Ppi/UsbController.h> 16 #include <Ppi/Usb2HostController.h> 17 #include <Ppi/IoMmu.h> 18 #include <Ppi/EndOfPeiPhase.h> 19 20 #include <Library/DebugLib.h> 21 #include <Library/PeimEntryPoint.h> 22 #include <Library/PeiServicesLib.h> 23 #include <Library/BaseMemoryLib.h> 24 #include <Library/TimerLib.h> 25 #include <Library/IoLib.h> 26 #include <Library/MemoryAllocationLib.h> 27 28 typedef struct _PEI_XHC_DEV PEI_XHC_DEV; 29 typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT; 30 31 #include "UsbHcMem.h" 32 #include "XhciReg.h" 33 #include "XhciSched.h" 34 35 #define CMD_RING_TRB_NUMBER 0x100 36 #define TR_RING_TRB_NUMBER 0x100 37 #define ERST_NUMBER 0x01 38 #define EVENT_RING_TRB_NUMBER 0x200 39 40 #define XHC_1_MICROSECOND 1 41 #define XHC_1_MILLISECOND (1000 * XHC_1_MICROSECOND) 42 #define XHC_1_SECOND (1000 * XHC_1_MILLISECOND) 43 44 // 45 // XHC reset timeout experience values. 46 // The unit is millisecond, setting it as 1s. 47 // 48 #define XHC_RESET_TIMEOUT (1000) 49 50 // 51 // TRSTRCY delay requirement in usb 2.0 spec chapter 7.1.7.5. 52 // The unit is microsecond, setting it as 10ms. 53 // 54 #define XHC_RESET_RECOVERY_DELAY (10 * 1000) 55 56 // 57 // Wait for root port state stable. 58 // 59 #define XHC_ROOT_PORT_STATE_STABLE (200 * XHC_1_MILLISECOND) 60 61 // 62 // XHC generic timeout experience values. 63 // The unit is millisecond, setting it as 10s. 64 // 65 #define XHC_GENERIC_TIMEOUT (10 * 1000) 66 67 #define XHC_LOW_32BIT(Addr64) ((UINT32)(((UINTN)(Addr64)) & 0XFFFFFFFF)) 68 #define XHC_HIGH_32BIT(Addr64) ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF)) 69 #define XHC_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit))) 70 71 #define XHC_REG_BIT_IS_SET(XHC, Offset, Bit) \ 72 (XHC_BIT_IS_SET(XhcPeiReadOpReg ((XHC), (Offset)), (Bit))) 73 74 #define USB_DESC_TYPE_HUB 0x29 75 #define USB_DESC_TYPE_HUB_SUPER_SPEED 0x2a 76 77 // 78 // The RequestType in EFI_USB_DEVICE_REQUEST is composed of 79 // three fields: One bit direction, 2 bit type, and 5 bit 80 // target. 81 // 82 #define USB_REQUEST_TYPE(Dir, Type, Target) \ 83 ((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target))) 84 85 struct _USB_DEV_CONTEXT { 86 // 87 // Whether this entry in UsbDevContext array is used or not. 88 // 89 BOOLEAN Enabled; 90 // 91 // The slot id assigned to the new device through XHCI's Enable_Slot cmd. 92 // 93 UINT8 SlotId; 94 // 95 // The route string presented an attached usb device. 96 // 97 USB_DEV_ROUTE RouteString; 98 // 99 // The route string of parent device if it exists. Otherwise it's zero. 100 // 101 USB_DEV_ROUTE ParentRouteString; 102 // 103 // The actual device address assigned by XHCI through Address_Device command. 104 // 105 UINT8 XhciDevAddr; 106 // 107 // The requested device address from UsbBus driver through Set_Address standard usb request. 108 // As XHCI spec replaces this request with Address_Device command, we have to record the 109 // requested device address and establish a mapping relationship with the actual device address. 110 // Then UsbBus driver just need to be aware of the requested device address to access usb device 111 // through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual 112 // device address and access the actual device. 113 // 114 UINT8 BusDevAddr; 115 // 116 // The pointer to the input device context. 117 // 118 VOID *InputContext; 119 // 120 // The pointer to the output device context. 121 // 122 VOID *OutputContext; 123 // 124 // The transfer queue for every endpoint. 125 // 126 VOID *EndpointTransferRing[31]; 127 // 128 // The device descriptor which is stored to support XHCI's Evaluate_Context cmd. 129 // 130 EFI_USB_DEVICE_DESCRIPTOR DevDesc; 131 // 132 // As a usb device may include multiple configuration descriptors, we dynamically allocate an array 133 // to store them. 134 // Note that every configuration descriptor stored here includes those lower level descriptors, 135 // such as Interface descriptor, Endpoint descriptor, and so on. 136 // These information is used to support XHCI's Config_Endpoint cmd. 137 // 138 EFI_USB_CONFIG_DESCRIPTOR **ConfDesc; 139 }; 140 141 #define USB_XHC_DEV_SIGNATURE SIGNATURE_32 ('x', 'h', 'c', 'i') 142 143 struct _PEI_XHC_DEV { 144 UINTN Signature; 145 PEI_USB2_HOST_CONTROLLER_PPI Usb2HostControllerPpi; 146 EFI_PEI_PPI_DESCRIPTOR PpiDescriptor; 147 UINT32 UsbHostControllerBaseAddress; 148 USBHC_MEM_POOL *MemPool; 149 150 // 151 // EndOfPei callback is used to stop the XHC DMA operation 152 // after exit PEI phase. 153 // 154 EFI_PEI_NOTIFY_DESCRIPTOR EndOfPeiNotifyList; 155 156 // 157 // XHCI configuration data 158 // 159 UINT8 CapLength; ///< Capability Register Length 160 XHC_HCSPARAMS1 HcSParams1; ///< Structural Parameters 1 161 XHC_HCSPARAMS2 HcSParams2; ///< Structural Parameters 2 162 XHC_HCCPARAMS HcCParams; ///< Capability Parameters 163 UINT32 DBOff; ///< Doorbell Offset 164 UINT32 RTSOff; ///< Runtime Register Space Offset 165 UINT32 PageSize; 166 UINT32 MaxScratchpadBufs; 167 UINT64 *ScratchBuf; 168 VOID *ScratchMap; 169 UINT64 *ScratchEntry; 170 UINTN *ScratchEntryMap; 171 UINT64 *DCBAA; 172 UINT32 MaxSlotsEn; 173 // 174 // Cmd Transfer Ring 175 // 176 TRANSFER_RING CmdRing; 177 // 178 // EventRing 179 // 180 EVENT_RING EventRing; 181 182 // 183 // Store device contexts managed by XHCI device 184 // The array supports up to 255 devices, entry 0 is reserved and should not be used. 185 // 186 USB_DEV_CONTEXT UsbDevContext[256]; 187 }; 188 189 #define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS(a) CR (a, PEI_XHC_DEV, Usb2HostControllerPpi, USB_XHC_DEV_SIGNATURE) 190 #define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS_NOTIFY(a) CR (a, PEI_XHC_DEV, EndOfPeiNotifyList, USB_XHC_DEV_SIGNATURE) 191 192 /** 193 Initialize the memory management pool for the host controller. 194 195 @return Pointer to the allocated memory pool or NULL if failed. 196 197 **/ 198 USBHC_MEM_POOL * 199 UsbHcInitMemPool ( 200 VOID 201 ) 202 ; 203 204 /** 205 Release the memory management pool. 206 207 @param Pool The USB memory pool to free. 208 209 **/ 210 VOID 211 UsbHcFreeMemPool ( 212 IN USBHC_MEM_POOL *Pool 213 ) 214 ; 215 216 /** 217 Allocate some memory from the host controller's memory pool 218 which can be used to communicate with host controller. 219 220 @param Pool The host controller's memory pool. 221 @param Size Size of the memory to allocate. 222 223 @return The allocated memory or NULL. 224 225 **/ 226 VOID * 227 UsbHcAllocateMem ( 228 IN USBHC_MEM_POOL *Pool, 229 IN UINTN Size 230 ) 231 ; 232 233 /** 234 Free the allocated memory back to the memory pool. 235 236 @param Pool The memory pool of the host controller. 237 @param Mem The memory to free. 238 @param Size The size of the memory to free. 239 240 **/ 241 VOID 242 UsbHcFreeMem ( 243 IN USBHC_MEM_POOL *Pool, 244 IN VOID *Mem, 245 IN UINTN Size 246 ) 247 ; 248 249 250 /** 251 Initialize IOMMU. 252 **/ 253 VOID 254 IoMmuInit ( 255 VOID 256 ); 257 258 /** 259 Provides the controller-specific addresses required to access system memory from a 260 DMA bus master. 261 262 @param Operation Indicates if the bus master is going to read or write to system memory. 263 @param HostAddress The system memory address to map to the PCI controller. 264 @param NumberOfBytes On input the number of bytes to map. On output the number of bytes 265 that were mapped. 266 @param DeviceAddress The resulting map address for the bus master PCI controller to use to 267 access the hosts HostAddress. 268 @param Mapping A resulting value to pass to Unmap(). 269 270 @retval EFI_SUCCESS The range was mapped for the returned NumberOfBytes. 271 @retval EFI_UNSUPPORTED The HostAddress cannot be mapped as a common buffer. 272 @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 273 @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources. 274 @retval EFI_DEVICE_ERROR The system hardware could not map the requested address. 275 276 **/ 277 EFI_STATUS 278 IoMmuMap ( 279 IN EDKII_IOMMU_OPERATION Operation, 280 IN VOID *HostAddress, 281 IN OUT UINTN *NumberOfBytes, 282 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, 283 OUT VOID **Mapping 284 ); 285 286 /** 287 Completes the Map() operation and releases any corresponding resources. 288 289 @param Mapping The mapping value returned from Map(). 290 291 @retval EFI_SUCCESS The range was unmapped. 292 @retval EFI_INVALID_PARAMETER Mapping is not a value that was returned by Map(). 293 @retval EFI_DEVICE_ERROR The data was not committed to the target system memory. 294 **/ 295 EFI_STATUS 296 IoMmuUnmap ( 297 IN VOID *Mapping 298 ); 299 300 /** 301 Allocates pages that are suitable for an OperationBusMasterCommonBuffer or 302 OperationBusMasterCommonBuffer64 mapping. 303 304 @param Pages The number of pages to allocate. 305 @param HostAddress A pointer to store the base system memory address of the 306 allocated range. 307 @param DeviceAddress The resulting map address for the bus master PCI controller to use to 308 access the hosts HostAddress. 309 @param Mapping A resulting value to pass to Unmap(). 310 311 @retval EFI_SUCCESS The requested memory pages were allocated. 312 @retval EFI_UNSUPPORTED Attributes is unsupported. The only legal attribute bits are 313 MEMORY_WRITE_COMBINE and MEMORY_CACHED. 314 @retval EFI_INVALID_PARAMETER One or more parameters are invalid. 315 @retval EFI_OUT_OF_RESOURCES The memory pages could not be allocated. 316 317 **/ 318 EFI_STATUS 319 IoMmuAllocateBuffer ( 320 IN UINTN Pages, 321 OUT VOID **HostAddress, 322 OUT EFI_PHYSICAL_ADDRESS *DeviceAddress, 323 OUT VOID **Mapping 324 ); 325 326 /** 327 Frees memory that was allocated with AllocateBuffer(). 328 329 @param Pages The number of pages to free. 330 @param HostAddress The base system memory address of the allocated range. 331 @param Mapping The mapping value returned from Map(). 332 333 @retval EFI_SUCCESS The requested memory pages were freed. 334 @retval EFI_INVALID_PARAMETER The memory range specified by HostAddress and Pages 335 was not allocated with AllocateBuffer(). 336 337 **/ 338 EFI_STATUS 339 IoMmuFreeBuffer ( 340 IN UINTN Pages, 341 IN VOID *HostAddress, 342 IN VOID *Mapping 343 ); 344 345 #endif 346