qemu-devel
[Top][All Lists]
Advanced

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

[PATCH RFC 10/16] hw/arm: split create_gic function


From: Xu Yandong
Subject: [PATCH RFC 10/16] hw/arm: split create_gic function
Date: Mon, 17 Feb 2020 02:51:22 -0500

Split sharable GIC qdev create and sysbus initiatea codes as independent 
function.

Signed-off-by: Xu Yandong <address@hidden>
---
 hw/arm/arm.c         | 106 +++++++++++++++++++++++++++++++++++++++++++
 hw/arm/virt.c        |  93 +------------------------------------
 include/hw/arm/arm.h |   4 ++
 3 files changed, 112 insertions(+), 91 deletions(-)

diff --git a/hw/arm/arm.c b/hw/arm/arm.c
index ecb99611ed..c51bf513d2 100644
--- a/hw/arm/arm.c
+++ b/hw/arm/arm.c
@@ -39,6 +39,112 @@
 #include "hw/intc/arm_gic.h"
 #include "kvm_arm.h"
 
+void qdev_create_gic(ArmMachineState *ams)
+{
+    MachineState *ms = MACHINE(ams);
+    /* We create a standalone GIC */
+    const char *gictype;
+    int type = ams->gic_version;
+    unsigned int smp_cpus = ms->smp.cpus;
+    uint32_t nb_redist_regions = 0;
+
+    gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
+
+    ams->gic = qdev_create(NULL, gictype);
+    qdev_prop_set_uint32(ams->gic, "revision", type);
+    qdev_prop_set_uint32(ams->gic, "num-cpu", smp_cpus);
+    /* Note that the num-irq property counts both internal and external
+     * interrupts; there are always 32 of the former (mandated by GIC spec).
+     */
+    qdev_prop_set_uint32(ams->gic, "num-irq", NUM_IRQS + 32);
+
+    if (type == 3) {
+        uint32_t redist0_capacity =
+                    ams->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
+        uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
+
+        nb_redist_regions = virt_gicv3_redist_region_count(ams);
+
+        qdev_prop_set_uint32(ams->gic, "len-redist-region-count",
+                             nb_redist_regions);
+        qdev_prop_set_uint32(ams->gic, "redist-region-count[0]", 
redist0_count);
+
+        if (nb_redist_regions == 2) {
+            uint32_t redist1_capacity =
+                    ams->memmap[VIRT_HIGH_GIC_REDIST2].size / 
GICV3_REDIST_SIZE;
+
+            qdev_prop_set_uint32(ams->gic, "redist-region-count[1]",
+                MIN(smp_cpus - redist0_count, redist1_capacity));
+        }
+    }
+}
+
+void init_gic_sysbus(ArmMachineState *ams)
+{
+    MachineState *ms = MACHINE(ams);
+    /* We create a standalone GIC */
+    SysBusDevice *gicbusdev;
+    int type = ams->gic_version, i;
+    unsigned int smp_cpus = ms->smp.cpus;
+    uint32_t nb_redist_regions = 0;
+
+    gicbusdev = SYS_BUS_DEVICE(ams->gic);
+    sysbus_mmio_map(gicbusdev, 0, ams->memmap[VIRT_GIC_DIST].base);
+    if (type == 3) {
+        sysbus_mmio_map(gicbusdev, 1, ams->memmap[VIRT_GIC_REDIST].base);
+        if (nb_redist_regions == 2) {
+            sysbus_mmio_map(gicbusdev, 2,
+                            ams->memmap[VIRT_HIGH_GIC_REDIST2].base);
+        }
+    } else {
+        sysbus_mmio_map(gicbusdev, 1, ams->memmap[VIRT_GIC_CPU].base);
+    }
+
+    /* Wire the outputs from each CPU's generic timer and the GICv3
+     * maintenance interrupt signal to the appropriate GIC PPI inputs,
+     * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
+     */
+    for (i = 0; i < smp_cpus; i++) {
+        DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
+        int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
+        int irq;
+        /* Mapping from the output timer irq lines from the CPU to the
+         * GIC PPI inputs we use for the virt board.
+         */
+        const int timer_irq[] = {
+            [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
+            [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
+            [GTIMER_HYP]  = ARCH_TIMER_NS_EL2_IRQ,
+            [GTIMER_SEC]  = ARCH_TIMER_S_EL1_IRQ,
+        };
+
+        for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
+            qdev_connect_gpio_out(cpudev, irq,
+                                  qdev_get_gpio_in(ams->gic,
+                                                   ppibase + timer_irq[irq]));
+        }
+
+        if (type == 3) {
+            qemu_irq irq = qdev_get_gpio_in(ams->gic,
+                                            ppibase + ARCH_GIC_MAINT_IRQ);
+            qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
+                                        0, irq);
+        }
+
+        qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
+                                    qdev_get_gpio_in(ams->gic, ppibase
+                                                     + VIRTUAL_PMU_IRQ));
+
+        sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
ARM_CPU_IRQ));
+        sysbus_connect_irq(gicbusdev, i + smp_cpus,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+        sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+        sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+    }
+}
+
 static char *virt_get_gic_version(Object *obj, Error **errp)
 {
     ArmMachineState *ams = ARM_MACHINE(obj);
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index b9689b0f0c..f971f49bcf 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -672,103 +672,14 @@ static void set_gic_virt_sysbus(VirtMachineState *vms)
 
 static void create_gic(VirtMachineState *vms)
 {
-    MachineState *ms = MACHINE(vms);
     ArmMachineState *ams = ARM_MACHINE(vms);
-    /* We create a standalone GIC */
-    SysBusDevice *gicbusdev;
-    const char *gictype;
-    int type = ams->gic_version, i;
-    unsigned int smp_cpus = ms->smp.cpus;
-    uint32_t nb_redist_regions = 0;
-
-    gictype = (type == 3) ? gicv3_class_name() : gic_class_name();
-
-    ams->gic = qdev_create(NULL, gictype);
-    qdev_prop_set_uint32(ams->gic, "revision", type);
-    qdev_prop_set_uint32(ams->gic, "num-cpu", smp_cpus);
-    /* Note that the num-irq property counts both internal and external
-     * interrupts; there are always 32 of the former (mandated by GIC spec).
-     */
-    qdev_prop_set_uint32(ams->gic, "num-irq", NUM_IRQS + 32);
 
-    if (type == 3) {
-        uint32_t redist0_capacity =
-                    ams->memmap[VIRT_GIC_REDIST].size / GICV3_REDIST_SIZE;
-        uint32_t redist0_count = MIN(smp_cpus, redist0_capacity);
-
-        nb_redist_regions = virt_gicv3_redist_region_count(ams);
-
-        qdev_prop_set_uint32(ams->gic, "len-redist-region-count",
-                             nb_redist_regions);
-        qdev_prop_set_uint32(ams->gic, "redist-region-count[0]", 
redist0_count);
-
-        if (nb_redist_regions == 2) {
-            uint32_t redist1_capacity =
-                    ams->memmap[VIRT_HIGH_GIC_REDIST2].size / 
GICV3_REDIST_SIZE;
-
-            qdev_prop_set_uint32(ams->gic, "redist-region-count[1]",
-                MIN(smp_cpus - redist0_count, redist1_capacity));
-        }
-    }
+    qdev_create_gic(ams);
     qdev_gic_set_secure_bit(vms);
     qdev_gic_set_virt_bit(vms);
     qdev_init_nofail(ams->gic);
-    gicbusdev = SYS_BUS_DEVICE(ams->gic);
-    sysbus_mmio_map(gicbusdev, 0, ams->memmap[VIRT_GIC_DIST].base);
-    if (type == 3) {
-        sysbus_mmio_map(gicbusdev, 1, ams->memmap[VIRT_GIC_REDIST].base);
-        if (nb_redist_regions == 2) {
-            sysbus_mmio_map(gicbusdev, 2,
-                            ams->memmap[VIRT_HIGH_GIC_REDIST2].base);
-        }
-    } else {
-        sysbus_mmio_map(gicbusdev, 1, ams->memmap[VIRT_GIC_CPU].base);
-    }
-
-    /* Wire the outputs from each CPU's generic timer and the GICv3
-     * maintenance interrupt signal to the appropriate GIC PPI inputs,
-     * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
-     */
-    for (i = 0; i < smp_cpus; i++) {
-        DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
-        int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
-        int irq;
-        /* Mapping from the output timer irq lines from the CPU to the
-         * GIC PPI inputs we use for the virt board.
-         */
-        const int timer_irq[] = {
-            [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
-            [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
-            [GTIMER_HYP]  = ARCH_TIMER_NS_EL2_IRQ,
-            [GTIMER_SEC]  = ARCH_TIMER_S_EL1_IRQ,
-        };
-
-        for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
-            qdev_connect_gpio_out(cpudev, irq,
-                                  qdev_get_gpio_in(ams->gic,
-                                                   ppibase + timer_irq[irq]));
-        }
-
-        if (type == 3) {
-            qemu_irq irq = qdev_get_gpio_in(ams->gic,
-                                            ppibase + ARCH_GIC_MAINT_IRQ);
-            qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
-                                        0, irq);
-        }
-
-        qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
-                                    qdev_get_gpio_in(ams->gic, ppibase
-                                                     + VIRTUAL_PMU_IRQ));
-
-        sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, 
ARM_CPU_IRQ));
-        sysbus_connect_irq(gicbusdev, i + smp_cpus,
-                           qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
-        sysbus_connect_irq(gicbusdev, i + 2 * smp_cpus,
-                           qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
-        sysbus_connect_irq(gicbusdev, i + 3 * smp_cpus,
-                           qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
-    }
 
+    init_gic_sysbus(ams);
     set_gic_virt_sysbus(vms);
     fdt_add_gic_node(vms);
     fdt_gic_set_virt_extension(vms);
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index f8bde03cc3..9ba51c4882 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -108,6 +108,10 @@ typedef struct {
 #define ARM_MACHINE_CLASS(klass) \
     OBJECT_CLASS_CHECK(ArmMachineClass, klass, TYPE_ARM_MACHINE)
 
+void qdev_create_gic(ArmMachineState *ams);
+
+void init_gic_sysbus(ArmMachineState *ams);
+
 /* Return the number of used redistributor regions  */
 static inline int virt_gicv3_redist_region_count(ArmMachineState *ams)
 {
-- 
2.18.1




reply via email to

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