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