From owner-svn-soc-all@FreeBSD.ORG Tue Jul 16 13:56:17 2013 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id C91D322D for ; Tue, 16 Jul 2013 13:56:17 +0000 (UTC) (envelope-from syuu@FreeBSD.org) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) by mx1.freebsd.org (Postfix) with ESMTP id BA496875 for ; Tue, 16 Jul 2013 13:56:17 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.7/8.14.7) with ESMTP id r6GDuHNl019663 for ; Tue, 16 Jul 2013 13:56:17 GMT (envelope-from syuu@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.7/8.14.6/Submit) id r6GDuHId019660 for svn-soc-all@FreeBSD.org; Tue, 16 Jul 2013 13:56:17 GMT (envelope-from syuu@FreeBSD.org) Date: Tue, 16 Jul 2013 13:56:17 GMT Message-Id: <201307161356.r6GDuHId019660@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to syuu@FreeBSD.org using -f From: syuu@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r254843 - in soc2013/syuu/bhyve_usb/usr.sbin/bhyve: . usb MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Jul 2013 13:56:17 -0000 Author: syuu Date: Tue Jul 16 13:56:17 2013 New Revision: 254843 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=254843 Log: timer function implemented Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/Makefile soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c Modified: soc2013/syuu/bhyve_usb/usr.sbin/bhyve/Makefile ============================================================================== --- soc2013/syuu/bhyve_usb/usr.sbin/bhyve/Makefile Tue Jul 16 12:22:36 2013 (r254842) +++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/Makefile Tue Jul 16 13:56:17 2013 (r254843) @@ -16,13 +16,13 @@ SRCS+= vmm_instruction_emul.c .PATH: ${.CURDIR}/usb -CFLAGS+=-I${.CURDIR}/usb/include -I${.CURDIR} +CFLAGS+=-I${.CURDIR}/usb/include -I${.CURDIR} SRCS+= core.c hcd-uhci.c NO_MAN= DPADD= ${LIBVMMAPI} ${LIBMD} ${LIBPTHREAD} -LDADD= -lvmmapi -lmd -lpthread +LDADD= -lvmmapi -lmd -lpthread -lrt WARNS?= 2 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 12:22:36 2013 (r254842) +++ soc2013/syuu/bhyve_usb/usr.sbin/bhyve/usb/hcd-uhci.c Tue Jul 16 13:56:17 2013 (r254843) @@ -31,6 +31,8 @@ #include #include #include +#include +#include #include "pci_emul.h" #include "hw/usb.h" @@ -250,6 +252,14 @@ uint16_t ctrl; } UHCIPort; +typedef void(*timer_func_t)(void*); +typedef struct Timer { + timer_t timerid; + struct sigevent se; + timer_func_t func; + void *arg; +} Timer; + struct UHCIState { struct pci_uhci_softc *sc; PCIDevice dev; @@ -263,7 +273,7 @@ uint8_t sof_timing; uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ int64_t expire_time; -// QEMUTimer *frame_timer; + Timer *frame_timer; // QEMUBH *bh; uint32_t frame_bytes; uint32_t frame_bandwidth; @@ -309,6 +319,77 @@ static void uhci_queue_fill(UHCIQueue *q, UHCI_TD *td); static void uhci_process_frame(UHCIState *s); +#define SECINNS (1000000000L) + +static int64_t timespec_to_ns(struct timespec *ts) +{ + return ((int64_t)(ts->tv_sec * SECINNS) + ts->tv_nsec); +} + +static struct timespec ns_to_timerspec(int64_t ns) +{ + struct timespec ts; + ts.tv_sec = ns / SECINNS; + ts.tv_nsec = ns % SECINNS; + return ts; +} + +static int64_t get_clock_ns(void) +{ + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts)) { + perror("clock_gettime"); + exit(1); + } + return timespec_to_ns(&ts); +} + +static int64_t get_ticks_per_sec(void) +{ + return (1000000000L); +} + +void timer_handler(union sigval sigv) +{ + Timer *timer = (Timer *)sigv.sigval_ptr; + timer->func(timer->arg); +} + +static Timer *new_timer(timer_func_t func, void *arg) +{ + Timer *timer = (Timer *)calloc(1, sizeof(*timer)); + if (!timer) { + perror("calloc"); + exit(1); + } + timer->se.sigev_notify = SIGEV_THREAD; + timer->se.sigev_value.sigval_ptr = (Timer *)timer; + timer->se.sigev_notify_function = timer_handler; + timer->func = func; + timer->arg = arg; + if (timer_create(CLOCK_REALTIME, &timer->se, &timer->timerid)) { + perror("timer_create"); + exit(1); + } + return timer; +} + +static void mod_timer(Timer *timer, int64_t ns) +{ + struct itimerspec its; + + its.it_value = its.it_interval = ns_to_timerspec(ns); + timer_settime(timer->timerid, 0, &its, 0); +} + +static void del_timer(Timer *timer) +{ + struct itimerspec its; + + memset(&its, 0, sizeof(its)); + timer_settime(timer->timerid, 0, &its, 0); +} + static inline int32_t uhci_queue_token(UHCI_TD *td) { if ((td->token & (0xf << 15)) == 0) { @@ -498,7 +579,6 @@ } else { level = 0; } -// qemu_set_irq(s->dev.irq[s->irq_pin], level); if (level) pci_lintr_assert(s->sc->sc_pi); else @@ -518,6 +598,7 @@ pci_set_cfgdata8(sc->sc_pi, 0x6b, 0x00); s->cmd = 0; s->status = 0; + fprintf(usblog, "%s s->status = 0\n", __func__); s->status2 = 0; s->intr = 0; s->fl_base_addr = 0; @@ -551,14 +632,12 @@ static int uhci_post_load(void *opaque, int version_id) { -#if 0 UHCIState *s = opaque; if (version_id < 2) { - s->expire_time = qemu_get_clock_ns(vm_clock) + + s->expire_time = get_clock_ns() + (get_ticks_per_sec() / FRAME_TIMER_FREQ); } -#endif return 0; } @@ -602,12 +681,16 @@ if ((val & UHCI_CMD_RS) && !(s->cmd & UHCI_CMD_RS)) { /* start frame processing */ trace_usb_uhci_schedule_start(); -// s->expire_time = qemu_get_clock_ns(vm_clock) + -// (get_ticks_per_sec() / FRAME_TIMER_FREQ); -// qemu_mod_timer(s->frame_timer, s->expire_time); + s->expire_time = get_clock_ns() + + (get_ticks_per_sec() / FRAME_TIMER_FREQ); + mod_timer(s->frame_timer, s->expire_time); s->status &= ~UHCI_STS_HCHALTED; + fprintf(usblog, "%s status &= ~UHCI_STS_HCHALTED\n", __func__); + fprintf(usblog, "%s status = %x\n", __func__, s->status); } else if (!(val & UHCI_CMD_RS)) { s->status |= UHCI_STS_HCHALTED; + fprintf(usblog, "%s status |= UHCI_STS_HCHALTED\n", __func__); + fprintf(usblog, "%s status = %x\n", __func__, s->status); } if (val & UHCI_CMD_GRESET) { UHCIPort *port; @@ -618,10 +701,12 @@ port = &s->ports[i]; usb_device_reset(port->port.dev); } + fprintf(usblog, "%s:%d\n", __func__, __LINE__); uhci_reset(s); return; } if (val & UHCI_CMD_HCRESET) { + fprintf(usblog, "%s:%d\n", __func__, __LINE__); uhci_reset(s); return; } @@ -630,6 +715,8 @@ case 0x02: fprintf(usblog, "%s USBSTS val:%lx\n", __func__, val); s->status &= ~val; + fprintf(usblog, "%s s->status &= ~%lx\n", __func__, val); + fprintf(usblog, "%s s->status = %x\n", __func__, s->status); /* XXX: the chip spec is not coherent, so we add a hidden register to distinguish between IOC and SPD */ if (val & UHCI_STS_USBINT) @@ -760,6 +847,8 @@ if (s->cmd & UHCI_CMD_EGSM) { s->cmd |= UHCI_CMD_FGR; s->status |= UHCI_STS_RD; + fprintf(usblog, "%s s->status |= UHCI_STS_RD\n", __func__); + fprintf(usblog, "%s s->status = %x\n", __func__, s->status); uhci_update_irq(s); } } @@ -884,6 +973,8 @@ td->ctrl &= ~TD_CTRL_ACTIVE; s->status |= UHCI_STS_USBERR; + fprintf(usblog, "%s s->status |= UHCI_STS_USBERR\n", __func__); + fprintf(usblog, "%s s->status = %x\n", __func__, s->status); if (td->ctrl & TD_CTRL_IOC) { *int_mask |= 0x01; } @@ -1051,6 +1142,8 @@ /* invalid pid : frame interrupted */ uhci_async_free(async); s->status |= UHCI_STS_HCPERR; + fprintf(usblog, "%s s->status |= UHCI_STS_USBERR\n", __func__); + fprintf(usblog, "%s s->status = %x\n", __func__, s->status); uhci_update_irq(s); return TD_RESULT_STOP_FRAME; } @@ -1152,7 +1245,7 @@ assert(int_mask == 0); plink = ptd.link; } - usb_device_flush_ep_queue(q->ep->dev, q->ep); +// usb_device_flush_ep_queue(q->ep->dev, q->ep); } static void uhci_process_frame(UHCIState *s) @@ -1289,7 +1382,7 @@ UHCIState *s = opaque; uint64_t t_now, t_last_run; int i, frames; - const uint64_t frame_t /* = get_ticks_per_sec() / FRAME_TIMER_FREQ */; + const uint64_t frame_t = get_ticks_per_sec() / FRAME_TIMER_FREQ; s->completions_only = false; // qemu_bh_cancel(s->bh); @@ -1297,16 +1390,18 @@ if (!(s->cmd & UHCI_CMD_RS)) { /* Full stop */ trace_usb_uhci_schedule_stop(); -// qemu_del_timer(s->frame_timer); + del_timer(s->frame_timer); uhci_async_cancel_all(s); /* set hchalted bit in status - UHCI11D 2.1.2 */ s->status |= UHCI_STS_HCHALTED; + fprintf(usblog, "%s s->status |= UHCI_STS_HCHALTED\n", __func__); + fprintf(usblog, "%s s->status = %x\n", __func__, s->status); return; } /* We still store expire_time in our state, for migration */ t_last_run = s->expire_time - frame_t; -// t_now = qemu_get_clock_ns(vm_clock); + t_now = get_clock_ns(); /* Process up to MAX_FRAMES_PER_TICK frames */ frames = (t_now - t_last_run) / frame_t; @@ -1336,11 +1431,13 @@ if (s->pending_int_mask) { s->status2 |= s->pending_int_mask; s->status |= UHCI_STS_USBINT; + fprintf(usblog, "%s s->status |= UHCI_STS_USBINT\n", __func__); + fprintf(usblog, "%s s->status = %x\n", __func__, s->status); uhci_update_irq(s); } s->pending_int_mask = 0; -// qemu_mod_timer(s->frame_timer, t_now + frame_t); + mod_timer(s->frame_timer, t_now + frame_t); } /* @@ -1616,9 +1713,11 @@ } memset(&sc->sc_st, 0, sizeof(sc->sc_st)); + sc->sc_st.frame_timer = new_timer(uhci_frame_timer, &sc->sc_st); sc->sc_st.num_ports_vmstate = NB_PORTS; QTAILQ_INIT(&sc->sc_st.queues); sc->sc_st.sc = sc; + fprintf(usblog, "%s:%d\n", __func__, __LINE__); uhci_reset(&sc->sc_st); pci_emul_alloc_bar(pi, 4, PCIBAR_IO, 0x20);