qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 4/4] mips: add gic support to malta


From: Yongbok Kim
Subject: [Qemu-devel] [PATCH 4/4] mips: add gic support to malta
Date: Fri, 16 Oct 2015 00:52:09 +0100

Add Global Interrupt Controller support to Malta board.
The I8259 is connected to pin 3 of the GIC.
Increase number of CPUs supported to 32.

Signed-off-by: Yongbok Kim <address@hidden>
---
 hw/mips/mips_malta.c |   71 ++++++++++++++++++++++++++++++++++++++++++++++++-
 target-mips/cpu.h    |    1 +
 2 files changed, 70 insertions(+), 2 deletions(-)

diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index c1f570a..d2611f0 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -54,6 +54,8 @@
 #include "hw/empty_slot.h"
 #include "sysemu/kvm.h"
 #include "exec/semihost.h"
+#include "hw/mips/mips_gcr.h"
+#include "hw/mips/mips_gic.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -92,6 +94,8 @@ typedef struct {
 typedef struct {
     SysBusDevice parent_obj;
 
+    MIPSGCRState gcr;
+    MIPSGICState gic;
     qemu_irq *i8259;
 } MaltaState;
 
@@ -566,6 +570,50 @@ static MaltaFPGAState *malta_fpga_init(MemoryRegion 
*address_space,
     return s;
 }
 
+static void gcr_init(MaltaState *s, Error **err)
+{
+    SysBusDevice *gcrbusdev;
+    DeviceState *gcrdev;
+
+    object_initialize(&s->gcr, sizeof(s->gcr), TYPE_MIPS_GCR);
+    qdev_set_parent_bus(DEVICE(&s->gcr), sysbus_get_default());
+
+    gcrdev = DEVICE(&s->gcr);
+
+    object_property_set_int(OBJECT(&s->gcr), smp_cpus, "num-cpu", err);
+    object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", err);
+    object_property_set_bool(OBJECT(&s->gcr), true, "realized", err);
+    if (*err != NULL) {
+        return;
+    }
+
+    gcrbusdev = SYS_BUS_DEVICE(gcrdev);
+    sysbus_mmio_map(gcrbusdev, 0, GCR_BASE_ADDR);
+}
+
+static void *gic_init(MaltaState *s, Error **err)
+{
+    SysBusDevice *gicbusdev;
+    DeviceState *gicdev;
+
+    object_initialize(&s->gic, sizeof(s->gic), TYPE_MIPS_GIC);
+    qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default());
+
+    gicdev = DEVICE(&s->gic);
+
+    object_property_set_int(OBJECT(&s->gic), smp_cpus, "num-cpu", err);
+    object_property_set_int(OBJECT(&s->gic), 256, "num-irq", err);
+    object_property_set_bool(OBJECT(&s->gic), true, "realized", err);
+    if (*err != NULL) {
+        return NULL;
+    }
+
+    gicbusdev = SYS_BUS_DEVICE(gicdev);
+    sysbus_mmio_map(gicbusdev, 0, GIC_BASE_ADDR);
+
+    return (void *) s->gic.irqs;
+}
+
 /* Network support */
 static void network_init(PCIBus *pci_bus)
 {
@@ -1136,6 +1184,21 @@ void mips_malta_init(MachineState *machine)
     cpu_mips_irq_init_cpu(env);
     cpu_mips_clock_init(env);
 
+    /* GCR/GIC */
+    if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
+        Error *err = NULL;
+        gcr_init(s, &err);
+        if (err != NULL) {
+            error_report("%s", error_get_pretty(err));
+            exit(1);
+        }
+        env->gic_irqs = gic_init(s, &err);
+        if (err != NULL) {
+            error_report("%s", error_get_pretty(err));
+            exit(1);
+        }
+    }
+
     /*
      * We have a circular dependency problem: pci_bus depends on isa_irq,
      * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
@@ -1155,7 +1218,11 @@ void mips_malta_init(MachineState *machine)
 
     /* Interrupt controller */
     /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
-    s->i8259 = i8259_init(isa_bus, env->irq[2]);
+    if (env->gic_irqs) {
+        s->i8259 = i8259_init(isa_bus, env->gic_irqs[3]);
+    } else {
+        s->i8259 = i8259_init(isa_bus, env->irq[2]);
+    }
 
     isa_bus_irqs(isa_bus, s->i8259);
     pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
@@ -1209,7 +1276,7 @@ static void mips_malta_machine_init(MachineClass *mc)
 {
     mc->desc = "MIPS Malta Core LV";
     mc->init = mips_malta_init;
-    mc->max_cpus = 16;
+    mc->max_cpus = 32;
     mc->is_default = 1;
 }
 
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 639ef37..fdd5643 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -594,6 +594,7 @@ struct CPUMIPSState {
 
     const mips_def_t *cpu_model;
     void *irq[8];
+    void **gic_irqs;
     QEMUTimer *timer; /* Internal timer */
 };
 
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]