All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luca Tettamanti <kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.org
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	Luca Tettamanti
	<kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Subject: [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-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
---
 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


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >>  http://get.splunk.com/

WARNING: multiple messages have this Message-ID (diff)
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: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-08-10 20:32 Luca Tettamanti [this message]
2007-08-10 20:32 ` [Qemu-devel] [PATCH] Add support for HPET periodic timer Luca Tettamanti
     [not found] ` <11867779422209-git-send-email-kronos.it-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2007-08-13  8:04   ` Avi Kivity
2007-08-13  8:04     ` [Qemu-devel] Re: [kvm-devel] " Avi Kivity
     [not found]     ` <46C0109E.3090800-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-08-13 11:50       ` Daniel P. Berrange
2007-08-13 11:50         ` [Qemu-devel] Re: [kvm-devel] " Daniel P. Berrange
     [not found]         ` <20070813115030.GB14348-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2007-08-13 17:03           ` Luca
2007-08-13 17:03             ` [Qemu-devel] Re: [kvm-devel] " 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-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=qemu-devel-qX2TKyscuCcdnm+yROfE0A@public.gmane.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.