Commit c40ec5a966eab19e75c98ee779145875d362b515
1 parent
c8994013
Add -clock option, by Luca Tettamanti.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3126 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
56 additions
and
1 deletions
vl.c
... | ... | @@ -56,6 +56,7 @@ |
56 | 56 | #include <pty.h> |
57 | 57 | #include <malloc.h> |
58 | 58 | #include <linux/rtc.h> |
59 | +#include <linux/hpet.h> | |
59 | 60 | #include <linux/ppdev.h> |
60 | 61 | #include <linux/parport.h> |
61 | 62 | #else |
... | ... | @@ -809,6 +810,9 @@ static void unix_stop_timer(struct qemu_alarm_timer *t); |
809 | 810 | |
810 | 811 | #ifdef __linux__ |
811 | 812 | |
813 | +static int hpet_start_timer(struct qemu_alarm_timer *t); | |
814 | +static void hpet_stop_timer(struct qemu_alarm_timer *t); | |
815 | + | |
812 | 816 | static int rtc_start_timer(struct qemu_alarm_timer *t); |
813 | 817 | static void rtc_stop_timer(struct qemu_alarm_timer *t); |
814 | 818 | |
... | ... | @@ -818,7 +822,9 @@ static void rtc_stop_timer(struct qemu_alarm_timer *t); |
818 | 822 | |
819 | 823 | static struct qemu_alarm_timer alarm_timers[] = { |
820 | 824 | #ifdef __linux__ |
821 | - /* RTC - if available - is preferred */ | |
825 | + /* HPET - if available - is preferred */ | |
826 | + {"hpet", hpet_start_timer, hpet_stop_timer, NULL}, | |
827 | + /* ...otherwise try RTC */ | |
822 | 828 | {"rtc", rtc_start_timer, rtc_stop_timer, NULL}, |
823 | 829 | #endif |
824 | 830 | #ifndef _WIN32 |
... | ... | @@ -1088,6 +1094,55 @@ static void enable_sigio_timer(int fd) |
1088 | 1094 | fcntl(fd, F_SETOWN, getpid()); |
1089 | 1095 | } |
1090 | 1096 | |
1097 | +static int hpet_start_timer(struct qemu_alarm_timer *t) | |
1098 | +{ | |
1099 | + struct hpet_info info; | |
1100 | + int r, fd; | |
1101 | + | |
1102 | + fd = open("/dev/hpet", O_RDONLY); | |
1103 | + if (fd < 0) | |
1104 | + return -1; | |
1105 | + | |
1106 | + /* Set frequency */ | |
1107 | + r = ioctl(fd, HPET_IRQFREQ, RTC_FREQ); | |
1108 | + if (r < 0) { | |
1109 | + fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024Hz timer. This is not a fatal\n" | |
1110 | + "error, but for better emulation accuracy type:\n" | |
1111 | + "'echo 1024 > /proc/sys/dev/hpet/max-user-freq' as root.\n"); | |
1112 | + goto fail; | |
1113 | + } | |
1114 | + | |
1115 | + /* Check capabilities */ | |
1116 | + r = ioctl(fd, HPET_INFO, &info); | |
1117 | + if (r < 0) | |
1118 | + goto fail; | |
1119 | + | |
1120 | + /* Enable periodic mode */ | |
1121 | + r = ioctl(fd, HPET_EPI, 0); | |
1122 | + if (info.hi_flags && (r < 0)) | |
1123 | + goto fail; | |
1124 | + | |
1125 | + /* Enable interrupt */ | |
1126 | + r = ioctl(fd, HPET_IE_ON, 0); | |
1127 | + if (r < 0) | |
1128 | + goto fail; | |
1129 | + | |
1130 | + enable_sigio_timer(fd); | |
1131 | + t->priv = (void *)fd; | |
1132 | + | |
1133 | + return 0; | |
1134 | +fail: | |
1135 | + close(fd); | |
1136 | + return -1; | |
1137 | +} | |
1138 | + | |
1139 | +static void hpet_stop_timer(struct qemu_alarm_timer *t) | |
1140 | +{ | |
1141 | + int fd = (int)t->priv; | |
1142 | + | |
1143 | + close(fd); | |
1144 | +} | |
1145 | + | |
1091 | 1146 | static int rtc_start_timer(struct qemu_alarm_timer *t) |
1092 | 1147 | { |
1093 | 1148 | int rtc_fd; | ... | ... |