1/** @file
2Private Header file for Usb Host Controller PEIM
3
4Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
5
6This program and the accompanying materials
7are licensed and made available under the terms and conditions
8of the BSD License which accompanies this distribution.  The
9full text of the license may be found at
10http://opensource.org/licenses/bsd-license.php
11
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15**/
16
17#ifndef _RECOVERY_XHC_H_
18#define _RECOVERY_XHC_H_
19
20#include <PiPei.h>
21
22#include <Ppi/UsbController.h>
23#include <Ppi/Usb2HostController.h>
24
25#include <Library/DebugLib.h>
26#include <Library/PeimEntryPoint.h>
27#include <Library/PeiServicesLib.h>
28#include <Library/BaseMemoryLib.h>
29#include <Library/TimerLib.h>
30#include <Library/IoLib.h>
31#include <Library/MemoryAllocationLib.h>
32
33typedef struct _PEI_XHC_DEV PEI_XHC_DEV;
34typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT;
35
36#include "UsbHcMem.h"
37#include "XhciReg.h"
38#include "XhciSched.h"
39
40#define CMD_RING_TRB_NUMBER         0x100
41#define TR_RING_TRB_NUMBER          0x100
42#define ERST_NUMBER                 0x01
43#define EVENT_RING_TRB_NUMBER       0x200
44
45#define XHC_1_MICROSECOND           1
46#define XHC_1_MILLISECOND           (1000 * XHC_1_MICROSECOND)
47#define XHC_1_SECOND                (1000 * XHC_1_MILLISECOND)
48
49//
50// XHC reset timeout experience values.
51// The unit is millisecond, setting it as 1s.
52//
53#define XHC_RESET_TIMEOUT           (1000)
54
55//
56// Wait for root port state stable.
57//
58#define XHC_ROOT_PORT_STATE_STABLE  (200 * XHC_1_MILLISECOND)
59
60//
61// XHC generic timeout experience values.
62// The unit is millisecond, setting it as 10s.
63//
64#define XHC_GENERIC_TIMEOUT         (10 * 1000)
65
66#define XHC_LOW_32BIT(Addr64)       ((UINT32)(((UINTN)(Addr64)) & 0XFFFFFFFF))
67#define XHC_HIGH_32BIT(Addr64)      ((UINT32)(RShiftU64((UINTN)(Addr64), 32) & 0XFFFFFFFF))
68#define XHC_BIT_IS_SET(Data, Bit)   ((BOOLEAN)(((Data) & (Bit)) == (Bit)))
69
70#define XHC_REG_BIT_IS_SET(XHC, Offset, Bit) \
71          (XHC_BIT_IS_SET(XhcPeiReadOpReg ((XHC), (Offset)), (Bit)))
72
73#define USB_DESC_TYPE_HUB              0x29
74#define USB_DESC_TYPE_HUB_SUPER_SPEED  0x2a
75
76//
77// The RequestType in EFI_USB_DEVICE_REQUEST is composed of
78// three fields: One bit direction, 2 bit type, and 5 bit
79// target.
80//
81#define USB_REQUEST_TYPE(Dir, Type, Target) \
82          ((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target)))
83
84struct _USB_DEV_CONTEXT {
85  //
86  // Whether this entry in UsbDevContext array is used or not.
87  //
88  BOOLEAN                           Enabled;
89  //
90  // The slot id assigned to the new device through XHCI's Enable_Slot cmd.
91  //
92  UINT8                             SlotId;
93  //
94  // The route string presented an attached usb device.
95  //
96  USB_DEV_ROUTE                     RouteString;
97  //
98  // The route string of parent device if it exists. Otherwise it's zero.
99  //
100  USB_DEV_ROUTE                     ParentRouteString;
101  //
102  // The actual device address assigned by XHCI through Address_Device command.
103  //
104  UINT8                             XhciDevAddr;
105  //
106  // The requested device address from UsbBus driver through Set_Address standard usb request.
107  // As XHCI spec replaces this request with Address_Device command, we have to record the
108  // requested device address and establish a mapping relationship with the actual device address.
109  // Then UsbBus driver just need to be aware of the requested device address to access usb device
110  // through EFI_USB2_HC_PROTOCOL. Xhci driver would be responsible for translating it to actual
111  // device address and access the actual device.
112  //
113  UINT8                             BusDevAddr;
114  //
115  // The pointer to the input device context.
116  //
117  VOID                              *InputContext;
118  //
119  // The pointer to the output device context.
120  //
121  VOID                              *OutputContext;
122  //
123  // The transfer queue for every endpoint.
124  //
125  VOID                              *EndpointTransferRing[31];
126  //
127  // The device descriptor which is stored to support XHCI's Evaluate_Context cmd.
128  //
129  EFI_USB_DEVICE_DESCRIPTOR         DevDesc;
130  //
131  // As a usb device may include multiple configuration descriptors, we dynamically allocate an array
132  // to store them.
133  // Note that every configuration descriptor stored here includes those lower level descriptors,
134  // such as Interface descriptor, Endpoint descriptor, and so on.
135  // These information is used to support XHCI's Config_Endpoint cmd.
136  //
137  EFI_USB_CONFIG_DESCRIPTOR         **ConfDesc;
138};
139
140#define USB_XHC_DEV_SIGNATURE       SIGNATURE_32 ('x', 'h', 'c', 'i')
141
142struct _PEI_XHC_DEV {
143  UINTN                             Signature;
144  PEI_USB2_HOST_CONTROLLER_PPI      Usb2HostControllerPpi;
145  EFI_PEI_PPI_DESCRIPTOR            PpiDescriptor;
146  UINT32                            UsbHostControllerBaseAddress;
147  USBHC_MEM_POOL                    *MemPool;
148
149  //
150  // XHCI configuration data
151  //
152  UINT8                             CapLength;    ///< Capability Register Length
153  XHC_HCSPARAMS1                    HcSParams1;   ///< Structural Parameters 1
154  XHC_HCSPARAMS2                    HcSParams2;   ///< Structural Parameters 2
155  XHC_HCCPARAMS                     HcCParams;    ///< Capability Parameters
156  UINT32                            DBOff;        ///< Doorbell Offset
157  UINT32                            RTSOff;       ///< Runtime Register Space Offset
158  UINT32                            PageSize;
159  UINT32                            MaxScratchpadBufs;
160  UINT64                            *ScratchBuf;
161  UINT64                            *ScratchEntry;
162  UINT64                            *DCBAA;
163  UINT32                            MaxSlotsEn;
164  //
165  // Cmd Transfer Ring
166  //
167  TRANSFER_RING                     CmdRing;
168  //
169  // EventRing
170  //
171  EVENT_RING                        EventRing;
172
173  //
174  // Store device contexts managed by XHCI device
175  // The array supports up to 255 devices, entry 0 is reserved and should not be used.
176  //
177  USB_DEV_CONTEXT                   UsbDevContext[256];
178};
179
180#define PEI_RECOVERY_USB_XHC_DEV_FROM_THIS(a) CR (a, PEI_XHC_DEV, Usb2HostControllerPpi, USB_XHC_DEV_SIGNATURE)
181
182/**
183  Initialize the memory management pool for the host controller.
184
185  @return Pointer to the allocated memory pool or NULL if failed.
186
187**/
188USBHC_MEM_POOL *
189UsbHcInitMemPool (
190  VOID
191  )
192;
193
194/**
195  Release the memory management pool.
196
197  @param  Pool          The USB memory pool to free.
198
199**/
200VOID
201UsbHcFreeMemPool (
202  IN USBHC_MEM_POOL     *Pool
203  )
204;
205
206/**
207  Allocate some memory from the host controller's memory pool
208  which can be used to communicate with host controller.
209
210  @param  Pool          The host controller's memory pool.
211  @param  Size          Size of the memory to allocate.
212
213  @return The allocated memory or NULL.
214
215**/
216VOID *
217UsbHcAllocateMem (
218  IN USBHC_MEM_POOL     *Pool,
219  IN UINTN              Size
220  )
221;
222
223/**
224  Free the allocated memory back to the memory pool.
225
226  @param  Pool          The memory pool of the host controller.
227  @param  Mem           The memory to free.
228  @param  Size          The size of the memory to free.
229
230**/
231VOID
232UsbHcFreeMem (
233  IN USBHC_MEM_POOL     *Pool,
234  IN VOID               *Mem,
235  IN UINTN              Size
236  )
237;
238
239#endif
240