diff options
author | Jan Beulich <jbeulich@suse.com> | 2013-05-21 10:12:50 +0200 |
---|---|---|
committer | Jan Beulich <jbeulich@suse.com> | 2013-05-21 10:12:50 +0200 |
commit | f3347f520cb4d8aa4566182b013c6758d80cbe88 (patch) | |
tree | 18d078892a80b52aad4f36b24aa0a0b9d82a1616 /xen/arch/x86/hvm/rtc.c | |
parent | 5d43891bf4002b754cd90d83e91d9190e8c8b9d0 (diff) | |
download | xen-f3347f520cb4d8aa4566182b013c6758d80cbe88.tar.gz xen-f3347f520cb4d8aa4566182b013c6758d80cbe88.tar.bz2 xen-f3347f520cb4d8aa4566182b013c6758d80cbe88.zip |
x86/HVM: adjust IRQ (de-)assertion
De-assertion should only happen when RTC_IRQF gets cleared, i.e. upon
REG_C reads. Assertion should be done only when the flag transitions
from 0 to 1.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Tested-by: Roger Pau Monné <roger.pau@citrix.com> (FreeBSD guest)
Diffstat (limited to 'xen/arch/x86/hvm/rtc.c')
-rw-r--r-- | xen/arch/x86/hvm/rtc.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/xen/arch/x86/hvm/rtc.c b/xen/arch/x86/hvm/rtc.c index b728d5e3db..b215886ef0 100644 --- a/xen/arch/x86/hvm/rtc.c +++ b/xen/arch/x86/hvm/rtc.c @@ -52,23 +52,19 @@ static inline int convert_hour(RTCState *s, int hour); static void rtc_update_irq(RTCState *s) { - struct domain *d = vrtc_domain(s); - uint8_t irqf; - ASSERT(spin_is_locked(&s->lock)); - /* IRQ is raised if any source is both raised & enabled */ - irqf = (s->hw.cmos_data[RTC_REG_B] - & s->hw.cmos_data[RTC_REG_C] - & (RTC_PF|RTC_AF|RTC_UF)) - ? RTC_IRQF : 0; + if ( s->hw.cmos_data[RTC_REG_C] & RTC_IRQF ) + return; - s->hw.cmos_data[RTC_REG_C] &= ~RTC_IRQF; - s->hw.cmos_data[RTC_REG_C] |= irqf; + /* IRQ is raised if any source is both raised & enabled */ + if ( !(s->hw.cmos_data[RTC_REG_B] & + s->hw.cmos_data[RTC_REG_C] & + (RTC_PF | RTC_AF | RTC_UF)) ) + return; - hvm_isa_irq_deassert(d, RTC_IRQ); - if ( irqf ) - hvm_isa_irq_assert(d, RTC_IRQ); + s->hw.cmos_data[RTC_REG_C] |= RTC_IRQF; + hvm_isa_irq_assert(vrtc_domain(s), RTC_IRQ); } void rtc_periodic_interrupt(void *opaque) @@ -631,6 +627,8 @@ static uint32_t rtc_ioport_read(RTCState *s, uint32_t addr) case RTC_REG_C: ret = s->hw.cmos_data[s->hw.cmos_index]; s->hw.cmos_data[RTC_REG_C] = 0x00; + if ( ret & RTC_IRQF ) + hvm_isa_irq_deassert(d, RTC_IRQ); rtc_update_irq(s); check_update_timer(s); alarm_timer_update(s); |