qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Luca Tettamanti <kronos.it@gmail.com>
To: qemu-devel@nongnu.org
Cc: kvm-devel@lists.sourceforge.net, Luca Tettamanti <kronos.it@gmail.com>
Subject: [Qemu-devel] [PATCH] Add support for HPET periodic timer.
Date: Fri, 10 Aug 2007 22:32:22 +0200	[thread overview]
Message-ID: <11867779422209-git-send-email-kronos.it@gmail.com> (raw)

Linux operates the HPET timer in legacy replacement mode, which means that the
periodic interrupt of the CMOS RTC is not delivered (qemu won't be able to use
/dev/rtc). Add support for HPET (/dev/hpet) as a replacement for the RTC; the
periodic interrupt is delivered via SIGIO and is handled in the same way as the
RTC timer.
HPET must be explicitly enabled with -use-hpet.

Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
---
 qemu/vl.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/qemu/vl.c b/qemu/vl.c
index 4ad39f1..db7262b 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -54,6 +54,7 @@
 #include <pty.h>
 #include <malloc.h>
 #include <linux/rtc.h>
+#include <linux/hpet.h>
 #include <linux/ppdev.h>
 #endif
 #endif
@@ -996,8 +997,9 @@ static void host_alarm_handler(int host_signum)
 
 static int use_rtc = 1;
 static int rtc_fd;
+static int use_hpet;
 
-static int start_rtc_timer(void)
+static int enable_rtc(void)
 {
     rtc_fd = open("/dev/rtc", O_RDONLY);
     if (rtc_fd < 0)
@@ -1017,6 +1019,56 @@ static int start_rtc_timer(void)
     return 0;
 }
 
+static char default_hpet[] = "/dev/hpet";
+
+static int enable_hpet(void)
+{
+    struct hpet_info info;
+    int r;
+
+    rtc_fd = open(default_hpet, O_RDONLY);
+    if (rtc_fd < 0)
+        return -1;
+
+    /* Set frequency */
+    r = ioctl(rtc_fd, HPET_IRQFREQ, RTC_FREQ);
+    if (r < 0) {
+        fprintf(stderr, "Could not configure '/dev/hpet' to have a 1024 Hz 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(rtc_fd, HPET_INFO, &info);
+    if (r < 0)
+        goto fail;
+    
+    /* Enable periodic mode */
+    r = ioctl(rtc_fd, HPET_EPI, 0);
+    if (info.hi_flags && (r < 0))
+        goto fail;
+
+    /* Enable interrupt */
+    r = ioctl(rtc_fd, HPET_IE_ON, 0);
+    if (r < 0)
+        goto fail;
+
+    pit_min_timer_count = PIT_FREQ / RTC_FREQ;
+
+    return 0;
+fail:
+    close(rtc_fd);
+    return -1;
+}
+
+static int start_rtc_timer(void)
+{
+    if (use_hpet)
+        return enable_hpet();
+    else
+        return enable_rtc();
+}
 #else
 
 static int start_rtc_timer(void)
@@ -1090,7 +1142,7 @@ static void init_timer_alarm(void)
            2.6 kernels */
         if (itv.it_interval.tv_usec > 1000 || 1) {
             /* try to use /dev/rtc to have a faster timer */
-            if (!use_rtc || (start_rtc_timer() < 0))
+            if ((!use_rtc && !use_hpet) || (start_rtc_timer() < 0))
                 goto use_itimer;
             /* disable itimer */
             itv.it_interval.tv_sec = 0;
@@ -6482,6 +6534,7 @@ void help(void)
            "-tdf            inject timer interrupts that got lost\n"
 #if defined(__linux__)
            "-no-rtc         don't use /dev/rtc for timer alarm (do use gettimeofday)\n"
+           "-use-hpet       use /dev/hpet (HPET) instead of RTC for timer alarm\n"
 #endif
 	   "-option-rom rom load a file, rom, into the option ROM space\n"
            "\n"
@@ -6574,6 +6627,7 @@ enum {
     QEMU_OPTION_tdf,
 #if defined(__linux__)
     QEMU_OPTION_no_rtc,
+    QEMU_OPTION_use_hpet,
 #endif
     QEMU_OPTION_cpu_vendor,
 };
@@ -6671,6 +6725,7 @@ const QEMUOption qemu_options[] = {
     { "tdf", 0, QEMU_OPTION_tdf }, /* enable time drift fix */
 #if defined(__linux__)
     { "no-rtc", 0, QEMU_OPTION_no_rtc },
+    { "use-hpet", 0, QEMU_OPTION_use_hpet },
 #endif
     { "cpu-vendor", HAS_ARG, QEMU_OPTION_cpu_vendor },
     { NULL },
@@ -7395,6 +7450,9 @@ int main(int argc, char **argv)
 	    case QEMU_OPTION_no_rtc:
 		use_rtc = 0;
 		break;
+	    case QEMU_OPTION_use_hpet:
+		use_hpet = 1;
+		break;
 #endif
 	    case QEMU_OPTION_cpu_vendor:
 		cpu_vendor_string = optarg;
-- 
1.5.2.3

             reply	other threads:[~2007-08-10 20:32 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-10 20:32 Luca Tettamanti [this message]
2007-08-13  8:04 ` [Qemu-devel] Re: [kvm-devel] [PATCH] Add support for HPET periodic timer Avi Kivity
2007-08-13 11:50   ` Daniel P. Berrange
2007-08-13 17:03     ` Luca

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11867779422209-git-send-email-kronos.it@gmail.com \
    --to=kronos.it@gmail.com \
    --cc=kvm-devel@lists.sourceforge.net \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).