Patchwork [12/22] i8259: Switch to per-PIC IRQ update

login
register
mail settings
Submitter Jan Kiszka
Date Sept. 28, 2011, 11 a.m.
Message ID <6fcea37212a2baec80a7d1d79a777359a8ca3674.1317207666.git.jan.kiszka@siemens.com>
Download mbox | patch
Permalink /patch/116769/
State New
Headers show

Comments

Jan Kiszka - Sept. 28, 2011, 11 a.m.
This converts pic_update_irq to work against a single PIC instead of the
complete cascade. Along this change, the required update after
pic_set_irq1 is now moved into that function.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/i8259.c |   59 ++++++++++++++++++++---------------------------------------
 1 files changed, 20 insertions(+), 39 deletions(-)

Patch

diff --git a/hw/i8259.c b/hw/i8259.c
index 3498c6b..53b86dd 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -118,39 +118,19 @@  static int pic_get_irq(PicState *s)
     }
 }
 
-static void pic_set_irq1(PicState *s, int irq, int level);
-
-/* raise irq to CPU if necessary. must be called every time the active
-   irq may change */
-static void pic_update_irq(PicState2 *s)
+/* Update INT output. Must be called every time the output may have changed. */
+static void pic_update_irq(PicState *s)
 {
-    int irq2, irq;
-
-    /* first look at slave pic */
-    irq2 = pic_get_irq(&s->pics[1]);
-    if (irq2 >= 0) {
-        /* if irq request by slave pic, signal master PIC */
-        pic_set_irq1(&s->pics[0], 2, 1);
-        pic_set_irq1(&s->pics[0], 2, 0);
-    }
-    /* look at requested irq */
-    irq = pic_get_irq(&s->pics[0]);
-    if (irq >= 0) {
-#if defined(DEBUG_PIC)
-        {
-            int i;
-            for(i = 0; i < 2; i++) {
-                printf("pic%d: imr=%x irr=%x padd=%d\n",
-                       i, s->pics[i].imr, s->pics[i].irr,
-                       s->pics[i].priority_add);
+    int irq;
 
-            }
-        }
-        printf("pic: cpu_interrupt\n");
-#endif
-        qemu_irq_raise(s->pics[0].int_out);
+    irq = pic_get_irq(s);
+    if (irq >= 0) {
+        DPRINTF("pic%d: imr=%x irr=%x padd=%d\n",
+                s == &s->pics_state->pics[0] ? 0 : 1, s->imr, s->irr,
+                s->priority_add);
+        qemu_irq_raise(s->int_out);
     } else {
-        qemu_irq_lower(s->pics[0].int_out);
+        qemu_irq_lower(s->int_out);
     }
 }
 
@@ -179,6 +159,7 @@  static void pic_set_irq1(PicState *s, int irq, int level)
             s->last_irr &= ~mask;
         }
     }
+    pic_update_irq(s);
 }
 
 #ifdef DEBUG_IRQ_LATENCY
@@ -205,7 +186,6 @@  static void i8259_set_irq(void *opaque, int irq, int level)
     }
 #endif
     pic_set_irq1(&s->pics[irq >> 3], irq & 7, level);
-    pic_update_irq(s);
 }
 
 /* acknowledge interrupt 'irq' */
@@ -220,6 +200,7 @@  static void pic_intack(PicState *s, int irq)
     /* We don't clear a level sensitive interrupt here */
     if (!(s->elcr & (1 << irq)))
         s->irr &= ~(1 << irq);
+    pic_update_irq(s);
 }
 
 int pic_read_irq(PicState2 *s)
@@ -246,7 +227,6 @@  int pic_read_irq(PicState2 *s)
         irq = 7;
         intno = s->pics[0].irq_base + irq;
     }
-    pic_update_irq(s);
 
 #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_LATENCY)
     if (irq == 2) {
@@ -283,7 +263,7 @@  static void pic_reset(void *opaque)
     s->init4 = 0;
     s->single_mode = 0;
     /* Note: ELCR is not reset */
-    pic_update_irq(s->pics_state);
+    pic_update_irq(s);
 }
 
 static void pic_ioport_write(void *opaque, target_phys_addr_t addr64,
@@ -326,23 +306,23 @@  static void pic_ioport_write(void *opaque, target_phys_addr_t addr64,
                     s->isr &= ~(1 << irq);
                     if (cmd == 5)
                         s->priority_add = (irq + 1) & 7;
-                    pic_update_irq(s->pics_state);
+                    pic_update_irq(s);
                 }
                 break;
             case 3:
                 irq = val & 7;
                 s->isr &= ~(1 << irq);
-                pic_update_irq(s->pics_state);
+                pic_update_irq(s);
                 break;
             case 6:
                 s->priority_add = (val + 1) & 7;
-                pic_update_irq(s->pics_state);
+                pic_update_irq(s);
                 break;
             case 7:
                 irq = val & 7;
                 s->isr &= ~(1 << irq);
                 s->priority_add = (irq + 1) & 7;
-                pic_update_irq(s->pics_state);
+                pic_update_irq(s);
                 break;
             default:
                 /* no operation */
@@ -354,7 +334,7 @@  static void pic_ioport_write(void *opaque, target_phys_addr_t addr64,
         case 0:
             /* normal mode */
             s->imr = val;
-            pic_update_irq(s->pics_state);
+            pic_update_irq(s);
             break;
         case 1:
             s->irq_base = val & 0xf8;
@@ -390,8 +370,9 @@  static uint32_t pic_poll_read(PicState *s)
         }
         s->irr &= ~(1 << ret);
         s->isr &= ~(1 << ret);
-        if (slave || ret != 2)
-            pic_update_irq(s->pics_state);
+        if (slave || ret != 2) {
+            pic_update_irq(s);
+        }
     } else {
         ret = 0x07;
     }