124 lines
5.1 KiB
Diff
124 lines
5.1 KiB
Diff
|
|
From 92124743f4560c490780a229f53ea5881f706383 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
Date: Sun, 5 Apr 2020 15:29:16 +0800
|
||
|
|
Subject: [PATCH] arm/virt/gic: Construct irqs connection from create_gic
|
||
|
|
|
||
|
|
Make the irqs can be connected to for individual CPU.
|
||
|
|
|
||
|
|
Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
|
||
|
|
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
|
||
|
|
---
|
||
|
|
hw/arm/virt.c | 90 ++++++++++++++++++++++++++++-----------------------
|
||
|
|
1 file changed, 49 insertions(+), 41 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
|
||
|
|
index 83f4887e57..55d403bad6 100644
|
||
|
|
--- a/hw/arm/virt.c
|
||
|
|
+++ b/hw/arm/virt.c
|
||
|
|
@@ -706,6 +706,54 @@ static void create_v2m(VirtMachineState *vms)
|
||
|
|
fdt_add_v2m_gic_node(vms);
|
||
|
|
}
|
||
|
|
|
||
|
|
+static void connect_gic_cpu_irqs(VirtMachineState *vms, int i)
|
||
|
|
+{
|
||
|
|
+ DeviceState *cpudev = DEVICE(qemu_get_cpu(i));
|
||
|
|
+ SysBusDevice *gicbusdev = SYS_BUS_DEVICE(vms->gic);
|
||
|
|
+ int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;
|
||
|
|
+ int num_cpus = object_property_get_uint(OBJECT(vms->gic), "num-cpu", NULL);
|
||
|
|
+ int gic_type = vms->gic_version;
|
||
|
|
+ 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(vms->gic,
|
||
|
|
+ ppibase + timer_irq[irq]));
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ if (gic_type == 3) {
|
||
|
|
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||
|
|
+ ppibase + ARCH_GIC_MAINT_IRQ);
|
||
|
|
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
|
||
|
|
+ 0, irq);
|
||
|
|
+ } else if (vms->virt) {
|
||
|
|
+ qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||
|
|
+ ppibase + ARCH_GIC_MAINT_IRQ);
|
||
|
|
+ sysbus_connect_irq(gicbusdev, i + 4 * num_cpus, irq);
|
||
|
|
+ }
|
||
|
|
+
|
||
|
|
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
|
||
|
|
+ qdev_get_gpio_in(vms->gic, ppibase
|
||
|
|
+ + VIRTUAL_PMU_IRQ));
|
||
|
|
+
|
||
|
|
+ sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
|
||
|
|
+ sysbus_connect_irq(gicbusdev, i + num_cpus,
|
||
|
|
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
|
||
|
|
+ sysbus_connect_irq(gicbusdev, i + 2 * num_cpus,
|
||
|
|
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
|
||
|
|
+ sysbus_connect_irq(gicbusdev, i + 3 * num_cpus,
|
||
|
|
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
|
||
|
|
+}
|
||
|
|
+
|
||
|
|
static void create_gic(VirtMachineState *vms)
|
||
|
|
{
|
||
|
|
MachineState *ms = MACHINE(vms);
|
||
|
|
@@ -775,47 +823,7 @@ static void create_gic(VirtMachineState *vms)
|
||
|
|
* 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(vms->gic,
|
||
|
|
- ppibase + timer_irq[irq]));
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- if (type == 3) {
|
||
|
|
- qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||
|
|
- ppibase + ARCH_GIC_MAINT_IRQ);
|
||
|
|
- qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt",
|
||
|
|
- 0, irq);
|
||
|
|
- } else if (vms->virt) {
|
||
|
|
- qemu_irq irq = qdev_get_gpio_in(vms->gic,
|
||
|
|
- ppibase + ARCH_GIC_MAINT_IRQ);
|
||
|
|
- sysbus_connect_irq(gicbusdev, i + 4 * smp_cpus, irq);
|
||
|
|
- }
|
||
|
|
-
|
||
|
|
- qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
|
||
|
|
- qdev_get_gpio_in(vms->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));
|
||
|
|
+ connect_gic_cpu_irqs(vms, i);
|
||
|
|
}
|
||
|
|
|
||
|
|
fdt_add_gic_node(vms);
|
||
|
|
--
|
||
|
|
2.19.1
|