Add PowerPC power-management state check callback.
[qemu] / hw / arm_gic.c
index c7cc380..8cd7182 100644 (file)
@@ -1,4 +1,4 @@
-/* 
+/*
  * ARM AMBA Generic/Distributed Interrupt Controller
  *
  * Copyright (c) 2006 CodeSourcery.
@@ -17,7 +17,7 @@
 
 #ifdef DEBUG_GIC
 #define DPRINTF(fmt, args...) \
-do { printf("arm_gic: " fmt , (int)s->base, ##args); } while (0)
+do { printf("arm_gic: " fmt , ##args); } while (0)
 #else
 #define DPRINTF(fmt, args...) do {} while(0)
 #endif
@@ -60,10 +60,8 @@ typedef struct gic_irq_state
 
 typedef struct gic_state
 {
-    arm_pic_handler handler;
     uint32_t base;
-    void *parent;
-    int parent_irq;
+    qemu_irq parent_irq;
     int enabled;
     int cpu_enabled;
 
@@ -88,7 +86,7 @@ static void gic_update(gic_state *s)
 
     s->current_pending = 1023;
     if (!s->enabled || !s->cpu_enabled) {
-        pic_set_irq_new(s->parent, s->parent_irq, 0);
+        qemu_irq_lower(s->parent_irq);
         return;
     }
     best_prio = 0x100;
@@ -102,12 +100,12 @@ static void gic_update(gic_state *s)
         }
     }
     if (best_prio > s->priority_mask) {
-        pic_set_irq_new(s->parent, s->parent_irq, 0);
+        qemu_irq_lower(s->parent_irq);
     } else {
         s->current_pending = best_irq;
         if (best_prio < s->running_priority) {
             DPRINTF("Raised pending IRQ %d\n", best_irq);
-            pic_set_irq_new(s->parent, s->parent_irq, 1);
+            qemu_irq_raise(s->parent_irq);
         }
     }
 }
@@ -117,7 +115,7 @@ static void gic_set_irq(void *opaque, int irq, int level)
     gic_state *s = (gic_state *)opaque;
     /* The first external input line is internal interrupt 32.  */
     irq += 32;
-    if (level == GIC_TEST_LEVEL(irq)) 
+    if (level == GIC_TEST_LEVEL(irq))
         return;
 
     if (level) {
@@ -135,7 +133,10 @@ static void gic_set_irq(void *opaque, int irq, int level)
 static void gic_set_running_irq(gic_state *s, int irq)
 {
     s->running_irq = irq;
-    s->running_priority = s->priority[irq];
+    if (irq == 1023)
+        s->running_priority = 0x100;
+    else
+        s->running_priority = s->priority[irq];
     gic_update(s);
 }
 
@@ -147,7 +148,7 @@ static uint32_t gic_acknowledge_irq(gic_state *s)
         DPRINTF("ACK no pending IRQ\n");
         return 1023;
     }
-    pic_set_irq_new(s->parent, s->parent_irq, 0);
+    qemu_irq_lower(s->parent_irq);
     s->last_active[new_irq] = s->running_irq;
     /* For level triggered interrupts we clear the pending bit while
        the interrupt is active.  */
@@ -160,7 +161,7 @@ static uint32_t gic_acknowledge_irq(gic_state *s)
 static void gic_complete_irq(gic_state * s, int irq)
 {
     int update = 0;
-    DPRINTF("EIO %d\n", irq);
+    DPRINTF("EOI %d\n", irq);
     if (s->running_irq == 1023)
         return; /* No active IRQ.  */
     if (irq != 1023) {
@@ -383,7 +384,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
         s->irq_target[irq] = value;
     } else if (offset < 0xf00) {
         /* Interrupt Configuration.  */
-        irq = (offset - 0xc00) * 2;
+        irq = (offset - 0xc00) * 4;
         if (irq >= GIC_NIRQ)
             goto bad_reg;
         for (i = 0; i < 4; i++) {
@@ -459,7 +460,7 @@ static uint32_t gic_cpu_read(void *opaque, target_phys_addr_t offset)
     case 0x18: /* Highest Pending Interrupt */
         return s->current_pending;
     default:
-        cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
+        cpu_abort (cpu_single_env, "gic_cpu_read: Bad offset %x\n", offset);
         return 0;
     }
 }
@@ -483,7 +484,7 @@ static void gic_cpu_write(void *opaque, target_phys_addr_t offset,
     case 0x10: /* End Of Interrupt */
         return gic_complete_irq(s, value & 0x3ff);
     default:
-        cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
+        cpu_abort (cpu_single_env, "gic_cpu_write: Bad offset %x\n", offset);
         return;
     }
     gic_update(s);
@@ -517,28 +518,28 @@ static void gic_reset(gic_state *s)
     s->cpu_enabled = 0;
 }
 
-void *arm_gic_init(uint32_t base, void *parent, int parent_irq)
+qemu_irq *arm_gic_init(uint32_t base, qemu_irq parent_irq)
 {
     gic_state *s;
+    qemu_irq *qi;
     int iomemtype;
 
     s = (gic_state *)qemu_mallocz(sizeof(gic_state));
     if (!s)
         return NULL;
-    s->handler = gic_set_irq;
-    s->parent = parent;
+    qi = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
     s->parent_irq = parent_irq;
     if (base != 0xffffffff) {
         iomemtype = cpu_register_io_memory(0, gic_cpu_readfn,
                                            gic_cpu_writefn, s);
-        cpu_register_physical_memory(base, 0x00000fff, iomemtype);
+        cpu_register_physical_memory(base, 0x00001000, iomemtype);
         iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
                                            gic_dist_writefn, s);
-        cpu_register_physical_memory(base + 0x1000, 0x00000fff, iomemtype);
+        cpu_register_physical_memory(base + 0x1000, 0x00001000, iomemtype);
         s->base = base;
     } else {
         s->base = 0;
     }
     gic_reset(s);
-    return s;
+    return qi;
 }