diff options
-rw-r--r-- | hw/mc146818rtc.c | 26 | ||||
-rw-r--r-- | sysemu.h | 1 | ||||
-rw-r--r-- | vl.c | 28 |
3 files changed, 42 insertions, 13 deletions
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c index 685eb89f90..e6e4cb7d5d 100644 --- a/hw/mc146818rtc.c +++ b/hw/mc146818rtc.c @@ -101,6 +101,7 @@ typedef struct RTCState { QEMUTimer *second_timer; QEMUTimer *second_timer2; Notifier clock_reset_notifier; + LostTickPolicy lost_tick_policy; } RTCState; static void rtc_set_time(RTCState *s); @@ -183,7 +184,7 @@ static void rtc_periodic_timer(void *opaque) if (s->cmos_data[RTC_REG_B] & REG_B_PIE) { s->cmos_data[RTC_REG_C] |= REG_C_IRQF; #ifdef TARGET_I386 - if(rtc_td_hack) { + if (s->lost_tick_policy == LOST_TICK_SLEW) { if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT) s->irq_reinject_on_ack_count = 0; apic_reset_irq_delivered(); @@ -544,7 +545,7 @@ static int rtc_post_load(void *opaque, int version_id) RTCState *s = opaque; if (version_id >= 2) { - if (rtc_td_hack) { + if (s->lost_tick_policy == LOST_TICK_SLEW) { rtc_coalesced_timer_update(s); } } @@ -589,7 +590,7 @@ static void rtc_notify_clock_reset(Notifier *notifier, void *data) qemu_mod_timer(s->second_timer2, s->next_second_time); rtc_timer_update(s, now); #ifdef TARGET_I386 - if (rtc_td_hack) { + if (s->lost_tick_policy == LOST_TICK_SLEW) { rtc_coalesced_timer_update(s); } #endif @@ -605,8 +606,9 @@ static void rtc_reset(void *opaque) qemu_irq_lower(s->irq); #ifdef TARGET_I386 - if (rtc_td_hack) - s->irq_coalesced = 0; + if (s->lost_tick_policy == LOST_TICK_SLEW) { + s->irq_coalesced = 0; + } #endif } @@ -654,12 +656,20 @@ static int rtc_initfn(ISADevice *dev) rtc_set_date_from_host(dev); - s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s); #ifdef TARGET_I386 - if (rtc_td_hack) + switch (s->lost_tick_policy) { + case LOST_TICK_SLEW: s->coalesced_timer = qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s); + break; + case LOST_TICK_DISCARD: + break; + default: + return -EINVAL; + } #endif + + s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s); 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); @@ -713,6 +723,8 @@ static DeviceInfo mc146818rtc_info = { .class_init = rtc_class_initfn, .props = (Property[]) { DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980), + DEFINE_PROP_LOSTTICKPOLICY("lost_tick_policy", RTCState, + lost_tick_policy, LOST_TICK_DISCARD), DEFINE_PROP_END_OF_LIST(), } }; @@ -105,7 +105,6 @@ extern int graphic_depth; extern DisplayType display_type; extern const char *keyboard_layout; extern int win2k_install_hack; -extern int rtc_td_hack; extern int alt_grab; extern int ctrl_grab; extern int usb_enabled; @@ -201,7 +201,6 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; int win2k_install_hack = 0; -int rtc_td_hack = 0; int usb_enabled = 0; int singlestep = 0; int smp_cpus = 1; @@ -540,9 +539,18 @@ static void configure_rtc(QemuOpts *opts) value = qemu_opt_get(opts, "driftfix"); if (value) { if (!strcmp(value, "slew")) { - rtc_td_hack = 1; + static GlobalProperty slew_lost_ticks[] = { + { + .driver = "mc146818rtc", + .property = "lost_tick_policy", + .value = "slew", + }, + { /* end of list */ } + }; + + qdev_prop_register_global_list(slew_lost_ticks); } else if (!strcmp(value, "none")) { - rtc_td_hack = 0; + /* discard is default */ } else { fprintf(stderr, "qemu: invalid option value '%s'\n", value); exit(1); @@ -2836,9 +2844,19 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_win2k_hack: win2k_install_hack = 1; break; - case QEMU_OPTION_rtc_td_hack: - rtc_td_hack = 1; + case QEMU_OPTION_rtc_td_hack: { + static GlobalProperty slew_lost_ticks[] = { + { + .driver = "mc146818rtc", + .property = "lost_tick_policy", + .value = "slew", + }, + { /* end of list */ } + }; + + qdev_prop_register_global_list(slew_lost_ticks); break; + } case QEMU_OPTION_acpitable: do_acpitable_option(optarg); break; |