diff options
author | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-17 23:28:44 +0000 |
---|---|---|
committer | aliguori <aliguori@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-17 23:28:44 +0000 |
commit | 16b29ae1807b024bd5052301550f5d47dae958a2 (patch) | |
tree | eeeb5072d4548b91f2111f3127737a374d89cab2 /hw/mc146818rtc.c | |
parent | 0bacd1300dbcd7f56bdbf1ca73438b6a68c31b8f (diff) |
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.c | 29 |
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 */ |