aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Zhang <yang.z.zhang@intel.com>2012-08-02 18:04:07 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2012-09-10 13:52:28 -0500
commit9324cc50c6b5df0998d46e8fca76e35f00ced6c3 (patch)
treeee986c3c6f51d72d00a36112137cc32d8825eea2
parente46deabaa58b78397aeef2b04147aeecf5933794 (diff)
RTC: Update interrupt state when interrupts are masked/unmasked
If an interrupt flag is already set when the interrupt becomes enabled, raise an interrupt immediately, and vice versa if interrupts become disabled. Signed-off-by: Yang Zhang <yang.z.zhang@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--hw/mc146818rtc.c9
-rw-r--r--hw/mc146818rtc_regs.h1
2 files changed, 10 insertions, 0 deletions
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index 175ddac6f..b41eb4b94 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -221,6 +221,15 @@ static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
rtc_set_time(s);
}
}
+ /* if an interrupt flag is already set when the interrupt
+ * becomes enabled, raise an interrupt immediately. */
+ if (data & s->cmos_data[RTC_REG_C] & REG_C_MASK) {
+ s->cmos_data[RTC_REG_C] |= REG_C_IRQF;
+ qemu_irq_raise(s->irq);
+ } else {
+ s->cmos_data[RTC_REG_C] &= ~REG_C_IRQF;
+ qemu_irq_lower(s->irq);
+ }
s->cmos_data[RTC_REG_B] = data;
periodic_timer_update(s, qemu_get_clock_ns(rtc_clock));
break;
diff --git a/hw/mc146818rtc_regs.h b/hw/mc146818rtc_regs.h
index 3ab37709f..fc10076ec 100644
--- a/hw/mc146818rtc_regs.h
+++ b/hw/mc146818rtc_regs.h
@@ -58,5 +58,6 @@
#define REG_C_IRQF 0x80
#define REG_C_PF 0x40
#define REG_C_AF 0x20
+#define REG_C_MASK 0x70
#endif