qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Weil <weil@mail.berlios.de>
To: Anthony Liguori <aliguori@us.ibm.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	QEMU Developers <qemu-devel@nongnu.org>
Subject: [Qemu-devel] [PATCH 4/4] qemu-timer: Fix timers for w32
Date: Sun, 10 Apr 2011 20:28:43 +0200	[thread overview]
Message-ID: <1302460123-25704-5-git-send-email-weil@mail.berlios.de> (raw)
In-Reply-To: <1302460123-25704-1-git-send-email-weil@mail.berlios.de>

Commit 68c23e5520e8286d79d96ab47c0ea722ceb75041 removed the
multimedia timer, but this timer is needed for certain
Linux kernels. Otherwise Linux boot stops with this error:

    MP-BIOS bug: 8254 timer not connected to IO-APIC

So the multimedia timer is added again here.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
---
 qemu-timer.c |   96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/qemu-timer.c b/qemu-timer.c
index 26e5ea3..a57197b 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -209,6 +209,10 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t)
 
 #ifdef _WIN32
 
+static int mm_start_timer(struct qemu_alarm_timer *t);
+static void mm_stop_timer(struct qemu_alarm_timer *t);
+static void mm_rearm_timer(struct qemu_alarm_timer *t);
+
 static int win32_start_timer(struct qemu_alarm_timer *t);
 static void win32_stop_timer(struct qemu_alarm_timer *t);
 static void win32_rearm_timer(struct qemu_alarm_timer *t);
@@ -301,6 +305,8 @@ static struct qemu_alarm_timer alarm_timers[] = {
 #endif
     {"unix", unix_start_timer, unix_stop_timer, NULL},
 #else
+    {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
+    {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
     {"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
     {"win32", win32_start_timer, win32_stop_timer, NULL},
 #endif
@@ -949,6 +955,96 @@ static void unix_stop_timer(struct qemu_alarm_timer *t)
 
 #ifdef _WIN32
 
+static MMRESULT mm_timer;
+static unsigned mm_period;
+
+static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg,
+                                      DWORD_PTR dwUser, DWORD_PTR dw1,
+                                      DWORD_PTR dw2)
+{
+    struct qemu_alarm_timer *t = alarm_timer;
+    if (!t) {
+        return;
+    }
+    if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) {
+        t->expired = alarm_has_dynticks(t);
+        t->pending = 1;
+        qemu_notify_event();
+    }
+}
+
+static int mm_start_timer(struct qemu_alarm_timer *t)
+{
+    TIMECAPS tc;
+    UINT flags;
+
+    memset(&tc, 0, sizeof(tc));
+    timeGetDevCaps(&tc, sizeof(tc));
+
+    mm_period = tc.wPeriodMin;
+    timeBeginPeriod(mm_period);
+
+    flags = TIME_CALLBACK_FUNCTION;
+    if (alarm_has_dynticks(t)) {
+        flags |= TIME_ONESHOT;
+    } else {
+        flags |= TIME_PERIODIC;
+    }
+
+    mm_timer = timeSetEvent(1,                  /* interval (ms) */
+                            mm_period,          /* resolution */
+                            mm_alarm_handler,   /* function */
+                            (DWORD)t,           /* parameter */
+                            flags);
+
+    if (!mm_timer) {
+        fprintf(stderr, "Failed to initialize win32 alarm timer: %ld\n",
+                GetLastError());
+        timeEndPeriod(mm_period);
+        return -1;
+    }
+
+    return 0;
+}
+
+static void mm_stop_timer(struct qemu_alarm_timer *t)
+{
+    timeKillEvent(mm_timer);
+    timeEndPeriod(mm_period);
+}
+
+static void mm_rearm_timer(struct qemu_alarm_timer *t)
+{
+    int nearest_delta_ms;
+
+    assert(alarm_has_dynticks(t));
+    if (!active_timers[QEMU_CLOCK_REALTIME] &&
+        !active_timers[QEMU_CLOCK_VIRTUAL] &&
+        !active_timers[QEMU_CLOCK_HOST]) {
+        return;
+    }
+
+    timeKillEvent(mm_timer);
+
+    nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000;
+    if (nearest_delta_ms < 1) {
+        nearest_delta_ms = 1;
+    }
+    mm_timer = timeSetEvent(nearest_delta_ms,
+                            mm_period,
+                            mm_alarm_handler,
+                            (DWORD)t,
+                            TIME_ONESHOT | TIME_CALLBACK_FUNCTION);
+
+    if (!mm_timer) {
+        fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n",
+                GetLastError());
+
+        timeEndPeriod(mm_period);
+        exit(1);
+    }
+}
+
 static int win32_start_timer(struct qemu_alarm_timer *t)
 {
     HANDLE hTimer;
-- 
1.7.2.5

  parent reply	other threads:[~2011-04-10 18:29 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-10 18:28 [Qemu-devel] qemu-timer: Clean code and re-add multimedia timers for windows Stefan Weil
2011-04-10 18:28 ` [Qemu-devel] [PATCH 1/4] qemu-timer: Add and use new function qemu_timer_expired_ns Stefan Weil
2011-04-20 14:26   ` [Qemu-devel] [PULL] qemu-timer: Add and use new function qemu_timer_expired_ns and other patches Stefan Weil
2011-04-28 12:18     ` Stefan Weil
2011-04-29 21:09       ` Blue Swirl
2011-04-10 18:28 ` [Qemu-devel] [PATCH 2/4] qemu-timer: Remove unneeded include statement (w32) Stefan Weil
2011-04-10 18:28 ` [Qemu-devel] [PATCH 3/4] qemu-timer: Avoid type casts Stefan Weil
2011-04-10 18:28 ` Stefan Weil [this message]
2011-04-11  7:36   ` [Qemu-devel] Re: [PATCH 4/4] qemu-timer: Fix timers for w32 Paolo Bonzini
2011-04-11 17:21     ` [Qemu-devel] " Stefan Weil
2011-04-12 12:36       ` Jan Kiszka
2011-04-12 12:40         ` Paolo Bonzini
2011-04-12 12:59           ` Jan Kiszka

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=1302460123-25704-5-git-send-email-weil@mail.berlios.de \
    --to=weil@mail.berlios.de \
    --cc=aliguori@us.ibm.com \
    --cc=pbonzini@redhat.com \
    --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).