socsvn commit: r254843 - in soc2013/syuu/bhyve_usb/usr.sbin/bhyve: . usb

syuu at FreeBSD.org syuu at FreeBSD.org
Tue Jul 16 13:56:17 UTC 2013


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 <pthread.h>
 #include <pthread_np.h>
 #include <string.h>
+#include <time.h>
+#include <signal.h>
 
 #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);


More information about the svn-soc-all mailing list