summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Bus/Pci/XhciDxe/Xhci.h
blob: 953ba4c5c213fee32334d310666a6fadebad1ef3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
/** @file

  Provides some data structure definitions used by the XHCI host controller driver.

Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which 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.

**/

#ifndef _EFI_XHCI_H_
#define _EFI_XHCI_H_

#include <Uefi.h>

#include <Protocol/Usb2HostController.h>
#include <Protocol/PciIo.h>

#include <Guid/EventGroup.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiLib.h>
#include <Library/PcdLib.h>
#include <Library/DebugLib.h>

#include <IndustryStandard/Pci.h>

typedef struct _USB_XHCI_DEV    USB_XHCI_DEV;
typedef struct _USB_DEV_CONTEXT USB_DEV_CONTEXT;

#include "XhciReg.h"
#include "XhciSched.h"
#include "ComponentName.h"

//
// XHC timeout experience values
//
#define XHC_1_MICROSECOND            1
#define XHC_1_MILLISECOND            (1000 * XHC_1_MICROSECOND)
#define XHC_1_SECOND                 (1000 * XHC_1_MILLISECOND)

//
// XHCI register operation timeout, set by experience
//
#define XHC_RESET_TIMEOUT            (1 * XHC_1_SECOND)
#define XHC_GENERIC_TIMEOUT          (10 * XHC_1_MILLISECOND)

//
// Wait for roothub port power stable, refers to Spec[XHCI1.0-2.3.9]
//
#define XHC_ROOT_PORT_RECOVERY_STALL (20 * XHC_1_MILLISECOND)

//
// Sync and Async transfer polling interval, set by experience,
// and the unit of Async is 100us, means 50ms as interval.
//
#define XHC_SYNC_POLL_INTERVAL       (20 * XHC_1_MILLISECOND)
#define XHC_ASYNC_POLL_INTERVAL      (50 * 10000U)

//
// XHC raises TPL to TPL_NOTIFY to serialize all its operations
// to protect shared data structures.
//
#define XHC_TPL                      TPL_NOTIFY

#define CMD_RING_TRB_NUMBER          0x40
#define TR_RING_TRB_NUMBER           0x40
#define ERST_NUMBER                  0x01
#define EVENT_RING_TRB_NUMBER        0x80

#define CMD_INTER                    0
#define CTRL_INTER                   1
#define BULK_INTER                   2
#define INT_INTER                    3
#define INT_INTER_ASYNC              4

//
// Iterate through the doule linked list. This is delete-safe.
// Don't touch NextEntry
//
#define EFI_LIST_FOR_EACH_SAFE(Entry, NextEntry, ListHead) \
  for (Entry = (ListHead)->ForwardLink, NextEntry = Entry->ForwardLink;\
      Entry != (ListHead); Entry = NextEntry, NextEntry = Entry->ForwardLink)

#define EFI_LIST_CONTAINER(Entry, Type, Field) BASE_CR(Entry, Type, Field)

#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(XhcReadOpReg ((Xhc), (Offset)), (Bit)))

#define XHCI_IS_DATAIN(EndpointAddr) XHC_BIT_IS_SET((EndpointAddr), 0x80)

#define USB_XHCI_DEV_SIGNATURE       SIGNATURE_32 ('x', 'h', 'c', 'i')
#define XHC_FROM_THIS(a)             CR(a, USB_XHCI_DEV, Usb2Hc, USB_XHCI_DEV_SIGNATURE)

#define USB_DESC_TYPE_HUB              0x29
#define USB_DESC_TYPE_HUB_SUPER_SPEED  0x2a

//
// Xhci Data and Ctrl Structures
//
#pragma pack(1)
typedef struct {
  UINT8                     ProgInterface;
  UINT8                     SubClassCode;
  UINT8                     BaseCode;
} USB_CLASSC;

typedef struct {
  UINT8                     Length;
  UINT8                     DescType;
  UINT8                     NumPorts;
  UINT16                    HubCharacter;
  UINT8                     PwrOn2PwrGood;
  UINT8                     HubContrCurrent;
  UINT8                     Filler[16];
} EFI_USB_HUB_DESCRIPTOR;
#pragma pack()

struct _USB_XHCI_DEV {
  UINT32                    Signature;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINT64                    OriginalPciAttributes;

