Patchwork [RFC,3/4] mc146818: push apic dependencies to pc.c

login
register
mail settings
Submitter Blue Swirl
Date May 23, 2010, 12:39 p.m.
Message ID <AANLkTim67gXLIfhR37-bN5LhOtIcaMHF4aC8oZCVIrl0@mail.gmail.com>
Download mbox | patch
Permalink /patch/53328/
State New
Headers show

Comments

Blue Swirl - May 23, 2010, 12:39 p.m.
A side effect is that coalesced irq handling is extended to seconds
alarm and irq reinjection.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
---
 hw/mc146818rtc.c |   20 ++++++++++----------
 hw/mc146818rtc.h |    1 +
 hw/pc.c          |    6 ++++++
 hw/pc.h          |    1 +
 4 files changed, 18 insertions(+), 10 deletions(-)

Patch

diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index e0c33c5..93d72cc 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -25,7 +25,6 @@ 
 #include "qemu-timer.h"
 #include "sysemu.h"
 #include "pc.h"
-#include "apic.h"
 #include "isa.h"
 #include "mc146818rtc.h"

@@ -115,16 +114,19 @@  static void rtc_coalesced_timer(void *opaque)
     RTCState *s = opaque;

     if (s->irq_coalesced != 0) {
-        apic_reset_irq_delivered();
         s->cmos_data[RTC_REG_C] |= 0xc0;
         qemu_irq_raise(s->irq);
-        if (apic_get_irq_delivered()) {
-            s->irq_coalesced--;
-        }
     }

     rtc_coalesced_timer_update(s);
 }
+
+void rtc_dec_coalesced(ISADevice *dev)
+{
+    RTCState *s = DO_UPCAST(RTCState, dev, dev);
+
+    s->irq_coalesced--;
+}
 #endif

 static void rtc_timer_update(RTCState *s, int64_t current_time)
@@ -168,11 +170,12 @@  static void rtc_periodic_timer(void *opaque)
         s->cmos_data[RTC_REG_C] |= 0xc0;
 #ifdef TARGET_I386
         if(rtc_td_hack) {
+            uint32_t old_coalesced = s->irq_coalesced;
+
             if (s->irq_reinject_on_ack_count >= RTC_REINJECT_ON_ACK_COUNT)
                 s->irq_reinject_on_ack_count = 0;		
-            apic_reset_irq_delivered();
             qemu_irq_raise(s->irq);
-            if (!apic_get_irq_delivered()) {
+            if (s->irq_coalesced == old_coalesced) {
                 s->irq_coalesced++;
                 rtc_coalesced_timer_update(s);
             }
@@ -452,10 +455,7 @@  static uint32_t cmos_ioport_read(void *opaque,
uint32_t addr)
             if(s->irq_coalesced &&
                     s->irq_reinject_on_ack_count < RTC_REINJECT_ON_ACK_COUNT) {
                 s->irq_reinject_on_ack_count++;
-                apic_reset_irq_delivered();
                 qemu_irq_raise(s->irq);
-                if (apic_get_irq_delivered())
-                    s->irq_coalesced--;
                 break;
             }
 #endif
diff --git a/hw/mc146818rtc.h b/hw/mc146818rtc.h
index d630485..c496ecd 100644
--- a/hw/mc146818rtc.h
+++ b/hw/mc146818rtc.h
@@ -6,6 +6,7 @@ 
 ISADevice *rtc_init(int base_year);
 void rtc_set_memory(ISADevice *dev, int addr, int val);
 void rtc_set_date(ISADevice *dev, const struct tm *tm);
+void rtc_dec_coalesced(ISADevice *dev);

 #define RTC_ISA_IRQ 8

diff --git a/hw/pc.c b/hw/pc.c
index 9f1a9d6..c6f28e1 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -78,6 +78,8 @@  static void isa_set_irq(IsaIrqState *isa, int n, int level)

 static void rtc_irq_handler(IsaIrqState *isa, int level)
 {
+    apic_reset_irq_delivered();
+
     /* When HPET is operating in legacy mode, RTC interrupts are disabled.
      * We block qemu_irq_raise, but not qemu_irq_lower, in case legacy
      * mode is established while interrupt is raised. We want it to
@@ -85,6 +87,9 @@  static void rtc_irq_handler(IsaIrqState *isa, int level)
      */
     if ((isa->hpet_state && !hpet_in_legacy_mode(isa->hpet_state)) || !level) {
         isa_set_irq(isa, RTC_ISA_IRQ, level);
+        if (apic_get_irq_delivered()) {
+            rtc_dec_coalesced(isa->rtc_state);
+        }
     }
 }

@@ -961,6 +966,7 @@  void pc_basic_device_init(qemu_irq *isa_irq,
IsaIrqState *isa,
     register_ioport_write(0xf0, 1, 1, ioportF0_write, NULL);

     *rtc_state = rtc_init(2000);
+    isa->rtc_state = *rtc_state;

     qemu_register_boot_set(pc_boot_set, *rtc_state);

diff --git a/hw/pc.h b/hw/pc.h
index 3e085b9..e19dfe9 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -42,6 +42,7 @@  void irq_info(Monitor *mon);
 typedef struct isa_irq_state {
     qemu_irq *i8259;
     qemu_irq *ioapic;
+    ISADevice *rtc_state;
     void *hpet_state;
 } IsaIrqState;