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