mc146818rtc: Use lost_tick_policy property

Allow to configure the MC146818 RTC via the new lost tick policy
property and replace rtc_td_hack with this mechanism.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
Jan Kiszka 2012-01-23 20:15:12 +01:00 committed by Anthony Liguori
parent 4f6dd9af9c
commit 433acf0dac
3 changed files with 42 additions and 13 deletions

View File

@ -101,6 +101,7 @@ typedef struct RTCState {
QEMUTimer *second_timer; QEMUTimer *second_timer;
QEMUTimer *second_timer2; QEMUTimer *second_timer2;
Notifier clock_reset_notifier; Notifier clock_reset_notifier;
LostTickPolicy lost_tick_policy;
} RTCState; } RTCState;
static void rtc_set_time(RTCState *s); 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) { if (s->cmos_data[RTC_REG_B] & REG_B_PIE) {
s->cmos_data[RTC_REG_C] |= REG_C_IRQF; s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
#ifdef TARGET_I386 #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) if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
s->irq_reinject_on_ack_count = 0; s->irq_reinject_on_ack_count = 0;
apic_reset_irq_delivered(); apic_reset_irq_delivered();
@ -544,7 +545,7 @@ static int rtc_post_load(void *opaque, int version_id)
RTCState *s = opaque; RTCState *s = opaque;
if (version_id >= 2) { if (version_id >= 2) {
if (rtc_td_hack) { if (s->lost_tick_policy == LOST_TICK_SLEW) {
rtc_coalesced_timer_update(s); 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); qemu_mod_timer(s->second_timer2, s->next_second_time);
rtc_timer_update(s, now); rtc_timer_update(s, now);
#ifdef TARGET_I386 #ifdef TARGET_I386
if (rtc_td_hack) { if (s->lost_tick_policy == LOST_TICK_SLEW) {
rtc_coalesced_timer_update(s); rtc_coalesced_timer_update(s);
} }
#endif #endif
@ -605,8 +606,9 @@ static void rtc_reset(void *opaque)
qemu_irq_lower(s->irq); qemu_irq_lower(s->irq);
#ifdef TARGET_I386 #ifdef TARGET_I386
if (rtc_td_hack) if (s->lost_tick_policy == LOST_TICK_SLEW) {
s->irq_coalesced = 0; s->irq_coalesced = 0;
}
#endif #endif
} }
@ -654,12 +656,20 @@ static int rtc_initfn(ISADevice *dev)
rtc_set_date_from_host(dev); rtc_set_date_from_host(dev);
s->periodic_timer = qemu_new_timer_ns(rtc_clock, rtc_periodic_timer, s);
#ifdef TARGET_I386 #ifdef TARGET_I386
if (rtc_td_hack) switch (s->lost_tick_policy) {
case LOST_TICK_SLEW:
s->coalesced_timer = s->coalesced_timer =
qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s); qemu_new_timer_ns(rtc_clock, rtc_coalesced_timer, s);
break;
case LOST_TICK_DISCARD:
break;
default:
return -EINVAL;
}
#endif #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_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->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, .class_init = rtc_class_initfn,
.props = (Property[]) { .props = (Property[]) {
DEFINE_PROP_INT32("base_year", RTCState, base_year, 1980), 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(), DEFINE_PROP_END_OF_LIST(),
} }
}; };

View File

@ -105,7 +105,6 @@ extern int graphic_depth;
extern DisplayType display_type; extern DisplayType display_type;
extern const char *keyboard_layout; extern const char *keyboard_layout;
extern int win2k_install_hack; extern int win2k_install_hack;
extern int rtc_td_hack;
extern int alt_grab; extern int alt_grab;
extern int ctrl_grab; extern int ctrl_grab;
extern int usb_enabled; extern int usb_enabled;

28
vl.c
View File

@ -201,7 +201,6 @@ CharDriverState *serial_hds[MAX_SERIAL_PORTS];
CharDriverState *parallel_hds[MAX_PARALLEL_PORTS]; CharDriverState *parallel_hds[MAX_PARALLEL_PORTS];
CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES]; CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
int win2k_install_hack = 0; int win2k_install_hack = 0;
int rtc_td_hack = 0;
int usb_enabled = 0; int usb_enabled = 0;
int singlestep = 0; int singlestep = 0;
int smp_cpus = 1; int smp_cpus = 1;
@ -540,9 +539,18 @@ static void configure_rtc(QemuOpts *opts)
value = qemu_opt_get(opts, "driftfix"); value = qemu_opt_get(opts, "driftfix");
if (value) { if (value) {
if (!strcmp(value, "slew")) { 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")) { } else if (!strcmp(value, "none")) {
rtc_td_hack = 0; /* discard is default */
} else { } else {
fprintf(stderr, "qemu: invalid option value '%s'\n", value); fprintf(stderr, "qemu: invalid option value '%s'\n", value);
exit(1); exit(1);
@ -2836,9 +2844,19 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_win2k_hack: case QEMU_OPTION_win2k_hack:
win2k_install_hack = 1; win2k_install_hack = 1;
break; break;
case QEMU_OPTION_rtc_td_hack: case QEMU_OPTION_rtc_td_hack: {
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);
break; break;
}
case QEMU_OPTION_acpitable: case QEMU_OPTION_acpitable:
do_acpitable_option(optarg); do_acpitable_option(optarg);
break; break;