diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2011-06-20 14:06:28 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2011-07-23 11:26:12 -0500 |
commit | 17604dac28b2410c021a4a52dcfa58e8803dfb24 (patch) | |
tree | 27d05f93470ccb7df50d02098d98e826238c01b0 /hw/mc146818rtc.c | |
parent | 691a0c9c9b71360271220c12f20a7238bc302503 (diff) |
mc146818rtc: Handle host clock resets
Make use of the new clock reset notifier to update the RTC whenever
rtc_clock is the host clock and that happens to jump backward. This
avoids that the RTC stalls for the period the host clock was set back.
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/mc146818rtc.c')
-rw-r--r-- | hw/mc146818rtc.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 1c9a706b1b..feb3b25acd 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -99,6 +99,7 @@ typedef struct RTCState { QEMUTimer *coalesced_timer; QEMUTimer *second_timer; QEMUTimer *second_timer2; + Notifier clock_reset_notifier; } RTCState; static void rtc_set_time(RTCState *s); @@ -572,6 +573,22 @@ static const VMStateDescription vmstate_rtc = { } }; +static void rtc_notify_clock_reset(Notifier *notifier, void *data) +{ + RTCState *s = container_of(notifier, RTCState, clock_reset_notifier); + int64_t now = *(int64_t *)data; + + rtc_set_date_from_host(&s->dev); + s->next_second_time = now + (get_ticks_per_sec() * 99) / 100; + qemu_mod_timer(s->second_timer2, s->next_second_time); + rtc_timer_update(s, now); +#ifdef TARGET_I386 + if (rtc_td_hack) { + rtc_coalesced_timer_update(s); + } +#endif +} + static void rtc_reset(void *opaque) { RTCState *s = opaque; @@ -608,6 +625,9 @@ static int rtc_initfn(ISADevice *dev) s->second_timer = qemu_new_timer_ns(rtc_clock, rtc_update_second, s); s->second_timer2 = qemu_new_timer_ns(rtc_clock, rtc_update_second2, s); + s->clock_reset_notifier.notify = rtc_notify_clock_reset; + qemu_register_clock_reset_notifier(rtc_clock, &s->clock_reset_notifier); + s->next_second_time = qemu_get_clock_ns(rtc_clock) + (get_ticks_per_sec() * 99) / 100; qemu_mod_timer(s->second_timer2, s->next_second_time); |