source: mainline/uspace/drv/bus/usb/xhci/debug.c@ 1938b381

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1938b381 was 1938b381, checked in by Jiří Zárevúcky <jiri.zarevucky@…>, 7 years ago

Use correct print format specifiers

  • Property mode set to 100644
File size: 12.0 KB
Line 
1/*
2 * Copyright (c) 2018 Ondrej Hlavaty, Jan Hrach
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 * Various functions to examine current state of the xHC.
34 */
35
36#include <inttypes.h>
37#include <byteorder.h>
38#include <usb/debug.h>
39
40#include "hw_struct/trb.h"
41#include "debug.h"
42#include "hc.h"
43
44#define PX "\t%-21s = "
45
46#define DUMP_REG_FIELD(ptr, title, size, ...) \
47 usb_log_debug(PX "%" PRIu##size, title, XHCI_REG_RD_FIELD(ptr, size, ##__VA_ARGS__))
48
49#define DUMP_REG_RANGE(ptr, title, size, ...) \
50 usb_log_debug(PX "%" PRIu##size, title, XHCI_REG_RD_RANGE(ptr, size, ##__VA_ARGS__))
51
52#define DUMP_REG_FLAG(ptr, title, size, ...) \
53 usb_log_debug(PX "%s", title, XHCI_REG_RD_FLAG(ptr, size, ##__VA_ARGS__) ? "true" : "false")
54
55#define DUMP_REG_INNER(set, title, field, size, type, ...) \
56 DUMP_REG_##type(&(set)->field, title, size, ##__VA_ARGS__)
57
58#define DUMP_REG(set, c) DUMP_REG_INNER(set, #c, c)
59
60/**
61 * Dumps all capability registers.
62 */
63void xhci_dump_cap_regs(const xhci_cap_regs_t *cap)
64{
65 usb_log_debug("Capabilities:");
66
67 DUMP_REG(cap, XHCI_CAP_LENGTH);
68 DUMP_REG(cap, XHCI_CAP_VERSION);
69 DUMP_REG(cap, XHCI_CAP_MAX_SLOTS);
70 DUMP_REG(cap, XHCI_CAP_MAX_INTRS);
71 DUMP_REG(cap, XHCI_CAP_MAX_PORTS);
72 DUMP_REG(cap, XHCI_CAP_IST);
73 DUMP_REG(cap, XHCI_CAP_ERST_MAX);
74 usb_log_debug(PX "%u", "Max Scratchpad bufs", xhci_get_max_spbuf(cap));
75 DUMP_REG(cap, XHCI_CAP_SPR);
76 DUMP_REG(cap, XHCI_CAP_U1EL);
77 DUMP_REG(cap, XHCI_CAP_U2EL);
78 DUMP_REG(cap, XHCI_CAP_AC64);
79 DUMP_REG(cap, XHCI_CAP_BNC);
80 DUMP_REG(cap, XHCI_CAP_CSZ);
81 DUMP_REG(cap, XHCI_CAP_PPC);
82 DUMP_REG(cap, XHCI_CAP_PIND);
83 DUMP_REG(cap, XHCI_CAP_C);
84 DUMP_REG(cap, XHCI_CAP_LTC);
85 DUMP_REG(cap, XHCI_CAP_NSS);
86 DUMP_REG(cap, XHCI_CAP_PAE);
87 DUMP_REG(cap, XHCI_CAP_SPC);
88 DUMP_REG(cap, XHCI_CAP_SEC);
89 DUMP_REG(cap, XHCI_CAP_CFC);
90 DUMP_REG(cap, XHCI_CAP_MAX_PSA_SIZE);
91 DUMP_REG(cap, XHCI_CAP_XECP);
92 DUMP_REG(cap, XHCI_CAP_DBOFF);
93 DUMP_REG(cap, XHCI_CAP_RTSOFF);
94 DUMP_REG(cap, XHCI_CAP_U3C);
95 DUMP_REG(cap, XHCI_CAP_CMC);
96 DUMP_REG(cap, XHCI_CAP_FSC);
97 DUMP_REG(cap, XHCI_CAP_CTC);
98 DUMP_REG(cap, XHCI_CAP_LEC);
99 DUMP_REG(cap, XHCI_CAP_CIC);
100}
101
102/**
103 * Dumps registers of one port.
104 */
105void xhci_dump_port(const xhci_port_regs_t *port)
106{
107 DUMP_REG(port, XHCI_PORT_CCS);
108 DUMP_REG(port, XHCI_PORT_PED);
109 DUMP_REG(port, XHCI_PORT_OCA);
110 DUMP_REG(port, XHCI_PORT_PR);
111 DUMP_REG(port, XHCI_PORT_PLS);
112 DUMP_REG(port, XHCI_PORT_PP);
113 DUMP_REG(port, XHCI_PORT_PS);
114 DUMP_REG(port, XHCI_PORT_PIC);
115 DUMP_REG(port, XHCI_PORT_LWS);
116 DUMP_REG(port, XHCI_PORT_CSC);
117 DUMP_REG(port, XHCI_PORT_PEC);
118 DUMP_REG(port, XHCI_PORT_WRC);
119 DUMP_REG(port, XHCI_PORT_OCC);
120 DUMP_REG(port, XHCI_PORT_PRC);
121 DUMP_REG(port, XHCI_PORT_PLC);
122 DUMP_REG(port, XHCI_PORT_CEC);
123 DUMP_REG(port, XHCI_PORT_CAS);
124 DUMP_REG(port, XHCI_PORT_WCE);
125 DUMP_REG(port, XHCI_PORT_WDE);
126 DUMP_REG(port, XHCI_PORT_WOE);
127 DUMP_REG(port, XHCI_PORT_DR);
128 DUMP_REG(port, XHCI_PORT_WPR);
129 DUMP_REG(port, XHCI_PORT_USB3_U1TO);
130 DUMP_REG(port, XHCI_PORT_USB3_U2TO);
131 DUMP_REG(port, XHCI_PORT_USB3_FLPMA);
132 DUMP_REG(port, XHCI_PORT_USB3_LEC);
133 DUMP_REG(port, XHCI_PORT_USB3_RLC);
134 DUMP_REG(port, XHCI_PORT_USB3_TLC);
135 DUMP_REG(port, XHCI_PORT_USB2_L1S);
136 DUMP_REG(port, XHCI_PORT_USB2_RWE);
137 DUMP_REG(port, XHCI_PORT_USB2_BESL);
138 DUMP_REG(port, XHCI_PORT_USB2_L1DS);
139 DUMP_REG(port, XHCI_PORT_USB2_HLE);
140 DUMP_REG(port, XHCI_PORT_USB2_TM);
141 DUMP_REG(port, XHCI_PORT_USB2_HIRDM);
142 DUMP_REG(port, XHCI_PORT_USB2_L1TO);
143 DUMP_REG(port, XHCI_PORT_USB2_BESLD);
144}
145
146/**
147 * Dumps all registers that define state of the HC.
148 */
149void xhci_dump_state(const xhci_hc_t *hc)
150{
151 usb_log_debug("Operational registers:");
152
153 DUMP_REG(hc->op_regs, XHCI_OP_RS);
154 DUMP_REG(hc->op_regs, XHCI_OP_HCRST);
155 DUMP_REG(hc->op_regs, XHCI_OP_INTE);
156 DUMP_REG(hc->op_regs, XHCI_OP_HSEE);
157 DUMP_REG(hc->op_regs, XHCI_OP_LHCRST);
158 DUMP_REG(hc->op_regs, XHCI_OP_CSS);
159 DUMP_REG(hc->op_regs, XHCI_OP_CRS);
160 DUMP_REG(hc->op_regs, XHCI_OP_EWE);
161 DUMP_REG(hc->op_regs, XHCI_OP_EU3S);
162 DUMP_REG(hc->op_regs, XHCI_OP_CME);
163 DUMP_REG(hc->op_regs, XHCI_OP_HCH);
164 DUMP_REG(hc->op_regs, XHCI_OP_HSE);
165 DUMP_REG(hc->op_regs, XHCI_OP_EINT);
166 DUMP_REG(hc->op_regs, XHCI_OP_PCD);
167 DUMP_REG(hc->op_regs, XHCI_OP_SSS);
168 DUMP_REG(hc->op_regs, XHCI_OP_RSS);
169 DUMP_REG(hc->op_regs, XHCI_OP_SRE);
170 DUMP_REG(hc->op_regs, XHCI_OP_CNR);
171 DUMP_REG(hc->op_regs, XHCI_OP_HCE);
172 DUMP_REG(hc->op_regs, XHCI_OP_PAGESIZE);
173 DUMP_REG(hc->op_regs, XHCI_OP_NOTIFICATION);
174 DUMP_REG(hc->op_regs, XHCI_OP_RCS);
175 DUMP_REG(hc->op_regs, XHCI_OP_CS);
176 DUMP_REG(hc->op_regs, XHCI_OP_CA);
177 DUMP_REG(hc->op_regs, XHCI_OP_CRR);
178 DUMP_REG(hc->op_regs, XHCI_OP_CRCR);
179 DUMP_REG(hc->op_regs, XHCI_OP_DCBAAP);
180 DUMP_REG(hc->rt_regs, XHCI_RT_MFINDEX);
181
182 usb_log_debug("Interrupter 0 state:");
183 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IP);
184 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IE);
185 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IMI);
186 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IMC);
187 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_ERSTSZ);
188 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_ERSTBA);
189 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_ERDP);
190}
191
192/**
193 * Dump registers of all ports.
194 */
195void xhci_dump_ports(const xhci_hc_t *hc)
196{
197 const size_t num_ports = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PORTS);
198 for (size_t i = 0; i < num_ports; i++) {
199 usb_log_debug("Port %zu state:", i);
200
201 xhci_dump_port(&hc->op_regs->portrs[i]);
202 }
203}
204
205static const char *trb_types [] = {
206 [0] = "<empty>",
207#define TRB(t) [XHCI_TRB_TYPE_##t] = #t
208 TRB(NORMAL),
209 TRB(SETUP_STAGE),
210 TRB(DATA_STAGE),
211 TRB(STATUS_STAGE),
212 TRB(ISOCH),
213 TRB(LINK),
214 TRB(EVENT_DATA),
215 TRB(NO_OP),
216 TRB(ENABLE_SLOT_CMD),
217 TRB(DISABLE_SLOT_CMD),
218 TRB(ADDRESS_DEVICE_CMD),
219 TRB(CONFIGURE_ENDPOINT_CMD),
220 TRB(EVALUATE_CONTEXT_CMD),
221 TRB(RESET_ENDPOINT_CMD),
222 TRB(STOP_ENDPOINT_CMD),
223 TRB(SET_TR_DEQUEUE_POINTER_CMD),
224 TRB(RESET_DEVICE_CMD),
225 TRB(FORCE_EVENT_CMD),
226 TRB(NEGOTIATE_BANDWIDTH_CMD),
227 TRB(SET_LATENCY_TOLERANCE_VALUE_CMD),
228 TRB(GET_PORT_BANDWIDTH_CMD),
229 TRB(FORCE_HEADER_CMD),
230 TRB(NO_OP_CMD),
231 TRB(TRANSFER_EVENT),
232 TRB(COMMAND_COMPLETION_EVENT),
233 TRB(PORT_STATUS_CHANGE_EVENT),
234 TRB(BANDWIDTH_REQUEST_EVENT),
235 TRB(DOORBELL_EVENT),
236 TRB(HOST_CONTROLLER_EVENT),
237 TRB(DEVICE_NOTIFICATION_EVENT),
238 TRB(MFINDEX_WRAP_EVENT),
239#undef TRB
240 [XHCI_TRB_TYPE_MAX] = NULL,
241};
242
243/**
244 * Stringify XHCI_TRB_TYPE_*.
245 */
246const char *xhci_trb_str_type(unsigned type)
247{
248 static char type_buf [20];
249
250 if (type < XHCI_TRB_TYPE_MAX && trb_types[type] != NULL)
251 return trb_types[type];
252
253 snprintf(type_buf, sizeof(type_buf), "<unknown (%u)>", type);
254 return type_buf;
255}
256
257/**
258 * Dump a TRB.
259 */
260void xhci_dump_trb(const xhci_trb_t *trb)
261{
262 usb_log_debug("TRB(%p): type %s, cycle %u, status 0x%#08" PRIx32 ", "
263 "parameter 0x%#016" PRIx64, trb, xhci_trb_str_type(TRB_TYPE(*trb)),
264 TRB_CYCLE(*trb), trb->status, trb->parameter);
265}
266
267static const char *ec_ids [] = {
268 [0] = "<empty>",
269#define EC(t) [XHCI_EC_##t] = #t
270 EC(USB_LEGACY),
271 EC(SUPPORTED_PROTOCOL),
272 EC(EXTENDED_POWER_MANAGEMENT),
273 EC(IOV),
274 EC(MSI),
275 EC(LOCALMEM),
276 EC(DEBUG),
277 EC(MSIX),
278#undef EC
279 [XHCI_EC_MAX] = NULL
280};
281
282/**
283 * Dump Extended Capability ID.
284 */
285const char *xhci_ec_str_id(unsigned id)
286{
287 static char buf [20];
288
289 if (id < XHCI_EC_MAX && ec_ids[id] != NULL)
290 return ec_ids[id];
291
292 snprintf(buf, sizeof(buf), "<unknown (%u)>", id);
293 return buf;
294}
295
296/**
297 * Dump Protocol Speed ID.
298 */
299static void xhci_dump_psi(const xhci_psi_t *psi)
300{
301 static const char speed_exp [] = " KMG";
302 static const char *psi_types [] = { "", " rsvd", " RX", " TX" };
303
304 usb_log_debug("Speed %u%s: %5u %cb/s, %s",
305 XHCI_REG_RD(psi, XHCI_PSI_PSIV),
306 psi_types[XHCI_REG_RD(psi, XHCI_PSI_PLT)],
307 XHCI_REG_RD(psi, XHCI_PSI_PSIM),
308 speed_exp[XHCI_REG_RD(psi, XHCI_PSI_PSIE)],
309 XHCI_REG_RD(psi, XHCI_PSI_PFD) ? "full-duplex" : "");
310}
311
312/**
313 * Dump given Extended Capability.
314 */
315void xhci_dump_extcap(const xhci_extcap_t *ec)
316{
317 xhci_sp_name_t name;
318 unsigned ports_from, ports_to;
319
320 unsigned id = XHCI_REG_RD(ec, XHCI_EC_CAP_ID);
321 usb_log_debug("Extended capability %s", xhci_ec_str_id(id));
322
323 switch (id) {
324 case XHCI_EC_SUPPORTED_PROTOCOL:
325 name.packed = host2uint32_t_le(XHCI_REG_RD(ec, XHCI_EC_SP_NAME));
326 ports_from = XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF);
327 ports_to = ports_from + XHCI_REG_RD(ec, XHCI_EC_SP_CP_COUNT) - 1;
328 unsigned psic = XHCI_REG_RD(ec, XHCI_EC_SP_PSIC);
329
330 usb_log_debug("\tProtocol %.4s%u.%u, ports %u-%u, "
331 "%u protocol speeds", name.str,
332 XHCI_REG_RD(ec, XHCI_EC_SP_MAJOR),
333 XHCI_REG_RD(ec, XHCI_EC_SP_MINOR),
334 ports_from, ports_to, psic);
335
336 for (unsigned i = 0; i < psic; i++)
337 xhci_dump_psi(xhci_extcap_psi(ec, i));
338 break;
339 }
340}
341
342void xhci_dump_slot_ctx(const struct xhci_slot_ctx *ctx)
343{
344#define SLOT_DUMP(name) usb_log_debug("\t" #name ":\t0x%x", XHCI_SLOT_##name(*ctx))
345 SLOT_DUMP(ROUTE_STRING);
346 SLOT_DUMP(SPEED);
347 SLOT_DUMP(MTT);
348 SLOT_DUMP(HUB);
349 SLOT_DUMP(CTX_ENTRIES);
350 SLOT_DUMP(MAX_EXIT_LATENCY);
351 SLOT_DUMP(ROOT_HUB_PORT);
352 SLOT_DUMP(NUM_PORTS);
353 SLOT_DUMP(TT_HUB_SLOT_ID);
354 SLOT_DUMP(TT_PORT_NUM);
355 SLOT_DUMP(TT_THINK_TIME);
356 SLOT_DUMP(INTERRUPTER);
357 SLOT_DUMP(DEVICE_ADDRESS);
358 SLOT_DUMP(STATE);
359#undef SLOT_DUMP
360}
361
362void xhci_dump_endpoint_ctx(const struct xhci_endpoint_ctx *ctx)
363{
364#define EP_DUMP_DW(name) usb_log_debug("\t" #name ":\t0x%x", XHCI_EP_##name(*ctx))
365#define EP_DUMP_QW(name) usb_log_debug("\t" #name ":\t0x%" PRIx64, XHCI_EP_##name(*ctx))
366 EP_DUMP_DW(STATE);
367 EP_DUMP_DW(MULT);
368 EP_DUMP_DW(MAX_P_STREAMS);
369 EP_DUMP_DW(LSA);
370 EP_DUMP_DW(INTERVAL);
371 EP_DUMP_DW(ERROR_COUNT);
372 EP_DUMP_DW(TYPE);
373 EP_DUMP_DW(HID);
374 EP_DUMP_DW(MAX_BURST_SIZE);
375 EP_DUMP_DW(MAX_PACKET_SIZE);
376 EP_DUMP_QW(DCS);
377 EP_DUMP_QW(TR_DPTR);
378 EP_DUMP_DW(MAX_ESIT_PAYLOAD_LO);
379 EP_DUMP_DW(MAX_ESIT_PAYLOAD_HI);
380#undef EP_DUMP_DW
381#undef EP_DUMP_QW
382}
383
384void xhci_dump_input_ctx(const xhci_hc_t *hc, const struct xhci_input_ctx *ictx)
385{
386 xhci_device_ctx_t *device_ctx = XHCI_GET_DEVICE_CTX(ictx, hc);
387 xhci_slot_ctx_t *slot_ctx = XHCI_GET_SLOT_CTX(device_ctx, hc);
388 xhci_input_ctrl_ctx_t *ctrl_ctx = XHCI_GET_CTRL_CTX(ictx, hc);
389
390 usb_log_debug("Input control context:");
391 usb_log_debug("\tDrop:\t0x%08x", xhci2host(32, ctrl_ctx->data[0]));
392 usb_log_debug("\tAdd:\t0x%08x", xhci2host(32, ctrl_ctx->data[1]));
393
394 usb_log_debug("\tConfig:\t0x%02x", XHCI_INPUT_CTRL_CTX_CONFIG_VALUE(*ctrl_ctx));
395 usb_log_debug("\tIface:\t0x%02x", XHCI_INPUT_CTRL_CTX_IFACE_NUMBER(*ctrl_ctx));
396 usb_log_debug("\tAlternate:\t0x%02x", XHCI_INPUT_CTRL_CTX_ALTER_SETTING(*ctrl_ctx));
397
398 usb_log_debug("Slot context:");
399 xhci_dump_slot_ctx(slot_ctx);
400
401 for (uint8_t dci = 1; dci <= XHCI_EP_COUNT; dci++)
402 if (XHCI_INPUT_CTRL_CTX_DROP(*ctrl_ctx, dci) ||
403 XHCI_INPUT_CTRL_CTX_ADD(*ctrl_ctx, dci)) {
404 usb_log_debug("Endpoint context DCI %u:", dci);
405 xhci_ep_ctx_t *ep_ctx = XHCI_GET_EP_CTX(device_ctx, hc, dci);
406 xhci_dump_endpoint_ctx(ep_ctx);
407 }
408}
409
410/**
411 * @}
412 */
Note: See TracBrowser for help on using the repository browser.