X-Git-Url: https://vcs.maemo.org/git/?a=blobdiff_plain;f=hw%2Farm_gic.c;h=8cd7182cff12b422324070ee8625aedb7ccd18b9;hb=cd346349b45ef056f138a184f660b8c34c3213cc;hp=94ce9aa340af8312a6d04cc226c1b20b145e1fae;hpb=326199c2707d45ecbbaa411f6640a152fc199d3e;p=qemu diff --git a/hw/arm_gic.c b/hw/arm_gic.c index 94ce9aa..8cd7182 100644 --- a/hw/arm_gic.c +++ b/hw/arm_gic.c @@ -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) { @@ -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; }