source: mainline/uspace/drv/bus/usb/xhci/hw_struct/regs.h@ ae3a941

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since ae3a941 was e0a5d4c, checked in by Ondřej Hlavatý <aearsis@…>, 7 years ago

usb: update copyrights

The data was generated by a script, guided manually. If you feel your
name is missing somewhere, please add it!

The semi-automated process was roughly:

1) Changes per file and author (limited to our team) were counted
2) Trivial numbers were thrown away
3) Authors were sorted by lines added to file
4) All previous copyrights were replaced by the newly generated one
5) Hunks changing only year were discarded

It seems that a lot of my copyrights were added. It is due to me being
both sticking my nose everywhere and lazy to update the copyright right
away :)

  • Property mode set to 100644
File size: 18.7 KB
Line 
1/*
2 * Copyright (c) 2018 Ondrej Hlavaty
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - 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 * - 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 ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup drvusbxhci
30 * @{
31 */
32/** @file
33 * Memory-mapped register structures of the xHC.
34 *
35 * The main pr
36 */
37
38#ifndef XHCI_REGS_H
39#define XHCI_REGS_H
40
41#include <macros.h>
42#include <ddi.h>
43#include "common.h"
44
45#define XHCI_PIO_CHANGE_UDELAY 5
46
47/*
48 * These four are the main macros to be used.
49 * Semantics is usual - READ reads value, WRITE changes value, SET sets
50 * selected bits, CLEAR clears selected bits to 0.
51 *
52 * The key thing here is the order of macro expansion, expanding the reg_spec
53 * argument as more arguments (comma delimited) for the inner macro.
54 */
55#define XHCI_REG_RD(reg_set, reg_spec) XHCI_REG_RD_INNER(reg_set, reg_spec)
56#define XHCI_REG_WR(reg_set, reg_spec, value) XHCI_REG_WR_INNER(reg_set, value, reg_spec)
57#define XHCI_REG_SET(reg_set, reg_spec, value) XHCI_REG_SET_INNER(reg_set, value, reg_spec)
58#define XHCI_REG_CLR(reg_set, reg_spec, value) XHCI_REG_CLR_INNER(reg_set, value, reg_spec)
59#define XHCI_REG_MASK(reg_spec) XHCI_REG_MASK_INNER(reg_spec)
60#define XHCI_REG_SHIFT(reg_spec) XHCI_REG_SHIFT_INNER(reg_spec)
61
62/*
63 * These take a pointer to the field, and selects the type-specific macro.
64 */
65#define XHCI_REG_RD_INNER(reg_set, field, size, type, ...) \
66 XHCI_REG_RD_##type(&((reg_set)->field), size, ##__VA_ARGS__)
67
68#define XHCI_REG_WR_INNER(reg_set, value, field, size, type, ...) \
69 XHCI_REG_WR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
70
71#define XHCI_REG_SET_INNER(reg_set, value, field, size, type, ...) \
72 XHCI_REG_SET_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
73
74#define XHCI_REG_CLR_INNER(reg_set, value, field, size, type, ...) \
75 XHCI_REG_CLR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
76
77#define XHCI_REG_MASK_INNER(field, size, type, ...) \
78 XHCI_REG_MASK_##type(size, ##__VA_ARGS__)
79
80#define XHCI_REG_SHIFT_INNER(field, size, type, ...) \
81 XHCI_REG_SHIFT_##type(size, ##__VA_ARGS__)
82
83/*
84 * Field handling is the easiest. Just do it with whole field.
85 */
86#define XHCI_REG_RD_FIELD(ptr, size) \
87 xhci2host(size, pio_read_##size((ptr)))
88#define XHCI_REG_WR_FIELD(ptr, value, size) \
89 pio_write_##size((ptr), host2xhci(size, value))
90#define XHCI_REG_SET_FIELD(ptr, value, size) \
91 pio_set_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
92#define XHCI_REG_CLR_FIELD(ptr, value, size) \
93 pio_clear_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
94#define XHCI_REG_MASK_FIELD(size) (~((uint##size##_t) 0))
95#define XHCI_REG_SHIFT_FIELD(size) (0)
96
97/*
98 * Flags are just trivial case of ranges.
99 */
100#define XHCI_REG_RD_FLAG(ptr, size, offset) \
101 XHCI_REG_RD_RANGE((ptr), size, (offset), (offset))
102#define XHCI_REG_WR_FLAG(ptr, value, size, offset) \
103 XHCI_REG_WR_RANGE((ptr), (value), size, (offset), (offset))
104#define XHCI_REG_SET_FLAG(ptr, value, size, offset) \
105 XHCI_REG_SET_RANGE((ptr), (value), size, (offset), (offset))
106#define XHCI_REG_CLR_FLAG(ptr, value, size, offset) \
107 XHCI_REG_CLR_RANGE((ptr), (value), size, (offset), (offset))
108#define XHCI_REG_MASK_FLAG(size, offset) BIT_V(uint##size##_t, offset)
109#define XHCI_REG_SHIFT_FLAG(size, offset) (offset)
110
111/*
112 * Ranges are the most difficult. We need to play around with bitmasks.
113 */
114#define XHCI_REG_RD_RANGE(ptr, size, hi, lo) \
115 BIT_RANGE_EXTRACT(uint##size##_t, (hi), (lo), XHCI_REG_RD_FIELD((ptr), size))
116
117#define XHCI_REG_WR_RANGE(ptr, value, size, hi, lo) \
118 pio_change_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
119 (hi), (lo), (value))), \
120 host2xhci(size, BIT_RANGE(uint##size##_t, (hi), (lo))), \
121 XHCI_PIO_CHANGE_UDELAY);
122
123#define XHCI_REG_SET_RANGE(ptr, value, size, hi, lo) \
124 pio_set_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
125 (hi), (lo), (value))), \
126 XHCI_PIO_CHANGE_UDELAY);
127
128#define XHCI_REG_CLR_RANGE(ptr, value, size, hi, lo) \
129 pio_clear_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, \
130 (hi), (lo), (value))), \
131 XHCI_PIO_CHANGE_UDELAY);
132
133#define XHCI_REG_MASK_RANGE(size, hi, lo) BIT_RANGE(uint##size##_t, hi, lo)
134#define XHCI_REG_SHIFT_RANGE(size, hi, lo) (lo)
135
136/** HC capability registers: section 5.3 */
137typedef const struct xhci_cap_regs {
138
139 /* Size of this structure, offset for the operation registers */
140 const ioport8_t caplength;
141
142 const PADD8;
143
144 /* BCD of specification version */
145 const ioport16_t hciversion;
146
147 /*
148 * 7:0 - MaxSlots
149 * 18:8 - MaxIntrs
150 * 31:24 - MaxPorts
151 */
152 const ioport32_t hcsparams1;
153
154 /*
155 * 3:0 - IST
156 * 7:4 - ERST Max
157 * 25:21 - Max Scratchpad Bufs Hi
158 * 26 - SPR
159 * 31:27 - Max Scratchpad Bufs Lo
160 */
161 const ioport32_t hcsparams2;
162
163 /*
164 * 7:0 - U1 Device Exit Latency
165 * 31:16 - U2 Device Exit Latency
166 */
167 const ioport32_t hcsparams3;
168
169 /*
170 * 11 10 9 8 7 6 5 4 3 2 1 0
171 * 11:0 - CFC SEC SPC PAE NSS LTC C PIND PPC CSZ BNC AC64
172 * 15:12 - MaxPSASize
173 * 31:16 - xECP
174 */
175 const ioport32_t hccparams1;
176
177 /*
178 * 31:2 - Doorbell Array Offset
179 */
180 const ioport32_t dboff;
181
182 /*
183 * 31:5 - Runtime Register Space Offset
184 */
185 const ioport32_t rtsoff;
186
187 /*
188 * 5 4 3 2 1 0
189 * 5:0 - Flags: CIC LEC CTC FSC CMC U3C
190 */
191 const ioport32_t hccparams2;
192
193 // the rest to operational registers is reserved
194} xhci_cap_regs_t;
195
196/*
197 * The register specifiers are to be used as the reg_spec argument.
198 *
199 * The values are field, bitsize, type, (type specific args)
200 * When the type is RANGE: hi, lo
201 */
202#define XHCI_CAP_LENGTH caplength, 8, FIELD
203#define XHCI_CAP_VERSION hciversion, 16, FIELD
204#define XHCI_CAP_MAX_SLOTS hcsparams1, 32, RANGE, 7, 0
205#define XHCI_CAP_MAX_INTRS hcsparams1, 32, RANGE, 18, 8
206#define XHCI_CAP_MAX_PORTS hcsparams1, 32, RANGE, 31, 24
207#define XHCI_CAP_IST hcsparams2, 32, RANGE, 3, 0
208#define XHCI_CAP_ERST_MAX hcsparams2, 32, RANGE, 7, 4
209#define XHCI_CAP_MAX_SPBUF_HI hcsparams2, 32, RANGE, 25, 21
210#define XHCI_CAP_SPR hcsparams2, 32, FLAG, 26
211#define XHCI_CAP_MAX_SPBUF_LO hcsparams2, 32, RANGE, 31, 27
212#define XHCI_CAP_U1EL hcsparams3, 32, RANGE, 7, 0
213#define XHCI_CAP_U2EL hcsparams3, 32, RANGE, 31, 16
214#define XHCI_CAP_AC64 hccparams1, 32, FLAG, 0
215#define XHCI_CAP_BNC hccparams1, 32, FLAG, 1
216#define XHCI_CAP_CSZ hccparams1, 32, FLAG, 2
217#define XHCI_CAP_PPC hccparams1, 32, FLAG, 3
218#define XHCI_CAP_PIND hccparams1, 32, FLAG, 4
219#define XHCI_CAP_C hccparams1, 32, FLAG, 5
220#define XHCI_CAP_LTC hccparams1, 32, FLAG, 6
221#define XHCI_CAP_NSS hccparams1, 32, FLAG, 7
222#define XHCI_CAP_PAE hccparams1, 32, FLAG, 8
223#define XHCI_CAP_SPC hccparams1, 32, FLAG, 9
224#define XHCI_CAP_SEC hccparams1, 32, FLAG, 10
225#define XHCI_CAP_CFC hccparams1, 32, FLAG, 11
226#define XHCI_CAP_MAX_PSA_SIZE hccparams1, 32, RANGE, 15, 12
227#define XHCI_CAP_XECP hccparams1, 32, RANGE, 31, 16
228#define XHCI_CAP_DBOFF dboff, 32, FIELD
229#define XHCI_CAP_RTSOFF rtsoff, 32, FIELD
230#define XHCI_CAP_U3C hccparams2, 32, FLAG, 0
231#define XHCI_CAP_CMC hccparams2, 32, FLAG, 1
232#define XHCI_CAP_FSC hccparams2, 32, FLAG, 2
233#define XHCI_CAP_CTC hccparams2, 32, FLAG, 3
234#define XHCI_CAP_LEC hccparams2, 32, FLAG, 4
235#define XHCI_CAP_CIC hccparams2, 32, FLAG, 5
236
237static inline unsigned xhci_get_max_spbuf(xhci_cap_regs_t *cap_regs) {
238 return XHCI_REG_RD(cap_regs, XHCI_CAP_MAX_SPBUF_HI) << 5
239 | XHCI_REG_RD(cap_regs, XHCI_CAP_MAX_SPBUF_LO);
240}
241
242/**
243 * XHCI Port Register Set: section 5.4, table 32
244 */
245typedef struct xhci_port_regs {
246 /*
247 * 4 3 2 1 0
248 * 4:0 - PR OCA Z PED CCS
249 * 8:5 - PLS
250 * 9 - PP
251 * 13:10 - Port Speed
252 * 15:14 - PIC
253 * 27 26 25 24 23 22 21 20 19 18 17 16
254 * 27:16 - WOE WDE WCE CAS CEC PLC PRC OCC WRC PEC CSC LWS
255 * 30 - DR
256 * 31 - WPR
257 */
258 ioport32_t portsc;
259
260 /*
261 * Contents of this fields depends on the protocol supported by the port.
262 * USB3:
263 * 7:0 - U1 Timeout
264 * 15:8 - U2 Timeout
265 * 16 - Force Link PM Accept
266 * USB2:
267 * 2:0 - L1S
268 * 3 - RWE
269 * 7:4 - BESL
270 * 15:8 - L1 Device Slot
271 * 16 - HLE
272 * 31:28 - Test Mode
273 */
274 ioport32_t portpmsc;
275
276 /*
277 * This field is valid only for USB3 ports.
278 * 15:0 - Link Error Count
279 * 19:16 - RLC
280 * 23:20 - TLC
281 */
282 ioport32_t portli;
283
284 /*
285 * This field is valid only for USB2 ports.
286 * 1:0 - HIRDM
287 * 9:2 - L1 Timeout
288 * 13:10 - BESLD
289 */
290 ioport32_t porthlpmc;
291} xhci_port_regs_t;
292
293#define XHCI_PORT_CCS portsc, 32, FLAG, 0
294#define XHCI_PORT_PED portsc, 32, FLAG, 1
295#define XHCI_PORT_OCA portsc, 32, FLAG, 3
296#define XHCI_PORT_PR portsc, 32, FLAG, 4
297#define XHCI_PORT_PLS portsc, 32, RANGE, 8, 5
298#define XHCI_PORT_PP portsc, 32, FLAG, 9
299#define XHCI_PORT_PS portsc, 32, RANGE, 13, 10
300#define XHCI_PORT_PIC portsc, 32, RANGE, 15, 14
301#define XHCI_PORT_LWS portsc, 32, FLAG, 16
302#define XHCI_PORT_CSC portsc, 32, FLAG, 17
303#define XHCI_PORT_PEC portsc, 32, FLAG, 18
304#define XHCI_PORT_WRC portsc, 32, FLAG, 19
305#define XHCI_PORT_OCC portsc, 32, FLAG, 20
306#define XHCI_PORT_PRC portsc, 32, FLAG, 21
307#define XHCI_PORT_PLC portsc, 32, FLAG, 22
308#define XHCI_PORT_CEC portsc, 32, FLAG, 23
309#define XHCI_PORT_CAS portsc, 32, FLAG, 24
310#define XHCI_PORT_WCE portsc, 32, FLAG, 25
311#define XHCI_PORT_WDE portsc, 32, FLAG, 26
312#define XHCI_PORT_WOE portsc, 32, FLAG, 27
313#define XHCI_PORT_DR portsc, 32, FLAG, 30
314#define XHCI_PORT_WPR portsc, 32, FLAG, 31
315
316#define XHCI_PORT_USB3_U1TO portpmsc, 32, RANGE, 7, 0
317#define XHCI_PORT_USB3_U2TO portpmsc, 32, RANGE, 15, 8
318#define XHCI_PORT_USB3_FLPMA portpmsc, 32, FLAG, 16
319#define XHCI_PORT_USB3_LEC portli, 32, RANGE, 15, 0
320#define XHCI_PORT_USB3_RLC portli, 32, RANGE, 19, 16
321#define XHCI_PORT_USB3_TLC portli, 32, RANGE, 23, 20
322
323#define XHCI_PORT_USB2_L1S portpmsc, 32, RANGE, 2, 0
324#define XHCI_PORT_USB2_RWE portpmsc, 32, FLAG, 3
325#define XHCI_PORT_USB2_BESL portpmsc, 32, RANGE, 7, 4
326#define XHCI_PORT_USB2_L1DS portpmsc, 32, RANGE, 15, 8
327#define XHCI_PORT_USB2_HLE portpmsc, 32, FLAG, 16
328#define XHCI_PORT_USB2_TM portpmsc, 32, RANGE, 31, 28
329#define XHCI_PORT_USB2_HIRDM porthlpmc, 32, RANGE, 1, 0
330#define XHCI_PORT_USB2_L1TO porthlpmc, 32, RANGE, 9, 2
331#define XHCI_PORT_USB2_BESLD porthlpmc, 32, RANGE, 13, 10
332
333/**
334 * XHCI Operational Registers: section 5.4
335 */
336typedef struct xhci_op_regs {
337
338 /*
339 * 3 2 1 0
340 * 3:0 - HSEE INTE HCRST R/S
341 *
342 * 11 10 9 8 7
343 * 11:7 - EU3S EWE CRS CSS LHCRST
344 * 13 - CME
345 */
346 ioport32_t usbcmd;
347
348 /*
349 * 4 3 2 1 0
350 * 4:0 - PCD EINT HSE _ HCH
351 *
352 * 12 11 10 9 8
353 * 12:8 - HCE CNR SRE RSS SSS
354 */
355 ioport32_t usbsts;
356
357 /*
358 * Bitmask of page sizes supported: 128M .. 4K
359 */
360 ioport32_t pagesize;
361
362 PADD32[2];
363
364 /*
365 * 15:0 - Notification enable
366 */
367 ioport32_t dnctrl;
368
369 /* 3 2 1 0
370 * 3:0 - CRR CA CS RCS
371 * 64:6 - Command Ring Pointer
372 */
373 ioport64_t crcr;
374
375 PADD32[4];
376
377 ioport64_t dcbaap;
378
379 /*
380 * 7:0 - MaxSlotsEn
381 * 8 - U3E
382 * 9 - CIE
383 */
384 ioport32_t config;
385
386 /* Offset of portrs from op_regs addr is 0x400. */
387 PADD32[241];
388
389 /*
390 * Individual ports register sets
391 */
392 xhci_port_regs_t portrs[256];
393} xhci_op_regs_t;
394
395#define XHCI_OP_RS usbcmd, 32, FLAG, 0
396#define XHCI_OP_HCRST usbcmd, 32, FLAG, 1
397#define XHCI_OP_INTE usbcmd, 32, FLAG, 2
398#define XHCI_OP_HSEE usbcmd, 32, FLAG, 3
399#define XHCI_OP_LHCRST usbcmd, 32, FLAG, 7
400#define XHCI_OP_CSS usbcmd, 32, FLAG, 8
401#define XHCI_OP_CRS usbcmd, 32, FLAG, 9
402#define XHCI_OP_EWE usbcmd, 32, FLAG, 10
403#define XHCI_OP_EU3S usbcmd, 32, FLAG, 11
404#define XHCI_OP_CME usbcmd, 32, FLAG, 13
405#define XHCI_OP_HCH usbsts, 32, FLAG, 0
406#define XHCI_OP_HSE usbsts, 32, FLAG, 2
407#define XHCI_OP_EINT usbsts, 32, FLAG, 3
408#define XHCI_OP_PCD usbsts, 32, FLAG, 4
409#define XHCI_OP_SSS usbsts, 32, FLAG, 8
410#define XHCI_OP_RSS usbsts, 32, FLAG, 9
411#define XHCI_OP_SRE usbsts, 32, FLAG, 10
412#define XHCI_OP_CNR usbsts, 32, FLAG, 11
413#define XHCI_OP_HCE usbsts, 32, FLAG, 12
414#define XHCI_OP_PAGESIZE pagesize, 32, FIELD
415#define XHCI_OP_NOTIFICATION dnctrl, 32, RANGE, 15, 0
416#define XHCI_OP_RCS crcr, 64, FLAG, 0
417#define XHCI_OP_CS crcr, 64, FLAG, 1
418#define XHCI_OP_CA crcr, 64, FLAG, 2
419#define XHCI_OP_CRR crcr, 64, FLAG, 3
420/*
421 * This shall be RANGE, 6, 0, but the value containing CR pointer and RCS flag
422 * must be written at once.
423 */
424#define XHCI_OP_CRCR crcr, 64, FIELD
425#define XHCI_OP_DCBAAP dcbaap, 64, FIELD
426#define XHCI_OP_MAX_SLOTS_EN config, 32, RANGE, 7, 0
427#define XHCI_OP_U3E config, 32, FLAG, 8
428#define XHCI_OP_CIE config, 32, FLAG, 9
429
430/* Aggregating field to read & write whole status at once */
431#define XHCI_OP_STATUS usbsts, 32, RANGE, 12, 0
432
433/* RW1C fields in usbsts */
434#define XHCI_STATUS_ACK_MASK 0x41C
435
436/**
437 * Interrupter Register Set: section 5.5.2
438 */
439typedef struct xhci_interrupter_regs {
440 /*
441 * 0 - Interrupt Pending
442 * 1 - Interrupt Enable
443 */
444 ioport32_t iman;
445
446 /*
447 * 15:0 - Interrupt Moderation Interval
448 * 31:16 - Interrupt Moderation Counter
449 */
450 ioport32_t imod;
451
452 ioport32_t erstsz;
453
454 PADD32;
455
456 ioport64_t erstba;
457
458 /*
459 * 2:0 - Dequeue ERST Segment Index
460 * 3 - Event Handler Busy
461 * 63:4 - Event Ring Dequeue Pointer
462 */
463 ioport64_t erdp;
464} xhci_interrupter_regs_t;
465
466#define XHCI_INTR_IP iman, 32, FLAG, 0
467#define XHCI_INTR_IE iman, 32, FLAG, 1
468#define XHCI_INTR_IMI imod, 32, RANGE, 15, 0
469#define XHCI_INTR_IMC imod, 32, RANGE, 31, 16
470#define XHCI_INTR_ERSTSZ erstsz, 32, FIELD
471#define XHCI_INTR_ERSTBA erstba, 64, FIELD
472#define XHCI_INTR_ERDP_ESI erdp, 64, RANGE, 2, 0
473#define XHCI_INTR_ERDP_EHB erdp, 64, FLAG, 3
474#define XHCI_INTR_ERDP erdp, 64, FIELD
475
476/**
477 * XHCI Runtime registers: section 5.5
478 */
479typedef struct xhci_rt_regs {
480 ioport32_t mfindex;
481
482 PADD32 [7];
483
484 xhci_interrupter_regs_t ir [];
485} xhci_rt_regs_t;
486
487#define XHCI_RT_MFINDEX mfindex, 32, RANGE, 13, 0
488#define XHCI_MFINDEX_MAX (1 << 14)
489
490/**
491 * XHCI Doorbell Registers: section 5.6
492 *
493 * These registers are to be written as a whole field.
494 */
495typedef ioport32_t xhci_doorbell_t;
496
497enum xhci_plt {
498 XHCI_PSI_PLT_SYMM,
499 XHCI_PSI_PLT_RSVD,
500 XHCI_PSI_PLT_RX,
501 XHCI_PSI_PLT_TX
502};
503
504/**
505 * Protocol speed ID: section 7.2.1
506 */
507typedef struct xhci_psi {
508 xhci_dword_t psi;
509} xhci_psi_t;
510
511#define XHCI_PSI_PSIV psi, 32, RANGE, 3, 0
512#define XHCI_PSI_PSIE psi, 32, RANGE, 5, 4
513#define XHCI_PSI_PLT psi, 32, RANGE, 7, 6
514#define XHCI_PSI_PFD psi, 32, FLAG, 8
515#define XHCI_PSI_PSIM psi, 32, RANGE, 31, 16
516
517enum xhci_extcap_type {
518 XHCI_EC_RESERVED = 0,
519 XHCI_EC_USB_LEGACY,
520 XHCI_EC_SUPPORTED_PROTOCOL,
521 XHCI_EC_EXTENDED_POWER_MANAGEMENT,
522 XHCI_EC_IOV,
523 XHCI_EC_MSI,
524 XHCI_EC_LOCALMEM,
525 XHCI_EC_DEBUG = 10,
526 XHCI_EC_MSIX = 17,
527 XHCI_EC_MAX = 255
528};
529
530/**
531 * xHCI Extended Capability: section 7
532 */
533typedef struct xhci_extcap {
534 xhci_dword_t header;
535 xhci_dword_t cap_specific[];
536} xhci_extcap_t;
537
538#define XHCI_EC_CAP_ID header, 32, RANGE, 7, 0
539#define XHCI_EC_SIZE header, 32, RANGE, 15, 8
540
541/* Supported protocol */
542#define XHCI_EC_SP_MINOR header, 32, RANGE, 23, 16
543#define XHCI_EC_SP_MAJOR header, 32, RANGE, 31, 24
544#define XHCI_EC_SP_NAME cap_specific[0], 32, FIELD
545#define XHCI_EC_SP_CP_OFF cap_specific[1], 32, RANGE, 7, 0
546#define XHCI_EC_SP_CP_COUNT cap_specific[1], 32, RANGE, 15, 8
547#define XHCI_EC_SP_PSIC cap_specific[1], 32, RANGE, 31, 28
548#define XHCI_EC_SP_SLOT_TYPE cap_specific[2], 32, RANGE, 4, 0
549
550typedef union {
551 char str [4];
552 uint32_t packed;
553} xhci_sp_name_t;
554
555static const xhci_sp_name_t xhci_name_usb = {
556 .str = "USB "
557};
558
559static inline xhci_extcap_t *xhci_extcap_next(const xhci_extcap_t *cur)
560{
561 unsigned dword_offset = XHCI_REG_RD(cur, XHCI_EC_SIZE);
562 if (!dword_offset)
563 return NULL;
564 return (xhci_extcap_t *) (((xhci_dword_t *) cur) + dword_offset);
565}
566
567static inline xhci_psi_t *xhci_extcap_psi(const xhci_extcap_t *ec, unsigned psid)
568{
569 assert(XHCI_REG_RD(ec, XHCI_EC_CAP_ID) == XHCI_EC_SUPPORTED_PROTOCOL);
570 assert(XHCI_REG_RD(ec, XHCI_EC_SP_PSIC) > psid);
571
572 unsigned dword_offset = 4 + psid;
573 return (xhci_psi_t *) (((xhci_dword_t *) ec) + dword_offset);
574}
575
576/**
577 * USB Legacy Support: section 7.1
578 *
579 * Legacy support have an exception from dword-access, because it needs to be
580 * byte-accessed.
581 */
582typedef struct xhci_extcap_legsup {
583 ioport8_t cap_id;
584 ioport8_t size; /**< Next Capability Pointer */
585 ioport8_t sem_bios;
586 ioport8_t sem_os;
587
588 /** USB Legacy Support Control/Status - RW for BIOS, RO for OS */
589 xhci_dword_t usblegctlsts;
590} xhci_legsup_t;
591
592#define XHCI_LEGSUP_SEM_BIOS sem_bios, 8, FLAG, 0
593#define XHCI_LEGSUP_SEM_OS sem_os, 8, FLAG, 0
594
595/* 4.22.1 BIOS may take up to 1 second to release the device */
596#define XHCI_LEGSUP_BIOS_TIMEOUT_US 1000000
597#define XHCI_LEGSUP_POLLING_DELAY_1MS 1000
598
599#endif
600/**
601 * @}
602 */
Note: See TracBrowser for help on using the repository browser.