Commit c40ec5a966eab19e75c98ee779145875d362b515

Authored by ths
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
... ... @@ -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;
... ...