blob: 16834f77cc0fc402a29997fcef5a1d0a50e5ccc9 [file] [log] [blame]
Patrick Georgi6615ef32010-08-13 09:18:58 +00001/*
2 * This file is part of the libpayload project.
3 *
4 * Copyright (C) 2010 Patrick Georgi
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
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.
16 *
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
27 * SUCH DAMAGE.
28 */
29
30#ifndef __XHCI_PRIVATE_H
31#define __XHCI_PRIVATE_H
32
33#include <usb/usb.h>
34
35#define MASK(startbit, lenbit) (((1<<(lenbit))-1)<<(startbit))
36
37typedef volatile union trb {
38 // transfer
39
40 // events
41#define TRB_EV_CMD_CMPL 33
42 struct {
43 u32 Cmd_TRB_Pointer_lo;
44 u32 Cmd_TRB_Pointer_hi;
45 struct {
46 unsigned long:24;
47 unsigned long Completion_Code:8;
48 } __attribute__ ((packed));
49 struct {
50 unsigned long C:1;
51 unsigned long:9;
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;
57
58#define TRB_EV_PORTSC 34
59 struct {
60 struct {
61 unsigned long:24;
62 unsigned long Port:8;
63 } __attribute__ ((packed));
64 u32 rsvd;
65 struct {
66 unsigned long:24;
67 unsigned long Completion_Code:8;
68 } __attribute__ ((packed));
69 struct {
70 unsigned long C:1;
71 unsigned long:9;
72 unsigned long TRB_Type:6;
73 unsigned long:16;
74 } __attribute__ ((packed));
75 } __attribute__ ((packed)) event_portsc;
76
77 // commands
78#define TRB_CMD_NOOP 23
79 struct {
80 u32 rsvd[3];
81 struct {
82 unsigned long C:1;
83 unsigned long:9;
84 unsigned long TRB_Type:6;
85 unsigned long:16;
86 } __attribute__ ((packed));
87 } __attribute__ ((packed)) cmd_No_Op;
88
89 // "others"
90 struct {
91 u32 Ring_Segment_Ptr_lo;
92 u32 Ring_Segment_Ptr_hi;
93 struct {
94 unsigned long:22;
95 unsigned long Interrupter_Target;
96 } __attribute__ ((packed));
97 struct {
98 unsigned long C:1;
99 unsigned long TC:1;
100 unsigned long:2;
101 unsigned long CH:1;
102 unsigned long IOC:1;
103 unsigned long:4;
104 unsigned long TRB_Type:6;
105 unsigned long:16;
106 } __attribute__ ((packed));
107 } __attribute__ ((packed)) link;
108} trb_t;
109
110typedef struct slotctx {
111 struct {
112 unsigned long Route_String:20;
113 unsigned long Speed:4;
114 unsigned long:1;
115 unsigned long MTT:1;
116 unsigned long Hub:1;
117 unsigned long Context_Entries:5;
118 } __attribute__ ((packed));
119 struct {
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));
124 struct {
125 unsigned long TT_Hub_Slot_ID:8;
126 unsigned long TT_Port_Number:8;
127 unsigned long TTT:2;
128 unsigned long:4;
129 unsigned long Interrupter_Target:10;
130 } __attribute__ ((packed));
131 struct {
132 unsigned long USB_Device_Address:8;
133 unsigned long:19;
134 unsigned long Slot_State:5;
135 } __attribute__ ((packed));
136 u32 rsvd[4];
137} slotctx_t;
138
139typedef struct epctx {
140 struct {
141 unsigned long EP_State:3;
142 unsigned long:5;
143 unsigned long Mult:2;
144 unsigned long MaxPStreams:5;
145 unsigned long LSA:1;
146 unsigned long Interval:8;
147 unsigned long:8;
148 } __attribute__ ((packed));
149 struct {
150 unsigned long:1;
151 unsigned long CErr:2;
152 unsigned long EP_Type:3;
153 unsigned long:1;
154 unsigned long HID:1;
155 unsigned long Max_Burst_Size:8;
156 unsigned long Max_Packet_Size:16;
157 } __attribute__ ((packed));
158 union {
159 u32 TR_Dequeue_Pointer_lo;
160 struct {
161 unsigned long DCS:1;
162 unsigned long:3;
163 } __attribute__ ((packed));
164 } __attribute__ ((packed));
165 u32 TR_Dequeue_Pointer_hi;
166 struct {
167 unsigned long Average_TRB_Length:16;
168 unsigned long Max_ESIT_Payload:16;
169 } __attribute__ ((packed));
170 u32 rsvd[3];
171} epctx_t;
172
173typedef struct devctx {
174 slotctx_t slot;
175 epctx_t ep0;
176 struct {
177 epctx_t out;
178 epctx_t in;
179 } eps[15];
180} devctx_t;
181
182typedef struct devctxp {
183 devctx_t *ptr;
184 void *upper;
185} devctxp_t;
186
187typedef struct erst_entry {
188 u32 seg_base_lo;
189 u32 seg_base_hi;
190 u32 seg_size;
191 u32 rsvd;
192} erst_entry_t;
193
194typedef struct xhci {
195 /* capreg is read-only, so no need for volatile,
196 and thus 32bit accesses can be assumed. */
197 struct capreg {
198 u8 caplength;
199 u8 res1;
200 union {
201 u16 hciversion;
202 struct {
203 u8 hciver_lo;
204 u8 hciver_hi;
205 } __attribute__ ((packed));
206 } __attribute__ ((packed));
207 union {
208 u32 hcsparams1;
209 struct {
210 unsigned long MaxSlots:7;
211 unsigned long MaxIntrs:11;
212 unsigned long:6;
213 unsigned long MaxPorts:8;
214 } __attribute__ ((packed));
215 } __attribute__ ((packed));
216 union {
217 u32 hcsparams2;
218 struct {
219 unsigned long IST:4;
220 unsigned long ERST_Max:4;
221 unsigned long:18;
222 unsigned long SPR:1;
223 unsigned long Max_Scratchpad_Bufs:5;
224 } __attribute__ ((packed));
225 } __attribute__ ((packed));
226 union {
227 u32 hcsparams3;
228 struct {
229 unsigned long u1latency:8;
230 unsigned long:8;
231 unsigned long u2latency:16;
232 } __attribute__ ((packed));
233 } __attribute__ ((packed));
234 union {
235 u32 hccparams;
236 struct {
237 unsigned long ac64:1;
238 unsigned long bnc:1;
239 unsigned long csz:1;
240 unsigned long ppc:1;
241 unsigned long pind:1;
242 unsigned long lhrc:1;
243 unsigned long ltc:1;
244 unsigned long nss:1;
245 unsigned long:4;
246 unsigned long MaxPSASize:4;
247 unsigned long xECP:16;
248 } __attribute__ ((packed));
249 } __attribute__ ((packed));
250 u32 dboff;
251 u32 rtsoff;
252 } __attribute__ ((packed)) *capreg;
253
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 {
258 u32 usbcmd;
259#define USBCMD_RS 1<<0
260#define USBCMD_HCRST 1<<1
261 u32 usbsts;
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
267 u32 pagesize;
268 u8 res1[0x13-0x0c+1];
269 u32 dnctrl;
270 u32 crcr_lo;
271 u32 crcr_hi;
272#define CRCR_RCS 1<<0
273#define CRCR_CS 1<<1
274#define CRCR_CA 1<<2
275#define CRCR_CRR 1<<3
276 u8 res2[0x2f-0x20+1];
277 u32 dcbaap_lo;
278 u32 dcbaap_hi;
279 u32 config;
280#define CONFIG_MASK_MaxSlotsEn 0xff
281 u8 res3[0x3ff-0x3c+1];
282 struct {
283 u32 portsc;
284#define PORTSC_CCS 1<<0
285#define PORTSC_PED 1<<1
286 // BIT 2 rsvdZ
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
308 // BIT 29:28 rsvdZ
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
312 u32 portpmsc;
313 u32 portli;
314 u32 res;
315 } __attribute__ ((packed)) prs[];
316 } __attribute__ ((packed)) *opreg;
317
318 /* R/W, volatile, MMIO -> no bitfields */
319 volatile struct hcrreg {
320 u32 mfindex;
321 u8 res1[0x20-0x4];
322 struct {
323 u32 iman;
324 u32 imod;
325 u32 erstsz;
326 u32 res;
327 u32 erstba_lo;
328 u32 erstba_hi;
329 u32 erdp_lo;
330 u32 erdp_hi;
331 } __attribute__ ((packed)) intrrs[]; // up to 1024, but maximum host specific, given in capreg->MaxIntrs
332 } __attribute__ ((packed)) *hcrreg;
333
334 /* R/W, volatile, MMIO -> no bitfields */
335 volatile u32 *dbreg;
336
337 /* R/W, volatile, Memory -> bitfields allowed */
338 volatile devctxp_t *dcbaa;
339
340 trb_t *cmd_ring;
341 trb_t *ev_ring;
342 volatile erst_entry_t *ev_ring_table;
343 int cmd_ccs, ev_ccs;
344
345 usbdev_t *roothub;
346} xhci_t;
347
348#define XHCI_INST(controller) ((xhci_t*)((controller)->instance))
349
350#endif