When a windows vm starts, periodic timer of rtc will stop several times. windows kernel will check whether REG_A_UIP is changed. REG_C's interrupt flags will not be cleared when periodic timer stops and the update timer will switch to alarm timer. So the expiration time of alarm timer is very long and REG_A_UIP will not vary.At last windows kernel will repeat to check REG_A_UIP all the time.
Signed-off-by: Peng Hao <peng.h...@zte.com.cn> Signed-off-by: Liu Yi <liu.y...@zte.com.cn> --- hw/timer/mc146818rtc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c index 1b8d3d7..aa55fae 100644 --- a/hw/timer/mc146818rtc.c +++ b/hw/timer/mc146818rtc.c @@ -457,6 +457,8 @@ static void rtc_update_timer(void *opaque) if ((new_irqs & s->cmos_data[RTC_REG_B]) != 0) { s->cmos_data[RTC_REG_C] |= REG_C_IRQF; qemu_irq_raise(s->irq); + } else if ((s->cmos_data[RTC_REG_B] & REG_B_UIE) == 0) { + s->cmos_data[RTC_REG_C] &= ~REG_C_UF; } check_update_timer(s); } @@ -559,7 +561,7 @@ static void cmos_ioport_write(void *opaque, hwaddr addr, s->cmos_data[RTC_REG_C] |= REG_C_IRQF; qemu_irq_raise(s->irq); } else { - s->cmos_data[RTC_REG_C] &= ~REG_C_IRQF; + s->cmos_data[RTC_REG_C] &= ~(REG_C_UF | REG_C_IRQF); qemu_irq_lower(s->irq); } s->cmos_data[RTC_REG_B] = data; -- 1.8.3.1