Changeset 91ca111 in mainline
- Timestamp:
- 2017-06-23T11:18:50Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 51b2693
- Parents:
- e4d7363
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/debug.c
re4d7363 r91ca111 35 35 36 36 #include <inttypes.h> 37 #include <byteorder.h> 37 38 #include <usb/debug.h> 38 39 … … 60 61 * Dumps all capability registers. 61 62 */ 62 void xhci_dump_cap_regs( xhci_cap_regs_t *cap)63 void xhci_dump_cap_regs(const xhci_cap_regs_t *cap) 63 64 { 64 65 usb_log_debug2("Capabilities:"); … … 99 100 } 100 101 101 void xhci_dump_port( xhci_port_regs_t *port)102 void xhci_dump_port(const xhci_port_regs_t *port) 102 103 { 103 104 DUMP_REG(port, XHCI_PORT_CCS); … … 124 125 } 125 126 126 void xhci_dump_state( xhci_hc_t *hc)127 void xhci_dump_state(const xhci_hc_t *hc) 127 128 { 128 129 usb_log_debug2("Operational registers:"); … … 171 172 } 172 173 173 void xhci_dump_ports( xhci_hc_t *hc)174 void xhci_dump_ports(const xhci_hc_t *hc) 174 175 { 175 176 const size_t num_ports = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PORTS); … … 230 231 } 231 232 232 void xhci_dump_trb( xhci_trb_t *trb)233 void xhci_dump_trb(const xhci_trb_t *trb) 233 234 { 234 235 usb_log_debug2("TRB(%p): type %s, cycle %u", trb, xhci_trb_str_type(TRB_TYPE(*trb)), TRB_CYCLE(*trb)); 236 } 237 238 static const char *ec_ids [] = { 239 [0] = "<empty>", 240 #define EC(t) [XHCI_EC_##t] = #t 241 EC(USB_LEGACY), 242 EC(SUPPORTED_PROTOCOL), 243 EC(EXTENDED_POWER_MANAGEMENT), 244 EC(IOV), 245 EC(MSI), 246 EC(LOCALMEM), 247 EC(DEBUG), 248 EC(MSIX), 249 #undef EC 250 [XHCI_EC_MAX] = NULL 251 }; 252 253 const char *xhci_ec_str_id(unsigned id) 254 { 255 static char buf [20]; 256 257 if (id < XHCI_EC_MAX && ec_ids[id] != NULL) 258 return ec_ids[id]; 259 260 snprintf(buf, sizeof(buf), "<unknown (%u)>", id); 261 return buf; 262 } 263 264 static void xhci_dump_psi(const xhci_psi_t *psi) 265 { 266 static const char speed_exp [] = " KMG"; 267 static const char *psi_types [] = { "", " rsvd", " RX", " TX" }; 268 269 usb_log_debug("Speed %u%s: %5u %cb/s, %s", 270 XHCI_REG_RD(psi, XHCI_PSI_PSIV), 271 psi_types[XHCI_REG_RD(psi, XHCI_PSI_PLT)], 272 XHCI_REG_RD(psi, XHCI_PSI_PSIM), 273 speed_exp[XHCI_REG_RD(psi, XHCI_PSI_PSIE)], 274 XHCI_REG_RD(psi, XHCI_PSI_PFD) ? "full-duplex" : ""); 275 } 276 277 void xhci_dump_extcap(const xhci_extcap_t *ec) 278 { 279 xhci_sp_name_t name; 280 unsigned ports_from, ports_to; 281 282 unsigned id = XHCI_REG_RD(ec, XHCI_EC_CAP_ID); 283 usb_log_debug("Extended capability %s", xhci_ec_str_id(id)); 284 285 switch (id) { 286 case XHCI_EC_SUPPORTED_PROTOCOL: 287 name.packed = host2uint32_t_le(XHCI_REG_RD(ec, XHCI_EC_SP_NAME)); 288 ports_from = XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF); 289 ports_to = ports_from + XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF) - 1; 290 usb_log_debug("\tProtocol %4s%u.%u, ports %u-%u", name.str, 291 XHCI_REG_RD(ec, XHCI_EC_SP_MAJOR), 292 XHCI_REG_RD(ec, XHCI_EC_SP_MINOR), 293 ports_from, ports_to); 294 295 unsigned psic = XHCI_REG_RD(ec, XHCI_EC_SP_PSIC); 296 for (unsigned i = 0; i < psic; i++) 297 xhci_dump_psi(xhci_extcap_psi(ec, i)); 298 break; 299 } 235 300 } 236 301 -
uspace/drv/bus/usb/xhci/debug.h
re4d7363 r91ca111 37 37 #define XHCI_DEBUG_H 38 38 39 /** 40 * As the debug header is likely to be included in every file, avoid including 41 * all headers of xhci to support "include what you use". 42 */ 39 43 struct xhci_hc; 40 44 struct xhci_cap_regs; 41 45 struct xhci_port_regs; 42 46 struct xhci_trb; 47 struct xhci_extcap; 43 48 44 49 void xhci_dump_cap_regs(const struct xhci_cap_regs *); 45 void xhci_dump_port( struct xhci_port_regs *);46 void xhci_dump_state( struct xhci_hc *);47 void xhci_dump_ports( struct xhci_hc *);50 void xhci_dump_port(const struct xhci_port_regs *); 51 void xhci_dump_state(const struct xhci_hc *); 52 void xhci_dump_ports(const struct xhci_hc *); 48 53 49 54 const char *xhci_trb_str_type(unsigned); 50 void xhci_dump_trb(struct xhci_trb *trb); 55 void xhci_dump_trb(const struct xhci_trb *trb); 56 57 const char *xhci_ec_str_id(unsigned); 58 void xhci_dump_extcap(const struct xhci_extcap *); 51 59 52 60 #endif -
uspace/drv/bus/usb/xhci/hc.c
re4d7363 r91ca111 69 69 }; 70 70 71 /** 72 * Default USB Speed ID mapping: Table 157 73 */ 74 #define PSI_TO_BPS(psie, psim) (((uint64_t) psim) << (10 * psie)) 75 #define PORT_SPEED(psie, psim) { \ 76 .rx_bps = PSI_TO_BPS(psie, psim), \ 77 .tx_bps = PSI_TO_BPS(psie, psim) \ 78 } 79 static const xhci_port_speed_t ps_default_full = PORT_SPEED(2, 12); 80 static const xhci_port_speed_t ps_default_low = PORT_SPEED(1, 1500); 81 static const xhci_port_speed_t ps_default_high = PORT_SPEED(2, 480); 82 static const xhci_port_speed_t ps_default_super = PORT_SPEED(3, 5); 83 84 /** 85 * Walk the list of extended capabilities. 86 */ 87 static int hc_parse_ec(xhci_hc_t *hc) 88 { 89 unsigned psic, major; 90 91 for (xhci_extcap_t *ec = hc->xecp; ec; ec = xhci_extcap_next(ec)) { 92 xhci_dump_extcap(ec); 93 switch (XHCI_REG_RD(ec, XHCI_EC_CAP_ID)) { 94 case XHCI_EC_USB_LEGACY: 95 assert(hc->legsup == NULL); 96 hc->legsup = (xhci_legsup_t *) ec; 97 break; 98 case XHCI_EC_SUPPORTED_PROTOCOL: 99 psic = XHCI_REG_RD(ec, XHCI_EC_SP_PSIC); 100 major = XHCI_REG_RD(ec, XHCI_EC_SP_MAJOR); 101 102 // "Implied" speed 103 if (psic == 0) { 104 /* 105 * According to section 7.2.2.1.2, only USB 2.0 106 * and USB 3.0 can have psic == 0. So we 107 * blindly assume the name == "USB " and minor 108 * == 0. 109 */ 110 if (major == 2) { 111 hc->speeds[1] = ps_default_full; 112 hc->speeds[2] = ps_default_low; 113 hc->speeds[3] = ps_default_high; 114 } else if (major == 3) { 115 hc->speeds[4] = ps_default_super; 116 } else { 117 return EINVAL; 118 } 119 120 usb_log_debug2("Implied speed of USB %u set up.", major); 121 } else { 122 for (unsigned i = 0; i < psic; i++) { 123 xhci_psi_t *psi = xhci_extcap_psi(ec, i); 124 unsigned sim = XHCI_REG_RD(psi, XHCI_PSI_PSIM); 125 unsigned psiv = XHCI_REG_RD(psi, XHCI_PSI_PSIV); 126 unsigned psie = XHCI_REG_RD(psi, XHCI_PSI_PSIE); 127 unsigned psim = XHCI_REG_RD(psi, XHCI_PSI_PSIM); 128 129 uint64_t bps = PSI_TO_BPS(psie, psim); 130 131 if (sim == XHCI_PSI_PLT_SYMM || sim == XHCI_PSI_PLT_RX) 132 hc->speeds[psiv].rx_bps = bps; 133 if (sim == XHCI_PSI_PLT_SYMM || sim == XHCI_PSI_PLT_TX) { 134 hc->speeds[psiv].tx_bps = bps; 135 usb_log_debug2("Speed %u set up for bps %" PRIu64 " / %" PRIu64 ".", psiv, hc->speeds[psiv].rx_bps, hc->speeds[psiv].tx_bps); 136 } 137 } 138 } 139 } 140 } 141 return EOK; 142 } 143 71 144 int hc_init_mmio(xhci_hc_t *hc, const hw_res_list_parsed_t *hw_res) 72 145 { … … 90 163 return err; 91 164 165 hc->base = base; 92 166 hc->cap_regs = (xhci_cap_regs_t *) base; 93 167 hc->op_regs = (xhci_op_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_LENGTH)); 94 168 hc->rt_regs = (xhci_rt_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF)); 95 169 hc->db_arry = (xhci_doorbell_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_DBOFF)); 170 171 uintptr_t xec_offset = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_XECP) * sizeof(xhci_dword_t); 172 if (xec_offset > 0) 173 hc->xecp = (xhci_extcap_t *) (base + xec_offset); 96 174 97 175 usb_log_debug2("Initialized MMIO reg areas:"); … … 105 183 hc->ac64 = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_AC64); 106 184 hc->max_slots = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_SLOTS); 185 186 if ((err = hc_parse_ec(hc))) { 187 pio_disable(hc->base, RNGSZ(hc->mmio_range)); 188 return err; 189 } 107 190 108 191 return EOK; … … 151 234 } 152 235 153 addr_range_t mmio_range = hw_res->mem_ranges.ranges[0];154 155 236 code->ranges = malloc(sizeof(irq_pio_range_t)); 156 237 if (code->ranges == NULL) … … 165 246 code->rangecount = 1; 166 247 code->ranges[0] = (irq_pio_range_t) { 167 .base = RNGABS( mmio_range),168 .size = RNGSZ( mmio_range),248 .base = RNGABS(hc->mmio_range), 249 .size = RNGSZ(hc->mmio_range), 169 250 }; 170 251 … … 172 253 memcpy(code->cmds, irq_commands, sizeof(irq_commands)); 173 254 174 void *intr0_iman = RNGABSPTR( mmio_range) + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF) + offsetof(xhci_rt_regs_t, ir[0]);255 void *intr0_iman = RNGABSPTR(hc->mmio_range) + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF) + offsetof(xhci_rt_regs_t, ir[0]); 175 256 code->cmds[0].addr = intr0_iman; 176 257 code->cmds[3].addr = intr0_iman; … … 182 263 int hc_claim(xhci_hc_t *hc, ddf_dev_t *dev) 183 264 { 184 // TODO: impl 185 return EOK; 265 /* No legacy support capability, the controller is solely for us */ 266 if (!hc->legsup) 267 return EOK; 268 269 /* 270 * TODO: Implement handoff from BIOS, section 4.22.1 271 * QEMU does not support this, so we have to test on real HW. 272 */ 273 return ENOTSUP; 186 274 } 187 275 … … 346 434 xhci_trb_ring_fini(&hc->command_ring); 347 435 xhci_event_ring_fini(&hc->event_ring); 436 pio_disable(hc->base, RNGSZ(hc->mmio_range)); 348 437 usb_log_info("HC(%p): Finalized.", hc); 349 438 } -
uspace/drv/bus/usb/xhci/hc.h
re4d7363 r91ca111 39 39 #include "trb_ring.h" 40 40 41 /** 42 * xHCI lets the controller define speeds of ports it controls. 43 */ 44 typedef struct xhci_port_speed { 45 uint64_t rx_bps, tx_bps; 46 } xhci_port_speed_t; 47 41 48 typedef struct xhci_hc { 49 /* MMIO range */ 50 addr_range_t mmio_range; 51 void *base; 52 53 /* Mapped register sets */ 42 54 xhci_cap_regs_t *cap_regs; 43 55 xhci_op_regs_t *op_regs; 44 56 xhci_rt_regs_t *rt_regs; 45 57 xhci_doorbell_t *db_arry; 58 xhci_extcap_t *xecp; /**< First extended capability */ 59 xhci_legsup_t *legsup; /**< Legacy support capability */ 46 60 47 addr_range_t mmio_range; 48 61 /* Structures in allocated memory */ 49 62 xhci_trb_ring_t command_ring; 50 63 xhci_event_ring_t event_ring; 51 52 64 xhci_device_ctx_t *dcbaa; 53 65 66 /* Cached capabilities */ 67 xhci_port_speed_t speeds [16]; 54 68 unsigned max_slots; 55 69 bool ac64; 56 57 70 } xhci_hc_t; 58 71 -
uspace/drv/bus/usb/xhci/hw_struct/regs.h
re4d7363 r91ca111 483 483 typedef ioport32_t xhci_doorbell_t; 484 484 485 enum xhci_plt { 486 XHCI_PSI_PLT_SYMM, 487 XHCI_PSI_PLT_RSVD, 488 XHCI_PSI_PLT_RX, 489 XHCI_PSI_PLT_TX 490 }; 491 492 /** 493 * Protocol speed ID: section 7.2.1 494 */ 495 typedef struct xhci_psi { 496 xhci_dword_t psi; 497 } xhci_psi_t; 498 499 #define XHCI_PSI_PSIV psi, 32, RANGE, 3, 0 500 #define XHCI_PSI_PSIE psi, 32, RANGE, 5, 4 501 #define XHCI_PSI_PLT psi, 32, RANGE, 7, 6 502 #define XHCI_PSI_PFD psi, 32, FLAG, 8 503 #define XHCI_PSI_PSIM psi, 32, RANGE, 31, 16 504 505 enum xhci_extcap_type { 506 XHCI_EC_RESERVED = 0, 507 XHCI_EC_USB_LEGACY, 508 XHCI_EC_SUPPORTED_PROTOCOL, 509 XHCI_EC_EXTENDED_POWER_MANAGEMENT, 510 XHCI_EC_IOV, 511 XHCI_EC_MSI, 512 XHCI_EC_LOCALMEM, 513 XHCI_EC_DEBUG = 10, 514 XHCI_EC_MSIX = 17, 515 XHCI_EC_MAX = 255 516 }; 517 518 /** 519 * xHCI Extended Capability: section 7 520 */ 521 typedef struct xhci_extcap { 522 xhci_dword_t header; 523 xhci_dword_t cap_specific[]; 524 } xhci_extcap_t; 525 526 #define XHCI_EC_CAP_ID header, 32, RANGE, 7, 0 527 #define XHCI_EC_SIZE header, 32, RANGE, 15, 8 528 529 /* Supported protocol */ 530 #define XHCI_EC_SP_MINOR header, 32, RANGE, 23, 16 531 #define XHCI_EC_SP_MAJOR header, 32, RANGE, 31, 24 532 #define XHCI_EC_SP_NAME cap_specific[0], 32, FIELD 533 #define XHCI_EC_SP_CP_OFF cap_specific[1], 32, RANGE, 7, 0 534 #define XHCI_EC_SP_CP_COUNT cap_specific[1], 32, RANGE, 15, 8 535 #define XHCI_EC_SP_PSIC cap_specific[1], 32, RANGE, 31, 28 536 #define XHCI_EC_SP_SLOT_TYPE cap_specific[2], 32, RANGE, 4, 0 537 538 typedef union { 539 char str [4]; 540 uint32_t packed; 541 } xhci_sp_name_t; 542 543 static inline xhci_extcap_t *xhci_extcap_next(const xhci_extcap_t *cur) 544 { 545 unsigned dword_offset = XHCI_REG_RD(cur, XHCI_EC_SIZE); 546 if (!dword_offset) 547 return NULL; 548 return (xhci_extcap_t *) (((xhci_dword_t *) cur) + dword_offset); 549 } 550 551 static inline xhci_psi_t *xhci_extcap_psi(const xhci_extcap_t *ec, unsigned psid) 552 { 553 assert(XHCI_REG_RD(ec, XHCI_EC_CAP_ID) == XHCI_EC_SUPPORTED_PROTOCOL); 554 assert(XHCI_REG_RD(ec, XHCI_EC_SP_PSIC) > psid); 555 556 unsigned dword_offset = 4 + psid; 557 return (xhci_psi_t *) (((xhci_dword_t *) ec) + dword_offset); 558 } 559 560 /** 561 * USB Legacy Support: section 7.1 562 * 563 * Legacy support have an exception from dword-access, because it needs to be 564 * byte-accessed. 565 */ 566 typedef struct xhci_extcap_legsup { 567 ioport8_t cap_id; 568 ioport8_t size; /**< Next Capability Pointer */ 569 ioport8_t sem_bios; 570 ioport8_t sem_os; 571 572 xhci_dword_t usblegctlsts; /**< USB Legacy Support Control/Status - RW for BIOS, RO for OS */ 573 } xhci_legsup_t; 574 575 #define XHCI_LEGSUP_SEM_BIOS sem_bios, 8, FLAG, 0 576 #define XHCI_LEGSUP_SEM_OS sem_os, 8, FLAG, 0 577 485 578 #endif 486 579 /** -
uspace/lib/usb/include/usb/usb.h
re4d7363 r91ca111 80 80 /** USB 2.0 high speed (480Mbits/s). */ 81 81 USB_SPEED_HIGH, 82 /** USB 3.0 super speed ( 480Mbits/s). */82 /** USB 3.0 super speed (5Gbits/s). */ 83 83 USB_SPEED_SUPER, 84 84 /** Psuedo-speed serving as a boundary. */
Note:
See TracChangeset
for help on using the changeset viewer.