2 * This file is part of the libpayload project.
4 * Copyright (C) 2010 Patrick Georgi
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #ifndef __XHCI_PRIVATE_H
31 #define __XHCI_PRIVATE_H
35 #define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
37 typedef volatile union trb {
41 #define TRB_EV_CMD_CMPL 33
43 u32 Cmd_TRB_Pointer_lo;
44 u32 Cmd_TRB_Pointer_hi;
47 unsigned long Completion_Code:8;
48 } __attribute__ ((packed));
52 unsigned long TRB_Type:6;
53 unsigned long VF_ID:8;
54 unsigned long Slot_ID:8;
55 } __attribute__ ((packed));
56 } __attribute__ ((packed)) event_cmd_cmpl;
58 #define TRB_EV_PORTSC 34
63 } __attribute__ ((packed));
67 unsigned long Completion_Code:8;
68 } __attribute__ ((packed));
72 unsigned long TRB_Type:6;
74 } __attribute__ ((packed));
75 } __attribute__ ((packed)) event_portsc;
78 #define TRB_CMD_NOOP 23
84 unsigned long TRB_Type:6;
86 } __attribute__ ((packed));
87 } __attribute__ ((packed)) cmd_No_Op;
91 u32 Ring_Segment_Ptr_lo;
92 u32 Ring_Segment_Ptr_hi;
95 unsigned long Interrupter_Target;
96 } __attribute__ ((packed));
104 unsigned long TRB_Type:6;
106 } __attribute__ ((packed));
107 } __attribute__ ((packed)) link;
110 typedef struct slotctx {
112 unsigned long Route_String:20;
113 unsigned long Speed:4;
117 unsigned long Context_Entries:5;
118 } __attribute__ ((packed));
120 unsigned long Max_Exit_Latency:16;
121 unsigned long Root_Hub_Port_Number:8;
122 unsigned long Number_of_Ports:8;
123 } __attribute__ ((packed));
125 unsigned long TT_Hub_Slot_ID:8;
126 unsigned long TT_Port_Number:8;
129 unsigned long Interrupter_Target:10;
130 } __attribute__ ((packed));
132 unsigned long USB_Device_Address:8;
134 unsigned long Slot_State:5;
135 } __attribute__ ((packed));
139 typedef struct epctx {
141 unsigned long EP_State:3;
143 unsigned long Mult:2;
144 unsigned long MaxPStreams:5;
146 unsigned long Interval:8;
148 } __attribute__ ((packed));
151 unsigned long CErr:2;
152 unsigned long EP_Type:3;
155 unsigned long Max_Burst_Size:8;
156 unsigned long Max_Packet_Size:16;
157 } __attribute__ ((packed));
159 u32 TR_Dequeue_Pointer_lo;
163 } __attribute__ ((packed));
164 } __attribute__ ((packed));
165 u32 TR_Dequeue_Pointer_hi;
167 unsigned long Average_TRB_Length:16;
168 unsigned long Max_ESIT_Payload:16;
169 } __attribute__ ((packed));
173 typedef struct devctx {
182 typedef struct devctxp {
187 typedef struct erst_entry {
194 typedef struct xhci {
195 /* capreg is read-only, so no need for volatile,
196 and thus 32bit accesses can be assumed. */
205 } __attribute__ ((packed));
206 } __attribute__ ((packed));
210 unsigned long MaxSlots:7;
211 unsigned long MaxIntrs:11;
213 unsigned long MaxPorts:8;
214 } __attribute__ ((packed));
215 } __attribute__ ((packed));
220 unsigned long ERST_Max:4;
223 unsigned long Max_Scratchpad_Bufs:5;
224 } __attribute__ ((packed));
225 } __attribute__ ((packed));
229 unsigned long u1latency:8;
231 unsigned long u2latency:16;
232 } __attribute__ ((packed));
233 } __attribute__ ((packed));
237 unsigned long ac64:1;
241 unsigned long pind:1;
242 unsigned long lhrc:1;
246 unsigned long MaxPSASize:4;
247 unsigned long xECP:16;
248 } __attribute__ ((packed));
249 } __attribute__ ((packed));
252 } __attribute__ ((packed)) *capreg;
254 /* opreg is R/W is most places, so volatile access is necessary.
255 volatile means that the compiler seeks byte writes if possible,
256 making bitfields unusable for MMIO register blocks. Yay C :-( */
257 volatile struct opreg {
259 #define USBCMD_RS 1<<0
260 #define USBCMD_HCRST 1<<1
262 #define USBSTS_HCH 1<<0
263 #define USBSTS_HSE 1<<2
264 #define USBSTS_EINT 1<<3
265 #define USBSTS_PCD 1<<4
266 #define USBSTS_CNR 1<<11
268 u8 res1[0x13-0x0c+1];
272 #define CRCR_RCS 1<<0
275 #define CRCR_CRR 1<<3
276 u8 res2[0x2f-0x20+1];
280 #define CONFIG_MASK_MaxSlotsEn 0xff
281 u8 res3[0x3ff-0x3c+1];
284 #define PORTSC_CCS 1<<0
285 #define PORTSC_PED 1<<1
287 #define PORTSC_OCA 1<<3
288 #define PORTSC_PR 1<<4
289 #define PORTSC_PLS 1<<5
290 #define PORTSC_PLS_MASK MASK(5, 4)
291 #define PORTSC_PP 1<<9
292 #define PORTSC_PORT_SPEED 1<<10
293 #define PORTSC_PORT_SPEED_MASK MASK(10, 4)
294 #define PORTSC_PIC 1<<14
295 #define PORTSC_PIC_MASK MASK(14, 2)
296 #define PORTSC_LWS 1<<16
297 #define PORTSC_CSC 1<<17
298 #define PORTSC_PEC 1<<18
299 #define PORTSC_WRC 1<<19
300 #define PORTSC_OCC 1<<20
301 #define PORTSC_PRC 1<<21
302 #define PORTSC_PLC 1<<22
303 #define PORTSC_CEC 1<<23
304 #define PORTSC_CAS 1<<24
305 #define PORTSC_WCE 1<<25
306 #define PORTSC_WDE 1<<26
307 #define PORTSC_WOE 1<<27
309 #define PORTSC_DR 1<<30
310 #define PORTSC_WPR 1<<31
311 #define PORTSC_RW_MASK PORTSC_PR | PORTSC_PLS_MASK | PORTSC_PP | PORTSC_PIC_MASK | PORTSC_LWS | PORTSC_WCE | PORTSC_WDE | PORTSC_WOE
315 } __attribute__ ((packed)) prs[];
316 } __attribute__ ((packed)) *opreg;
318 /* R/W, volatile, MMIO -> no bitfields */
319 volatile struct hcrreg {
331 } __attribute__ ((packed)) intrrs[]; // up to 1024, but maximum host specific, given in capreg->MaxIntrs
332 } __attribute__ ((packed)) *hcrreg;
334 /* R/W, volatile, MMIO -> no bitfields */
337 /* R/W, volatile, Memory -> bitfields allowed */
338 volatile devctxp_t *dcbaa;
342 volatile erst_entry_t *ev_ring_table;
348 #define XHCI_INST(controller) ((xhci_t*)((controller)->instance))