socsvn commit: r254820 - soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb
syuu at FreeBSD.org
syuu at FreeBSD.org
Tue Jul 16 04:06:46 UTC 2013
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);
More information about the svn-soc-all
mailing list