coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ehci_debug.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <stdint.h>
4 #include <console/console.h>
5 #include <console/usb.h>
6 #include <arch/io.h>
7 #include <device/mmio.h>
8 #include <arch/symbols.h>
9 #include <string.h>
10 #include <cbmem.h>
11 
12 #include "ehci_debug.h"
13 #include "usb_ch9.h"
14 #include "ehci.h"
15 
19 
22 
23 #if CONFIG(DEBUG_CONSOLE_INIT)
24 /* When selected, you can debug the connection of usbdebug dongle.
25  * EHCI port register bits and USB packets are dumped on console,
26  * assuming some other console already works.
27  */
28 # define dprintk(LEVEL, args...) \
29  do { if (!dbgp_enabled()) printk(LEVEL, ##args); } while (0)
30 #else
31 # define dprintk(LEVEL, args...) do {} while (0)
32 #endif
33 
34 #define DBGP_LEN_UPDATE(x, len) (((x) & ~0x0f) | ((len) & 0x0f))
35 
36 #define DBGP_CLAIM (DBGP_OWNER | DBGP_ENABLED | DBGP_INUSE)
37 
38 #define HUB_ROOT_RESET_TIME 50 /* times are in msec */
39 #define HUB_SHORT_RESET_TIME 10
40 #define HUB_LONG_RESET_TIME 200
41 #define HUB_RESET_TIMEOUT 500
42 
43 #define DBGP_MICROFRAME_TIMEOUT_LOOPS 1000
44 #define DBGP_MICROFRAME_RETRIES 10
45 #define DBGP_MAX_PACKET 8
46 
47 static int dbgp_enabled(void);
48 static void dbgp_print_data(struct ehci_dbg_port *ehci_debug);
49 
50 static struct ehci_debug_info glob_dbg_info;
52 
53 static inline struct ehci_debug_info *dbgp_ehci_info(void)
54 {
55  if (glob_dbg_info_p == NULL) {
56  struct ehci_debug_info *info;
58  /* The message likely does not show if we hit this. */
59  if (sizeof(*info) > _car_ehci_dbg_info_size)
60  die("BUG: Increase ehci_dbg_info reserve in CAR");
61  info = (void *)_car_ehci_dbg_info;
62  } else {
64  }
66  }
67  return glob_dbg_info_p;
68 }
69 
71 {
72  u32 ctrl;
73  int loop = 0;
74 
75  do {
76  ctrl = read32(&ehci_debug->control);
77  /* Stop when the transaction is finished */
78  if (ctrl & DBGP_DONE)
79  break;
80  } while (++loop < DBGP_MICROFRAME_TIMEOUT_LOOPS);
81 
82  if (! (ctrl & DBGP_DONE)) {
83  dprintk(BIOS_ERR, "%s: retry timeout.\n", __func__);
84  return -DBGP_ERR_SIGNAL;
85  }
86 
87  /* Now that we have observed the completed transaction,
88  * clear the done bit.
89  */
90  write32(&ehci_debug->control, ctrl | DBGP_DONE);
91  return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl);
92 }
93 
94 static void dbgp_breath(void)
95 {
96  /* Sleep to give the debug port a chance to breathe */
97 }
98 
100  unsigned int ctrl, const int timeout)
101 {
102  u32 rd_ctrl, rd_pids;
103  u32 ctrl_prev = 0, pids_prev = 0;
104  u8 lpid;
105  int ret, host_retries;
106  int loop;
107 
108  loop = 0;
109 device_retry:
110  host_retries = 0;
111  if (loop++ >= timeout)
112  return -DBGP_ERR_BAD;
113 
114 host_retry:
115  if (host_retries++ >= DBGP_MICROFRAME_RETRIES)
116  return -DBGP_ERR_BAD;
117  if (loop == 1 || host_retries > 1)
118  dprintk(BIOS_SPEW, "dbgp: start (@ %3d,%d) ctrl=%08x\n",
119  loop, host_retries, ctrl | DBGP_GO);
120  write32(&ehci_debug->control, ctrl | DBGP_GO);
122  rd_ctrl = read32(&ehci_debug->control);
123  rd_pids = read32(&ehci_debug->pids);
124 
125  if (rd_ctrl != ctrl_prev || rd_pids != pids_prev || (ret<0)) {
126  ctrl_prev = rd_ctrl;
127  pids_prev = rd_pids;
128  dprintk(BIOS_SPEW, "dbgp: status (@ %3d,%d) ctrl=%08x pids=%08x ret=%d\n",
129  loop, host_retries, rd_ctrl, rd_pids, ret);
130  }
131 
132  /* Controller hardware failure. */
133  if (ret == -DBGP_ERR_SIGNAL) {
134  return ret;
135 
136  /* Bus failure (corrupted microframe). */
137  } else if (ret == -DBGP_ERR_BAD) {
138  goto host_retry;
139  }
140 
141  lpid = DBGP_PID_GET(rd_pids);
142 
143  /* If I get an ACK or in-sync DATA PID, we are done. */
144  if ((lpid == USB_PID_ACK) || (lpid == pipe->pid)) {
145  pipe->pid ^= USB_PID_DATA_TOGGLE;
146  }
147 
148  /* If the port is getting full or it has dropped data
149  * start pacing ourselves, not necessary but it's friendly.
150  */
151  else if (lpid == USB_PID_NYET) {
152  dbgp_breath();
153  goto device_retry;
154  }
155 
156  /* If I get a NACK or out-of-sync DATA PID, reissue the transmission. */
157  else if ((lpid == USB_PID_NAK) || (lpid == (pipe->pid ^ USB_PID_DATA_TOGGLE))) {
158  goto device_retry;
159  }
160 
161  /* Abort on STALL handshake for endpoint 0.*/
162  else if ((lpid == USB_PID_STALL) && (pipe->endpoint == 0x0)) {
163  ret = -DBGP_ERR_BAD;
164  }
165 
167 
168  return ret;
169 }
170 
171 static void dbgp_set_data(struct ehci_dbg_port *ehci_debug, const void *buf, int size)
172 {
173  const unsigned char *bytes = buf;
174  u32 lo, hi;
175  int i;
176 
177  lo = hi = 0;
178  for (i = 0; i < 4 && i < size; i++)
179  lo |= bytes[i] << (8*i);
180  for (; i < 8 && i < size; i++)
181  hi |= bytes[i] << (8*(i - 4));
182  write32(&ehci_debug->data03, lo);
183  write32(&ehci_debug->data47, hi);
184 }
185 
186 static void dbgp_get_data(struct ehci_dbg_port *ehci_debug, void *buf, int size)
187 {
188  unsigned char *bytes = buf;
189  u32 lo, hi;
190  int i;
191 
192  lo = read32(&ehci_debug->data03);
193  hi = read32(&ehci_debug->data47);
194  for (i = 0; i < 4 && i < size; i++)
195  bytes[i] = (lo >> (8*i)) & 0xff;
196  for (; i < 8 && i < size; i++)
197  bytes[i] = (hi >> (8*(i - 4))) & 0xff;
198 }
199 
201 {
202  int len;
203  u32 ctrl, lo, hi;
204 
205  if (!CONFIG(DEBUG_CONSOLE_INIT) || dbgp_enabled())
206  return;
207 
208  ctrl = read32(&ehci_debug->control);
209  lo = read32(&ehci_debug->data03);
210  hi = read32(&ehci_debug->data47);
211 
212  len = DBGP_LEN(ctrl);
213  if (len) {
214  int i;
215  dprintk(BIOS_SPEW, "dbgp: buf:");
216  for (i = 0; i < 4 && i < len; i++)
217  dprintk(BIOS_SPEW, " %02x", (lo >> (8*i)) & 0xff);
218  for (; i < 8 && i < len; i++)
219  dprintk(BIOS_SPEW, " %02x", (hi >> (8*(i - 4))) & 0xff);
220  dprintk(BIOS_SPEW, "\n");
221  }
222 }
223 
225  const char *bytes, int size)
226 {
227  u32 pids, addr, ctrl;
228  int ret;
229 
230  if (size > DBGP_MAX_PACKET)
231  return -1;
232 
233  addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
234  pids = DBGP_PID_SET(pipe->pid, USB_PID_OUT);
235 
236  ctrl = read32(&ehci_debug->control);
237  ctrl = DBGP_LEN_UPDATE(ctrl, size);
238  ctrl |= DBGP_OUT;
239 
240  dbgp_set_data(ehci_debug, bytes, size);
241  write32(&ehci_debug->address, addr);
242  write32(&ehci_debug->pids, pids);
243 
244  ret = dbgp_wait_until_done(ehci_debug, pipe, ctrl, pipe->timeout);
245 
246  return ret;
247 }
248 
249 int dbgp_bulk_write_x(struct dbgp_pipe *pipe, const char *bytes, int size)
250 {
251  struct ehci_debug_info *dbg_info = dbgp_ehci_info();
252  struct ehci_dbg_port *port;
253  port = (void *)(uintptr_t)dbg_info->ehci_debug;
254  return dbgp_bulk_write(port, pipe, bytes, size);
255 }
256 
257 static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
258  void *data, int size)
259 {
260  u32 pids, addr, ctrl;
261  int ret;
262 
263  if (size > DBGP_MAX_PACKET)
264  return -1;
265 
266  addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
267  pids = DBGP_PID_SET(pipe->pid, USB_PID_IN);
268 
269  ctrl = read32(&ehci_debug->control);
270  ctrl = DBGP_LEN_UPDATE(ctrl, size);
271  ctrl &= ~DBGP_OUT;
272 
273  write32(&ehci_debug->address, addr);
274  write32(&ehci_debug->pids, pids);
275  ret = dbgp_wait_until_done(ehci_debug, pipe, ctrl, pipe->timeout);
276  if (ret < 0)
277  return ret;
278 
279  if (size > ret)
280  size = ret;
281  dbgp_get_data(ehci_debug, data, size);
282  return ret;
283 }
284 
285 int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size)
286 {
287  struct ehci_debug_info *dbg_info = dbgp_ehci_info();
288  struct ehci_dbg_port *port;
289  port = (void *)(uintptr_t)dbg_info->ehci_debug;
290  return dbgp_bulk_read(port, pipe, data, size);
291 }
292 
293 void dbgp_mdelay(int ms)
294 {
295  int i;
296 
297  while (ms--) {
298  for (i = 0; i < 1000; i++)
299  inb(0x80);
300  }
301 }
302 
303 int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned int devnum, int requesttype,
304  int request, int value, int index, void *data, int size)
305 {
306  struct ehci_debug_info *info = dbgp_ehci_info();
307  struct dbgp_pipe *pipe = &info->ep_pipe[DBGP_SETUP_EP0];
308  u32 pids, addr, ctrl;
309  struct usb_ctrlrequest req;
310  int read;
311  int ret, ret2;
312 
313  read = (requesttype & USB_DIR_IN) != 0;
314  if (size > DBGP_MAX_PACKET)
315  return -1;
316 
317  /* Compute the control message */
318  req.bRequestType = requesttype;
319  req.bRequest = request;
320  req.wValue = cpu_to_le16(value);
321  req.wIndex = cpu_to_le16(index);
322  req.wLength = cpu_to_le16(size);
323 
324  pipe->devnum = devnum;
325  pipe->endpoint = 0;
326  pipe->pid = USB_PID_DATA0;
327  pipe->timeout = 1000;
328  addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
329  pids = DBGP_PID_SET(pipe->pid, USB_PID_SETUP);
330 
331  ctrl = read32(&ehci_debug->control);
332  ctrl = DBGP_LEN_UPDATE(ctrl, sizeof(req));
333  ctrl |= DBGP_OUT;
334 
335  /* Setup stage */
336  dbgp_set_data(ehci_debug, &req, sizeof(req));
337  write32(&ehci_debug->address, addr);
338  write32(&ehci_debug->pids, pids);
339  ret = dbgp_wait_until_done(ehci_debug, pipe, ctrl, 1);
340  if (ret < 0)
341  return ret;
342 
343  /* Data stage (optional) */
344  if (read && size)
345  ret = dbgp_bulk_read(ehci_debug, pipe, data, size);
346  else if (!read && size)
347  ret = dbgp_bulk_write(ehci_debug, pipe, data, size);
348 
349  /* Status stage in opposite direction */
350  pipe->pid = USB_PID_DATA1;
351  ctrl = read32(&ehci_debug->control);
352  ctrl = DBGP_LEN_UPDATE(ctrl, 0);
353  if (read) {
354  pids = DBGP_PID_SET(pipe->pid, USB_PID_OUT);
355  ctrl |= DBGP_OUT;
356  } else {
357  pids = DBGP_PID_SET(pipe->pid, USB_PID_IN);
358  ctrl &= ~DBGP_OUT;
359  }
360 
361  write32(&ehci_debug->pids, pids);
362  ret2 = dbgp_wait_until_done(ehci_debug, pipe, ctrl, pipe->timeout);
363  if (ret2 < 0)
364  return ret2;
365 
366  return ret;
367 }
368 
369 static int ehci_reset_port(struct ehci_regs *ehci_regs, int port)
370 {
371  u32 portsc;
372  int loop;
373 
374  /* Reset the USB debug port */
375  portsc = read32(&ehci_regs->port_status[port - 1]);
376  portsc &= ~PORT_PE;
377  portsc |= PORT_RESET;
378  write32(&ehci_regs->port_status[port - 1], portsc);
379 
381 
382  portsc = read32(&ehci_regs->port_status[port - 1]);
384  portsc & ~(PORT_RWC_BITS | PORT_RESET));
385 
386  loop = 100;
387  do {
388  dbgp_mdelay(1);
389  portsc = read32(&ehci_regs->port_status[port - 1]);
390  } while ((portsc & PORT_RESET) && (--loop > 0));
391 
392  /* Device went away? */
393  if (!(portsc & PORT_CONNECT))
394  return -1; //-ENOTCONN;
395 
396  /* bomb out completely if something weird happened */
397  if ((portsc & PORT_CSC))
398  return -2; //-EINVAL;
399 
400  /* If we've finished resetting, then break out of the loop */
401  if (!(portsc & PORT_RESET) && (portsc & PORT_PE))
402  return 0;
403 
404  return -3; //-EBUSY;
405 }
406 
407 static int ehci_wait_for_port(struct ehci_regs *ehci_regs, int port)
408 {
409  u32 status;
410  int ret, reps;
411 
412  for (reps = 0; reps < 3; reps++) {
413  dbgp_mdelay(100);
414  status = read32(&ehci_regs->status);
415  if (status & STS_PCD) {
417  if (ret == 0)
418  return 0;
419  }
420  }
421  return -1; //-ENOTCONN;
422 }
423 
424 static int usbdebug_init_(uintptr_t ehci_bar, unsigned int offset, struct ehci_debug_info *info)
425 {
426  struct ehci_caps *ehci_caps;
427  struct ehci_regs *ehci_regs;
428 
429  u32 cmd, ctrl, status, portsc, hcs_params;
430  u32 debug_port, new_debug_port = 0, n_ports;
431  int ret, i;
432  int loop;
433  int port_map_tried;
434  int playtimes = 3;
435 
436  /* Keep all endpoints disabled before any printk() call. */
437  memset(info, 0, sizeof(*info));
438  info->ehci_base = ehci_bar;
439  info->ehci_debug = ehci_bar + offset;
440  info->ep_pipe[0].status |= DBGP_EP_NOT_PRESENT;
441 
442  dprintk(BIOS_INFO, "ehci_bar: 0x%lx debug_offset 0x%x\n", ehci_bar, offset);
443 
444  ehci_caps = (struct ehci_caps *)ehci_bar;
445  ehci_regs = (struct ehci_regs *)(ehci_bar +
447 
448  struct ehci_dbg_port *ehci_debug = (void *)(uintptr_t)info->ehci_debug;
449 
450  if (CONFIG_USBDEBUG_DEFAULT_PORT > 0)
451  ehci_debug_select_port(CONFIG_USBDEBUG_DEFAULT_PORT);
452  else
454 
455 try_next_time:
456  port_map_tried = 0;
457 
458 try_next_port:
459  hcs_params = read32(&ehci_caps->hcs_params);
460  debug_port = HCS_DEBUG_PORT(hcs_params);
461  n_ports = HCS_N_PORTS(hcs_params);
462 
463  dprintk(BIOS_INFO, "debug_port: %d\n", debug_port);
464  dprintk(BIOS_INFO, "n_ports: %d\n", n_ports);
465 
466  for (i = 1; i <= n_ports; i++) {
467  portsc = read32(&ehci_regs->port_status[i-1]);
468  dprintk(BIOS_INFO, "PORTSC #%d: %08x\n", i, portsc);
469  }
470 
471  if (port_map_tried && (new_debug_port != debug_port)) {
472  if (--playtimes) {
473  ehci_debug_select_port(debug_port);
474  goto try_next_time;
475  }
476  return -1;
477  }
478 
479  /* Wait until the controller is halted */
480  status = read32(&ehci_regs->status);
481  if (!(status & STS_HALT)) {
482  cmd = read32(&ehci_regs->command);
483  cmd &= ~CMD_RUN;
484  write32(&ehci_regs->command, cmd);
485  loop = 100;
486  do {
487  dbgp_mdelay(10);
488  status = read32(&ehci_regs->status);
489  } while (!(status & STS_HALT) && (--loop > 0));
490  if (status & STS_HALT)
491  dprintk(BIOS_INFO, "EHCI controller halted successfully.\n");
492  else
493  dprintk(BIOS_INFO, "EHCI controller is not halted. Reset may fail.\n");
494  }
495 
496  loop = 100;
497  /* Reset the EHCI controller */
498  cmd = read32(&ehci_regs->command);
499  cmd |= CMD_RESET;
500  write32(&ehci_regs->command, cmd);
501  do {
502  dbgp_mdelay(10);
503  cmd = read32(&ehci_regs->command);
504  } while ((cmd & CMD_RESET) && (--loop > 0));
505 
506  if (!loop) {
507  dprintk(BIOS_INFO, "Could not reset EHCI controller.\n");
508  // on some systems it works without succeeding here.
509  // return -2;
510  } else {
511  dprintk(BIOS_INFO, "EHCI controller reset successfully.\n");
512  }
513 
514  /* Claim ownership, but do not enable yet */
515  ctrl = read32(&ehci_debug->control);
516  ctrl |= DBGP_OWNER;
517  ctrl &= ~(DBGP_ENABLED | DBGP_INUSE);
518  write32(&ehci_debug->control, ctrl);
519 
520  /* Start EHCI controller */
521  cmd = read32(&ehci_regs->command);
522  cmd &= ~(CMD_LRESET | CMD_IAAD | CMD_PSE | CMD_ASE | CMD_RESET);
523  cmd |= CMD_RUN;
524  write32(&ehci_regs->command, cmd);
525 
526  /* Ensure everything is routed to the EHCI */
528 
529  /* Wait until the controller is no longer halted */
530  loop = 10;
531  do {
532  dbgp_mdelay(10);
533  status = read32(&ehci_regs->status);
534  } while ((status & STS_HALT) && (--loop > 0));
535 
536  if (!loop) {
537  dprintk(BIOS_INFO, "EHCI could not be started.\n");
538  return -3;
539  }
540  dprintk(BIOS_INFO, "EHCI started.\n");
541 
542  /* Wait for a device to show up in the debug port */
543  ret = ehci_wait_for_port(ehci_regs, debug_port);
544  if (ret < 0) {
545  dprintk(BIOS_INFO, "No device found in debug port %d\n", debug_port);
546  goto next_debug_port;
547  }
548  dprintk(BIOS_INFO, "EHCI done waiting for port.\n");
549 
550  /* Enable the debug port */
551  ctrl = read32(&ehci_debug->control);
552  ctrl |= DBGP_CLAIM;
553  write32(&ehci_debug->control, ctrl);
554  ctrl = read32(&ehci_debug->control);
555  if ((ctrl & DBGP_CLAIM) != DBGP_CLAIM) {
556  dprintk(BIOS_INFO, "No device in EHCI debug port.\n");
557  write32(&ehci_debug->control, ctrl & ~DBGP_CLAIM);
558  ret = -4;
559  goto err;
560  }
561  dprintk(BIOS_INFO, "EHCI debug port enabled.\n");
562 
563  dbgp_mdelay(100);
564 
565  struct ehci_dbg_port *port = (void *)(uintptr_t)info->ehci_debug;
566  ret = dbgp_probe_gadget(port, &info->ep_pipe[0]);
567  if (ret < 0) {
568  dprintk(BIOS_INFO, "Could not probe gadget on debug port.\n");
569  ret = -6;
570  goto err;
571  }
572 
573  info->ep_pipe[0].status &= ~DBGP_EP_NOT_PRESENT;
574 
575  return 0;
576 err:
577  /* Things didn't work so remove my claim */
578  ctrl = read32(&ehci_debug->control);
579  ctrl &= ~(DBGP_CLAIM | DBGP_OUT);
580  write32(&ehci_debug->control, ctrl);
581  //return ret;
582 
583 next_debug_port:
584  if (CONFIG_USBDEBUG_DEFAULT_PORT == 0) {
585  port_map_tried |= (1 << (debug_port - 1));
586  new_debug_port = ((debug_port-1 + 1) % n_ports) + 1;
587  if (port_map_tried != ((1 << n_ports) - 1)) {
588  ehci_debug_select_port(new_debug_port);
589  goto try_next_port;
590  }
591  if (--playtimes) {
592  ehci_debug_select_port(new_debug_port);
593  goto try_next_time;
594  }
595  } else {
596  if (--playtimes)
597  goto try_next_time;
598  }
599 
600  return ret;
601 }
602 
603 static int dbgp_enabled(void)
604 {
605  struct dbgp_pipe *globals = &dbgp_ehci_info()->ep_pipe[DBGP_SETUP_EP0];
606  return (globals->status & DBGP_EP_ENABLED);
607 }
608 
609 static int dbgp_not_present(void)
610 {
611  struct dbgp_pipe *globals = &dbgp_ehci_info()->ep_pipe[DBGP_SETUP_EP0];
612  return (globals->status & DBGP_EP_NOT_PRESENT);
613 }
614 
616 {
617  struct dbgp_pipe *globals = &dbgp_ehci_info()->ep_pipe[DBGP_SETUP_EP0];
618  if (!dbgp_ep_is_active(pipe) || (globals->status & DBGP_EP_BUSY))
619  return 0;
620  globals->status |= DBGP_EP_BUSY;
621  pipe->status |= DBGP_EP_BUSY;
622  return 1;
623 }
624 
625 void dbgp_put(struct dbgp_pipe *pipe)
626 {
627  struct dbgp_pipe *globals = &dbgp_ehci_info()->ep_pipe[DBGP_SETUP_EP0];
628  globals->status &= ~DBGP_EP_BUSY;
629  pipe->status &= ~DBGP_EP_BUSY;
630 }
631 
632 #if ENV_RAMSTAGE
633 void usbdebug_re_enable(uintptr_t ehci_base)
634 {
635  struct ehci_debug_info *dbg_info = dbgp_ehci_info();
636  u64 diff;
637  int i;
638 
639  diff = dbg_info->ehci_base - ehci_base;
640  dbg_info->ehci_debug -= diff;
641  dbg_info->ehci_base = ehci_base;
642 
643  for (i=0; i<DBGP_MAX_ENDPOINTS; i++)
644  if (dbg_info->ep_pipe[i].status & DBGP_EP_VALID)
645  dbg_info->ep_pipe[i].status |= DBGP_EP_ENABLED;
646 }
647 
648 void usbdebug_disable(void)
649 {
650  struct ehci_debug_info *dbg_info = dbgp_ehci_info();
651  int i;
652  for (i=0; i<DBGP_MAX_ENDPOINTS; i++)
653  dbg_info->ep_pipe[i].status &= ~DBGP_EP_ENABLED;
654 }
655 
656 #endif
657 
658 int usbdebug_hw_init(bool force)
659 {
660  struct ehci_debug_info *dbg_info = dbgp_ehci_info();
661  u32 ehci_base, dbg_offset;
662 
663  if (dbgp_enabled() && !force)
664  return 0;
665 
666  if (dbgp_not_present() && !force)
667  return -1;
668 
669  /* Do not attempt slow gadget init in postcar. */
670  if (ENV_POSTCAR)
671  return -1;
672 
673  /* Do full init if state claims we are still not enabled. */
674  if (ehci_debug_hw_enable(&ehci_base, &dbg_offset))
675  return -1;
676  return usbdebug_init_(ehci_base, dbg_offset, dbg_info);
677 }
678 
679 static void migrate_ehci_debug(int is_recovery)
680 {
681  struct ehci_debug_info *dbg_info_cbmem;
682  int rv;
683 
684  if (ENV_ROMSTAGE) {
685  /* Move state from CAR to CBMEM. */
686  struct ehci_debug_info *dbg_info = dbgp_ehci_info();
687  dbg_info_cbmem = cbmem_add(CBMEM_ID_EHCI_DEBUG,
688  sizeof(*dbg_info));
689  if (dbg_info_cbmem == NULL)
690  return;
691  memcpy(dbg_info_cbmem, dbg_info, sizeof(*dbg_info));
692  glob_dbg_info_p = dbg_info_cbmem;
693  return;
694  }
695 
696  if (CONFIG(USBDEBUG_IN_PRE_RAM)) {
697  /* Use state in CBMEM. */
698  dbg_info_cbmem = cbmem_find(CBMEM_ID_EHCI_DEBUG);
699  if (dbg_info_cbmem)
700  glob_dbg_info_p = dbg_info_cbmem;
701  }
702 
703  rv = usbdebug_hw_init(false);
704  if (rv < 0)
705  printk(BIOS_DEBUG, "usbdebug: Failed hardware init\n");
706  else
707  printk(BIOS_DEBUG, "usbdebug: " ENV_STRING " starting...\n");
708 }
709 
713 
715 {
716  return (pipe->status & DBGP_EP_STATMASK) == (DBGP_EP_VALID | DBGP_EP_ENABLED);
717 }
718 
720 {
722 }
723 
725 {
727 }
728 
729 void usbdebug_init(void)
730 {
731  /* USB console init is done early in romstage, yet delayed to
732  * CBMEM_INIT_HOOKs for postcar and ramstage as we recover state
733  * from CBMEM.
734  */
735  if (CONFIG(USBDEBUG_IN_PRE_RAM)
736  && (ENV_ROMSTAGE || ENV_BOOTBLOCK))
737  usbdebug_hw_init(false);
738 
739  /* USB console init is done early in ramstage if it was
740  * not done in romstage, this does not require CBMEM.
741  */
742  if (!CONFIG(USBDEBUG_IN_PRE_RAM) && ENV_RAMSTAGE)
743  usbdebug_hw_init(false);
744 }
pte_t value
Definition: mmu.c:91
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define _car_ehci_dbg_info_size
Definition: symbols.h:27
char _car_ehci_dbg_info[]
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
void * cbmem_find(u32 id)
Definition: imd_cbmem.c:166
#define CBMEM_ID_EHCI_DEBUG
Definition: cbmem_id.h:22
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
void __noreturn die(const char *fmt,...)
Definition: die.c:17
u8 inb(u16 port)
static struct smmstore_params_info info
Definition: ramstage.c:12
#define DBGP_EPADDR(dev, ep)
Definition: ehci.h:179
#define DBGP_INUSE
Definition: ehci.h:165
#define DBGP_LEN(x)
Definition: ehci.h:172
#define PORT_RWC_BITS
Definition: ehci.h:135
#define CMD_IAAD
Definition: ehci.h:59
#define HC_LENGTH(p)
Definition: ehci.h:16
#define PORT_RESET
Definition: ehci.h:126
#define CMD_PSE
Definition: ehci.h:61
#define DBGP_ERRCODE(x)
Definition: ehci.h:166
#define HCS_DEBUG_PORT(p)
Definition: ehci.h:19
#define CMD_RUN
Definition: ehci.h:64
#define CMD_ASE
Definition: ehci.h:60
#define CMD_LRESET
Definition: ehci.h:58
#define DBGP_GO
Definition: ehci.h:170
#define STS_HALT
Definition: ehci.h:72
#define PORT_CONNECT
Definition: ehci.h:134
#define STS_PCD
Definition: ehci.h:78
#define DBGP_ENABLED
Definition: ehci.h:163
#define DBGP_OUT
Definition: ehci.h:171
#define DBGP_PID_GET(x)
Definition: ehci.h:174
#define PORT_PE
Definition: ehci.h:132
#define DBGP_PID_SET(data, tok)
Definition: ehci.h:175
#define FLAG_CF
Definition: ehci.h:98
#define DBGP_ERROR
Definition: ehci.h:169
#define PORT_CSC
Definition: ehci.h:133
#define DBGP_ERR_BAD
Definition: ehci.h:167
#define HCS_N_PORTS(p)
Definition: ehci.h:25
#define DBGP_DONE
Definition: ehci.h:164
#define DBGP_OWNER
Definition: ehci.h:162
#define DBGP_ERR_SIGNAL
Definition: ehci.h:168
#define CMD_RESET
Definition: ehci.h:63
@ CONFIG
Definition: dsi_common.h:201
struct ehci_debug_info __packed
static struct ehci_debug_info * glob_dbg_info_p
Definition: ehci_debug.c:51
void dbgp_put(struct dbgp_pipe *pipe)
Definition: ehci_debug.c:625
static struct ehci_debug_info glob_dbg_info
Definition: ehci_debug.c:50
static void migrate_ehci_debug(int is_recovery)
Definition: ehci_debug.c:679
static int usbdebug_init_(uintptr_t ehci_bar, unsigned int offset, struct ehci_debug_info *info)
Definition: ehci_debug.c:424
static int dbgp_enabled(void)
Definition: ehci_debug.c:603
struct dbgp_pipe * dbgp_console_output(void)
Definition: ehci_debug.c:719
static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe, void *data, int size)
Definition: ehci_debug.c:257
static void dbgp_print_data(struct ehci_dbg_port *ehci_debug)
Definition: ehci_debug.c:200
ROMSTAGE_CBMEM_INIT_HOOK(migrate_ehci_debug)
POSTCAR_CBMEM_INIT_HOOK(migrate_ehci_debug)
struct dbgp_pipe * dbgp_console_input(void)
Definition: ehci_debug.c:724
#define DBGP_MAX_PACKET
Definition: ehci_debug.c:45
#define DBGP_MICROFRAME_RETRIES
Definition: ehci_debug.c:44
void dbgp_mdelay(int ms)
Definition: ehci_debug.c:293
#define HUB_ROOT_RESET_TIME
Definition: ehci_debug.c:38
static void dbgp_breath(void)
Definition: ehci_debug.c:94
int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size)
Definition: ehci_debug.c:285
static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe, const char *bytes, int size)
Definition: ehci_debug.c:224
int dbgp_ep_is_active(struct dbgp_pipe *pipe)
Definition: ehci_debug.c:714
static void dbgp_set_data(struct ehci_dbg_port *ehci_debug, const void *buf, int size)
Definition: ehci_debug.c:171
int usbdebug_hw_init(bool force)
Definition: ehci_debug.c:658
static int ehci_reset_port(struct ehci_regs *ehci_regs, int port)
Definition: ehci_debug.c:369
#define DBGP_CLAIM
Definition: ehci_debug.c:36
static int ehci_wait_for_port(struct ehci_regs *ehci_regs, int port)
Definition: ehci_debug.c:407
static int dbgp_wait_until_complete(struct ehci_dbg_port *ehci_debug)
Definition: ehci_debug.c:70
int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned int devnum, int requesttype, int request, int value, int index, void *data, int size)
Definition: ehci_debug.c:303
int dbgp_try_get(struct dbgp_pipe *pipe)
Definition: ehci_debug.c:615
#define dprintk(LEVEL, args...)
Definition: ehci_debug.c:31
RAMSTAGE_CBMEM_INIT_HOOK(migrate_ehci_debug)
int dbgp_bulk_write_x(struct dbgp_pipe *pipe, const char *bytes, int size)
Definition: ehci_debug.c:249
#define DBGP_MICROFRAME_TIMEOUT_LOOPS
Definition: ehci_debug.c:43
static struct ehci_debug_info * dbgp_ehci_info(void)
Definition: ehci_debug.c:53
static int dbgp_not_present(void)
Definition: ehci_debug.c:609
#define DBGP_LEN_UPDATE(x, len)
Definition: ehci_debug.c:34
void usbdebug_init(void)
Definition: ehci_debug.c:729
static void dbgp_get_data(struct ehci_dbg_port *ehci_debug, void *buf, int size)
Definition: ehci_debug.c:186
static int dbgp_wait_until_done(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe, unsigned int ctrl, const int timeout)
Definition: ehci_debug.c:99
int dbgp_probe_gadget(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
Definition: gadget.c:319
#define DBGP_EP_NOT_PRESENT
Definition: ehci_debug.h:20
void usbdebug_disable(void)
int ehci_debug_hw_enable(unsigned int *base, unsigned int *dbg_offset)
Definition: pci_ehci.c:19
#define DBGP_SETUP_EP0
Definition: ehci_debug.h:24
#define DBGP_CONSOLE_EPOUT
Definition: ehci_debug.h:25
#define DBGP_EP_VALID
Definition: ehci_debug.h:17
void usbdebug_re_enable(uintptr_t ehci_base)
#define DBGP_CONSOLE_EPIN
Definition: ehci_debug.h:26
#define DBGP_EP_BUSY
Definition: ehci_debug.h:19
#define DBGP_EP_STATMASK
Definition: ehci_debug.h:21
#define DBGP_EP_ENABLED
Definition: ehci_debug.h:18
#define DBGP_MAX_ENDPOINTS
Definition: ehci_debug.h:23
void ehci_debug_select_port(unsigned int port)
Definition: pci_ehci.c:62
static size_t offset
Definition: flashconsole.c:16
pipe
Definition: i915.h:38
port
Definition: i915.h:29
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
static uint8_t * buf
Definition: uart.c:7
#define ENV_BOOTBLOCK
Definition: rules.h:148
#define ENV_RAMSTAGE
Definition: rules.h:150
#define ENV_ROMSTAGE
Definition: rules.h:149
#define ENV_STRING
Definition: rules.h:156
#define ENV_SEPARATE_VERSTAGE
Definition: rules.h:152
#define ENV_POSTCAR
Definition: rules.h:154
#define NULL
Definition: stddef.h:19
uint64_t u64
Definition: stdint.h:54
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint8_t u8
Definition: stdint.h:45
Definition: ehci.h:11
u32 hcs_params
Definition: ehci.h:18
u32 hc_capbase
Definition: ehci.h:15
u32 address
Definition: ehci.h:178
u32 control
Definition: ehci.h:161
u32 pids
Definition: ehci.h:173
struct dbgp_pipe ep_pipe[DBGP_MAX_ENDPOINTS]
Definition: ehci_debug.c:20
Definition: ehci.h:44
u32 configured_flag
Definition: ehci.h:97
u32 status
Definition: ehci.h:67
u32 port_status[0]
Definition: ehci.h:101
u32 command
Definition: ehci.h:47
#define USB_PID_NYET
Definition: usb_ch9.h:79
#define USB_DIR_IN
Definition: usb_ch9.h:7
#define USB_PID_ACK
Definition: usb_ch9.h:76
#define USB_PID_SETUP
Definition: usb_ch9.h:74
#define USB_PID_NAK
Definition: usb_ch9.h:77
#define USB_PID_OUT
Definition: usb_ch9.h:71
#define USB_PID_DATA_TOGGLE
Definition: usb_ch9.h:92
#define USB_PID_DATA0
Definition: usb_ch9.h:81
#define USB_PID_IN
Definition: usb_ch9.h:72
#define USB_PID_STALL
Definition: usb_ch9.h:78
#define USB_PID_DATA1
Definition: usb_ch9.h:82