  EFI_USB2_HC_PROTOCOL      Usb2Hc;

  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  //
  // ExitBootServicesEvent is used to set OS semaphore and
  // stop the XHC DMA operation after exit boot service.
  //
  EFI_EVENT                 ExitBootServiceEvent;
  EFI_EVENT                 PollTimer;
  LIST_ENTRY                AsyncIntTransfers;

  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
  UINT16                    MaxInterrupt;
  UINT32                    PageSize;
  UINT64                    *ScratchBuf;
  UINT32                    MaxScratchpadBufs;
  UINT32                    ExtCapRegBase;
  UINT32                    UsbLegSupOffset;
  UINT64                    *DCBAA;
  UINT32                    MaxSlotsEn;
  //
  // Cmd Transfer Ring
  //
  TRANSFER_RING             CmdRing;
  //
  // CmdEventRing
  //
  EVENT_RING                CmdEventRing;
  //
  // ControlTREventRing
  //
  EVENT_RING                CtrlTrEventRing;
  //
  // BulkTREventRing
  //
  EVENT_RING                BulkTrEventRing;
  //
  // IntTREventRing
  //
  EVENT_RING                IntTrEventRing;
  //
  // AsyncIntTREventRing
  //
  EVENT_RING                AsynIntTrEventRing;
  //
  // Misc
  //
  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;

};

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                      *OutputDevContxt;
  //
  // 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;
};

extern EFI_DRIVER_BINDING_PROTOCOL      gXhciDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL      gXhciComponentName;
extern EFI_COMPONENT_NAME2_PROTOCOL     gXhciComponentName2;
extern USB_DEV_CONTEXT                  UsbDevContext[];

/**
  Test to see if this driver supports ControllerHandle. Any
  ControllerHandle that has Usb2HcProtocol installed will
  be supported.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to test.
  @param  RemainingDevicePath  Not used.

  @return EFI_SUCCESS          This driver supports this device.
  @return EFI_UNSUPPORTED      This driver does not support this device.

**/
EFI_STATUS
EFIAPI
XhcDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
  );

/**
  Starting the Usb XHCI Driver.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to test.
  @param  RemainingDevicePath  Not used.

  @return EFI_SUCCESS          supports this device.
  @return EFI_UNSUPPORTED      do not support this device.
  @return EFI_DEVICE_ERROR     cannot be started due to device Error.
  @return EFI_OUT_OF_RESOURCES cannot allocate resources.

**/
EFI_STATUS
EFIAPI
XhcDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
  );

/**
  Stop this driver on ControllerHandle. Support stoping any child handles
  created by this driver.

  @param  This                 Protocol instance pointer.
  @param  Controller           Handle of device to stop driver on.
  @param  NumberOfChildren     Number of Children in the ChildHandleBuffer.
  @param  ChildHandleBuffer    List of handles for the children we need to stop.

  @return EFI_SUCCESS          Success.
  @return EFI_DEVICE_ERROR     Fail.

**/
EFI_STATUS
EFIAPI
XhcDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL *This,
  IN EFI_HANDLE                  Controller,
  IN UINTN                       NumberOfChildren,
  IN EFI_HANDLE                  *ChildHandleBuffer
  );

/**
  Sets a feature for the specified root hub port.

  @param  This                  This EFI_USB2_HC_PROTOCOL instance.
  @param  PortNumber            Root hub port to set.
  @param  PortFeature           Feature to set.

  @retval EFI_SUCCESS           The feature specified by PortFeature was set.
  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
  @retval EFI_DEVICE_ERROR      Can't read register.

**/
EFI_STATUS
EFIAPI
XhcSetRootHubPortFeature (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT8                 PortNumber,
  IN EFI_USB_PORT_FEATURE  PortFeature
  );

/**
  Clears a feature for the specified root hub port.

  @param  This                  A pointer to the EFI_USB2_HC_PROTOCOL instance.
  @param  PortNumber            Specifies the root hub port whose feature is
                                requested to be cleared.
  @param  PortFeature           Indicates the feature selector associated with the
                                feature clear request.

  @retval EFI_SUCCESS           The feature specified by PortFeature was cleared
                                for the USB root hub port specified by PortNumber.
  @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.
  @retval EFI_DEVICE_ERROR      Can't read register.

**/
EFI_STATUS
EFIAPI
XhcClearRootHubPortFeature (
  IN EFI_USB2_HC_PROTOCOL  *This,
  IN UINT8                 PortNumber,
  IN EFI_USB_PORT_FEATURE  PortFeature
  );

#endif