From c40ec5a966eab19e75c98ee779145875d362b515 Mon Sep 17 00:00:00 2001 From: ths Date: Sun, 19 Aug 2007 22:09:40 +0000 Subject: [PATCH] Add -clock option, by Luca Tettamanti. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3126 c046a42c-6fe2-441c-8c8c-71466251a162 --- vl.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/vl.c b/vl.c index ae05b8f6ad..686bc3b65b 100644 --- a/vl.c +++ b/vl.c @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #else @@ -809,6 +810,9 @@ static void unix_stop_timer(struct qemu_alarm_timer *t); #ifdef __linux__ +static int hpet_start_timer(struct qemu_alarm_timer *t); +static void hpet_stop_timer(struct qemu_alarm_timer *t); + static int rtc_start_timer(struct qemu_alarm_timer *t); static void rtc_stop_timer(struct qemu_alarm_timer *t); @@ -818,7 +822,9 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t); static struct qemu_alarm_timer alarm_timers[] = { #ifdef __linux__ - /* RTC - if available - is preferred */ + /* HPET - if available - is preferred */ + {"hpet", hpet_start_timer, hpet_stop_timer, NULL}, + /* ...otherwise try RTC */ {"rtc", rtc_start_timer, rtc_stop_timer, NULL}, #endif #ifndef _WIN32 @@ -1088,6 +1094,55 @@ static void enable_sigio_timer(int fd) fcntl(fd, F_SETOWN, getpid()); } +static int hpet_start_timer(struct qemu_alarm_timer *t) +{ + struct hpet_info info; + int r, fd; + + fd = open("/dev/hpet", O_RDONLY); + if (fd < 0) + return -1; + + /* Set frequency */ + r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ); + if (r < 0) { + fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n" + "error, but for better emulation accuracy type:\n" + "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n"); + goto fail; + } + + /* Check capabilities */ + r = ioctl(fd, HPET_INFO, &info); + if (r < 0) + goto fail; + + /* Enable periodic mode */ + r = ioctl(fd, HPET_EPI, 0); + if (info.hi_flags && (r < 0)) + goto fail; + + /* Enable interrupt */ + r = ioctl(fd, HPET_IE_ON, 0); + if (r < 0) + goto fail; + + enable_sigio_timer(fd); + t->priv = (void *)fd; + + return 0; +fail: + close(fd); + return -1; +} + +static void hpet_stop_timer(struct qemu_alarm_timer *t) +{ + int fd = (int)t->priv; + + close(fd); +} + static int rtc_start_timer(struct qemu_alarm_timer *t) { int rtc_fd;