Date: Tue, 16 Jul 2013 04:06:45 GMT From: syuu@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r254820 - soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb Message-ID: <201307160406.r6G46jCt033290@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: syuu Date: Tue Jul 16 04:06:45 2013 New Revision: 254820 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254820 Log: pci_uhci_softc, debuglog output to /tmp/bhyveusb.log, use legacy intr instead of msi, usb rev version fix, uhci_reset segv fix, readable read/write debug message Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c ============================================================================== --- soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c Tue Jul 16 03:12:31 2013 (r254819) +++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c Tue Jul 16 04:06:45 2013 (r254820) @@ -43,14 +43,6 @@ #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82801I_UHCI6 0x2939 -/* - * Per-device softc - */ -struct pci_uhci_softc { - struct pci_devinst *sc_pi; - pthread_mutex_t sc_mtx; -}; - struct PCIDevice { uint8_t *config; }; @@ -62,93 +54,95 @@ typedef struct PCIDeviceClass PCIDeviceClass; typedef struct MemoryRegion MemoryRegion; +FILE *usblog; + #define trace_usb_uhci_queue_add(token) \ - fprintf(stderr, "%s:%d trace_usb_uhci_queue_add token=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_queue_add token=%x\n", \ __func__, __LINE__, token) #define trace_usb_uhci_queue_del(token, reason) \ - fprintf(stderr, "%s:%d trace_usb_uhci_queue_del token=%x reason=%s\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_queue_del token=%x reason=%s\n", \ __func__, __LINE__, token, reason) #define trace_usb_uhci_packet_add(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_add token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_add token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_packet_del(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_del token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_del token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_packet_cancel(token, td_addr, done) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_cancel token=%x td_addr=%x done=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_cancel token=%x td_addr=%x done=%x\n", \ __func__, __LINE__, token, td_addr, done) #define trace_usb_uhci_packet_link_async(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_link_async token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_link_async token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_packet_unlink_async(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_unlink_async token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_unlink_async token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_reset() \ - fprintf(stderr, "%s:%d trace_usb_uhci_reset\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_reset\n", \ __func__, __LINE__) #define trace_usb_uhci_mmio_writew(addr, val) \ - fprintf(stderr, "%s:%d trace_usb_uhci_mmio_writew addr=%lx val=%lx\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_mmio_writew addr=%lx val=%lx\n", \ __func__, __LINE__, addr, val) #define trace_usb_uhci_mmio_readw(addr, val) \ - fprintf(stderr, "%s:%d trace_usb_uhci_mmio_readw addr=%lx val=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_mmio_readw addr=%lx val=%x\n", \ __func__, __LINE__, addr, val) #define trace_usb_uhci_schedule_start() \ - fprintf(stderr, "%s:%d trace_usb_uhci_schedule_start\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_schedule_start\n", \ __func__, __LINE__) #define trace_usb_uhci_packet_complete_stall(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_stall token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_stall token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_packet_complete_babble(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_babble token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_babble token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_packet_complete_error(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_error token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_error token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_packet_complete_shortxfer(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_shortxfer token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_shortxfer token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_packet_complete_success(token, td_addr) \ - fprintf(stderr, "%s:%d trace_usb_uhci_packet_complete_success token=%x td_addr=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_packet_complete_success token=%x td_addr=%x\n", \ __func__, __LINE__, token, td_addr) #define trace_usb_uhci_td_queue(link, ctrl, token) \ - fprintf(stderr, "%s:%d trace_usb_uhci_td_queue link=%x ctrl=%x token=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_td_queue link=%x ctrl=%x token=%x\n", \ __func__, __LINE__, link, ctrl, token) #define trace_usb_uhci_frame_stop_bandwidth() \ - fprintf(stderr, "%s:%d trace_usb_uhci_frame_stop_bandwidth\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_frame_stop_bandwidth\n", \ __func__, __LINE__) #define trace_usb_uhci_qh_load(link) \ - fprintf(stderr, "%s:%d trace_usb_uhci_qh_load link=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_qh_load link=%x\n", \ __func__, __LINE__, link) #define trace_usb_uhci_frame_loop_stop_idle() \ - fprintf(stderr, "%s:%d trace_usb_uhci_frame_loop_stop_idle\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_frame_loop_stop_idle\n", \ __func__, __LINE__) #define trace_usb_uhci_frame_loop_continue() \ - fprintf(stderr, "%s:%d trace_usb_uhci_frame_loop_continue\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_frame_loop_continue\n", \ __func__, __LINE__) #define trace_usb_uhci_td_load(qh, link, ctrl, token) \ - fprintf(stderr, "%s:%d trace_usb_uhci_td_load qh=%x link=%x ctrl=%x token=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_td_load qh=%x link=%x ctrl=%x token=%x\n", \ __func__, __LINE__, qh, link, ctrl, token) #define trace_usb_uhci_td_nextqh(qh, link) \ - fprintf(stderr, "%s:%d trace_usb_uhci_td_nextqh qh=%x link=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_td_nextqh qh=%x link=%x\n", \ __func__, __LINE__, qh, link) #define trace_usb_uhci_td_async(qh, link) \ - fprintf(stderr, "%s:%d trace_usb_uhci_td_async qh=%x link=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_td_async qh=%x link=%x\n", \ __func__, __LINE__, qh, link) #define trace_usb_uhci_td_complete(qh, link) \ - fprintf(stderr, "%s:%d trace_usb_uhci_td_complete qh=%x link=%x\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_td_complete qh=%x link=%x\n", \ __func__, __LINE__, qh, link) #define trace_usb_uhci_schedule_stop() \ - fprintf(stderr, "%s:%d trace_usb_uhci_schedule_stop\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_schedule_stop\n", \ __func__, __LINE__) #define trace_usb_uhci_frame_start(num) \ - fprintf(stderr, "%s:%d trace_usb_uhci_frame_start num=%d\n", \ + fprintf(usblog, "%s:%d trace_usb_uhci_frame_start num=%d\n", \ __func__, __LINE__, num) //#define DEBUG //#define DEBUG_DUMP_DATA #define PCI_USBREV 0x60 /* USB protocol revision */ -#define PCI_USB_REV_1_1 0x11 +#define PCI_USB_REV_1_0 0x10 #define UHCI_CMD_FGR (1 << 4) #define UHCI_CMD_EGSM (1 << 3) @@ -257,6 +251,7 @@ } UHCIPort; struct UHCIState { + struct pci_uhci_softc *sc; PCIDevice dev; MemoryRegion io_bar; USBBus bus; /* Note unused when we're a companion controller */ @@ -301,8 +296,18 @@ uint32_t el_link; } UHCI_QH; +/* + * Per-device softc + */ +struct pci_uhci_softc { + struct pci_devinst *sc_pi; + struct UHCIState sc_st; + pthread_mutex_t sc_mtx; +}; + static void uhci_async_cancel(UHCIAsync *async); static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td); +static void uhci_process_frame(UHCIState *s); static inline int32_t uhci_queue_token(UHCI_TD *td) { @@ -341,7 +346,7 @@ async = QTAILQ_FIRST(&queue->asyncs); uhci_async_cancel(async); } - usb_device_ep_stopped(queue->ep->dev, queue->ep); +// usb_device_ep_stopped(queue->ep->dev, queue->ep); trace_usb_uhci_queue_del(queue->token, reason); QTAILQ_REMOVE(&s->queues, queue, next); @@ -494,21 +499,23 @@ level = 0; } // qemu_set_irq(s->dev.irq[s->irq_pin], level); + if (level) + pci_lintr_assert(s->sc->sc_pi); + else + pci_lintr_deassert(s->sc->sc_pi); } static void uhci_reset(void *opaque) { UHCIState *s = opaque; - uint8_t *pci_conf; int i; UHCIPort *port; + struct pci_uhci_softc *sc = s->sc; trace_usb_uhci_reset(); - pci_conf = s->dev.config; - - pci_conf[0x6a] = 0x01; /* usb clock */ - pci_conf[0x6b] = 0x00; + pci_set_cfgdata8(sc->sc_pi, 0x6a, 0x01); /* XXX: use macro */ + pci_set_cfgdata8(sc->sc_pi, 0x6b, 0x00); s->cmd = 0; s->status = 0; s->status2 = 0; @@ -587,10 +594,11 @@ { UHCIState *s = opaque; - trace_usb_uhci_mmio_writew(addr, val); +// trace_usb_uhci_mmio_writew(addr, val); switch(addr) { case 0x00: + fprintf(usblog, "%s USBCMD val:%lx\n", __func__, val); if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) { /* start frame processing */ trace_usb_uhci_schedule_start(); @@ -620,6 +628,7 @@ s->cmd = val; break; case 0x02: + fprintf(usblog, "%s USBSTS val:%lx\n", __func__, val); s->status &= ~val; /* XXX: the chip spec is not coherent, so we add a hidden register to distinguish between IOC and SPD */ @@ -628,22 +637,27 @@ uhci_update_irq(s); break; case 0x04: + fprintf(usblog, "%s USBINTR val:%lx\n", __func__, val); s->intr = val; uhci_update_irq(s); break; case 0x06: + fprintf(usblog, "%s FRNUM val:%lx\n", __func__, val); if (s->status & UHCI_STS_HCHALTED) s->frnum = val & 0x7ff; break; case 0x08: + fprintf(usblog, "%s FRBASEADD(lo) val:%lx\n", __func__, val); s->fl_base_addr &= 0xffff0000; s->fl_base_addr |= val & ~0xfff; break; case 0x0a: + fprintf(usblog, "%s FRBASEADD(hi) val:%lx\n", __func__, val); s->fl_base_addr &= 0x0000ffff; s->fl_base_addr |= (val << 16); break; case 0x0c: + fprintf(usblog, "%s SOFMOD val:%lx\n", __func__, val); s->sof_timing = val & 0xff; break; case 0x10 ... 0x1f: @@ -653,6 +667,7 @@ int n; n = (addr >> 1) & 7; + fprintf(usblog, "%s PORTSC%d val:%lx\n", __func__, n, val); if (n >= NB_PORTS) return; port = &s->ports[n]; @@ -685,24 +700,31 @@ switch(addr) { case 0x00: val = s->cmd; + fprintf(usblog, "%s USBCMD val:%x\n", __func__, val); break; case 0x02: val = s->status; + fprintf(usblog, "%s USBSTS val:%x\n", __func__, val); break; case 0x04: val = s->intr; + fprintf(usblog, "%s USBINTR val:%x\n", __func__, val); break; case 0x06: val = s->frnum; + fprintf(usblog, "%s FRNUM val:%x\n", __func__, val); break; case 0x08: val = s->fl_base_addr & 0xffff; + fprintf(usblog, "%s FRBASEADD(lo) val:%x\n", __func__, val); break; case 0x0a: val = (s->fl_base_addr >> 16) & 0xffff; + fprintf(usblog, "%s FRBASEADD(hi) val:%x\n", __func__, val); break; case 0x0c: val = s->sof_timing; + fprintf(usblog, "%s SOFMOD val:%x\n", __func__, val); break; case 0x10 ... 0x1f: { @@ -713,6 +735,7 @@ goto read_default; port = &s->ports[n]; val = port->ctrl; + fprintf(usblog, "%s PORTSC%d val:%x\n", __func__, n, val); } break; default: @@ -721,7 +744,7 @@ break; } - trace_usb_uhci_mmio_readw(addr, val); +// trace_usb_uhci_mmio_readw(addr, val); return val; } @@ -1060,6 +1083,7 @@ /* Force processing of this packet *now*, needed for migration */ s->completions_only = true; // qemu_bh_schedule(s->bh); + uhci_process_frame(s); } static int is_valid(uint32_t link) @@ -1542,7 +1566,7 @@ struct pci_uhci_softc *sc = pi->pi_arg; pthread_mutex_lock(&sc->sc_mtx); - printf("%s baridx:%d offset:%lx size:%d value:%lx\n", __func__, baridx, offset, size, value); + uhci_port_write(&sc->sc_st, offset, value, size); pthread_mutex_unlock(&sc->sc_mtx); } @@ -1555,7 +1579,7 @@ uint64_t value; pthread_mutex_lock(&sc->sc_mtx); - printf("%s baridx:%d offset:%lx size:%d\n", __func__, baridx, offset, size); + value = uhci_port_read(&sc->sc_st, offset, size); pthread_mutex_unlock(&sc->sc_mtx); return (value); @@ -1566,8 +1590,13 @@ { struct pci_uhci_softc *sc; + usblog = fopen("/tmp/bhyveusb.log", "w"); + if (!usblog) { + perror("fopen"); + exit(1); + } sc = malloc(sizeof(struct pci_uhci_softc)); - memset(sc, 0, sizeof(struct pci_uhci_softc)); + memset(sc, 0, sizeof(*sc)); pi->pi_arg = sc; sc->sc_pi = pi; @@ -1578,10 +1607,19 @@ pci_set_cfgdata16(pi, PCIR_DEVICE, PCI_DEVICE_ID_INTEL_82801I_UHCI6); pci_set_cfgdata16(pi, PCIR_VENDOR, PCI_VENDOR_ID_INTEL); pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_SERIALBUS); - pci_set_cfgdata8(pi, PCI_USBREV, PCI_USB_REV_1_1); - - /* MSI support */ - pci_emul_add_msicap(pi, 1); + pci_set_cfgdata8(pi, PCI_USBREV, PCI_USB_REV_1_0); + + if (!pci_is_legacy(pi)) { + fprintf(stderr, "hcd-uhci works only in legacy mode\n"); + } else { + pci_lintr_request(pi, 9); + } + + memset(&sc->sc_st, 0, sizeof(sc->sc_st)); + sc->sc_st.num_ports_vmstate = NB_PORTS; + QTAILQ_INIT(&sc->sc_st.queues); + sc->sc_st.sc = sc; + uhci_reset(&sc->sc_st); pci_emul_alloc_bar(pi, 4, PCIBAR_IO, 0x20);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201307160406.r6G46jCt033290>