summary refs log tree commit diff stats
path: root/hw/intc/arm_gic_common.c
diff options
context:
space:
mode:
authorPavel Fedin <p.fedin@samsung.com>2015-08-13 11:26:21 +0100
committerPeter Maydell <peter.maydell@linaro.org>2015-08-13 11:26:21 +0100
commit7926c210ab0c44fc3612461a50f487d16be98dca (patch)
treebb9d5d3a369ad519d1a57d73e8b5b03a5c4151f3 /hw/intc/arm_gic_common.c
parent6d6d2abf2c2e52c0f404d0a31a963e945b0cc7ad (diff)
downloadfocaccia-qemu-7926c210ab0c44fc3612461a50f487d16be98dca.tar.gz
focaccia-qemu-7926c210ab0c44fc3612461a50f487d16be98dca.zip
hw/arm/gic: Kill code duplication
Extracted duplicated initialization code from SW-emulated and KVM GIC
implementations and put into gic_init_irqs_and_mmio()

Signed-off-by: Pavel Fedin <p.fedin@samsung.com>
Message-id: 8ea5b2781ef39cb5989420987fc73c70e377687d.1438758065.git.p.fedin@samsung.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/intc/arm_gic_common.c')
-rw-r--r--hw/intc/arm_gic_common.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c
index a64d0714ea..fe64b51cff 100644
--- a/hw/intc/arm_gic_common.c
+++ b/hw/intc/arm_gic_common.c
@@ -84,6 +84,47 @@ static const VMStateDescription vmstate_gic = {
     }
 };
 
+void gic_init_irqs_and_mmio(GICState *s, qemu_irq_handler handler,
+                            const MemoryRegionOps *ops)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(s);
+    int i = s->num_irq - GIC_INTERNAL;
+
+    /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
+     * GPIO array layout is thus:
+     *  [0..N-1] SPIs
+     *  [N..N+31] PPIs for CPU 0
+     *  [N+32..N+63] PPIs for CPU 1
+     *   ...
+     */
+    if (s->revision != REV_NVIC) {
+        i += (GIC_INTERNAL * s->num_cpu);
+    }
+    qdev_init_gpio_in(DEVICE(s), handler, i);
+
+    for (i = 0; i < s->num_cpu; i++) {
+        sysbus_init_irq(sbd, &s->parent_irq[i]);
+    }
+    for (i = 0; i < s->num_cpu; i++) {
+        sysbus_init_irq(sbd, &s->parent_fiq[i]);
+    }
+
+    /* Distributor */
+    memory_region_init_io(&s->iomem, OBJECT(s), ops, s, "gic_dist", 0x1000);
+    sysbus_init_mmio(sbd, &s->iomem);
+
+    if (s->revision != REV_NVIC) {
+        /* This is the main CPU interface "for this core". It is always
+         * present because it is required by both software emulation and KVM.
+         * NVIC is not handled here because its CPU interface is different,
+         * neither it can use KVM.
+         */
+        memory_region_init_io(&s->cpuiomem[0], OBJECT(s), ops ? &ops[1] : NULL,
+                              s, "gic_cpu", s->revision == 2 ? 0x1000 : 0x100);
+        sysbus_init_mmio(sbd, &s->cpuiomem[0]);
+    }
+}
+
 static void arm_gic_common_realize(DeviceState *dev, Error **errp)
 {
     GICState *s = ARM_GIC_COMMON(dev);