summary refs log tree commit diff stats
path: root/hw/mc146818rtc.c
diff options
context:
space:
mode:
authoraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-12-17 23:28:44 +0000
committeraliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162>2008-12-17 23:28:44 +0000
commit16b29ae1807b024bd5052301550f5d47dae958a2 (patch)
treeeeeb5072d4548b91f2111f3127737a374d89cab2 /hw/mc146818rtc.c
parent0bacd1300dbcd7f56bdbf1ca73438b6a68c31b8f (diff)
downloadfocaccia-qemu-16b29ae1807b024bd5052301550f5d47dae958a2.tar.gz
focaccia-qemu-16b29ae1807b024bd5052301550f5d47dae958a2.zip
Add HPET emulation to qemu (Beth Kon)
This patch adds HPET emulation.  It can be disabled with -disable-hpet.  An hpet
provides a more finely granular clocksource than otherwise available on PC.
This means that latency-dependent applications (e.g. multimedia) will generally
be smoother when using the HPET.

Signed-off-by: Beth Kon <eak@us.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>



git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6081 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/mc146818rtc.c')
-rw-r--r--hw/mc146818rtc.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index ac41a947b8..d25b52b4d3 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -26,6 +26,7 @@
 #include "sysemu.h"
 #include "pc.h"
 #include "isa.h"
+#include "hpet_emul.h"
 
 //#define DEBUG_CMOS
 
@@ -69,6 +70,18 @@ struct RTCState {
     QEMUTimer *second_timer2;
 };
 
+static void rtc_irq_raise(qemu_irq irq) {
+    /* When HPET is operating in legacy mode, RTC interrupts are disabled 
+     * We block qemu_irq_raise, but not qemu_irq_lower, in case legacy
+     * mode is established while interrupt is raised. We want it to 
+     * be lowered in any case
+     */ 
+#if defined TARGET_I386 || defined TARGET_X86_64
+    if (!hpet_in_legacy_mode()) 
+#endif
+        qemu_irq_raise(irq);
+}
+
 static void rtc_set_time(RTCState *s);
 static void rtc_copy_date(RTCState *s);
 
@@ -78,8 +91,14 @@ static void rtc_timer_update(RTCState *s, int64_t current_time)
     int64_t cur_clock, next_irq_clock;
 
     period_code = s->cmos_data[RTC_REG_A] & 0x0f;
-    if (period_code != 0 &&
-        (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
+#if defined TARGET_I386 || defined TARGET_X86_64
+    /* disable periodic timer if hpet is in legacy mode, since interrupts are 
+     * disabled anyway.
+     */
+    if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE) && !hpet_in_legacy_mode()) {
+#else
+    if (period_code != 0 && (s->cmos_data[RTC_REG_B] & REG_B_PIE)) {
+#endif
         if (period_code <= 2)
             period_code += 7;
         /* period in 32 Khz cycles */
@@ -100,7 +119,7 @@ static void rtc_periodic_timer(void *opaque)
 
     rtc_timer_update(s, s->next_periodic_time);
     s->cmos_data[RTC_REG_C] |= 0xc0;
-    qemu_irq_raise(s->irq);
+    rtc_irq_raise(s->irq);
 }
 
 static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
@@ -319,14 +338,14 @@ static void rtc_update_second2(void *opaque)
              s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
 
             s->cmos_data[RTC_REG_C] |= 0xa0;
-            qemu_irq_raise(s->irq);
+            rtc_irq_raise(s->irq);
         }
     }
 
     /* update ended interrupt */
     if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
         s->cmos_data[RTC_REG_C] |= 0x90;
-        qemu_irq_raise(s->irq);
+        rtc_irq_raise(s->irq);
     }
 
     /* clear update in progress bit */