QEMUTimer *second_timer;
QEMUTimer *second_timer2;
Notifier clock_reset_notifier;
+ LostTickPolicy lost_tick_policy;
} RTCState;
static void rtc_set_time(RTCState *s);
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();
RTCState *s = opaque;
if (version_id >= 2) {
- if (rtc_td_hack) {
+ if (s->lost_tick_policy == LOST_TICK_SLEW) {
rtc_coalesced_timer_update(s);
}
}
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
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
}
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);
.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(),
}
};
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;
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);
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;