This series is an attempt to provide CPU hotplug support on ARM virt platform. This is based on ACPI GED device. We should enable ACPI support, and use vGICv3 and 64bit CPU to support CPU hotplug. Under KVM accel, the KVM vCPUs is pre-created. Besides, vGIC IRIs is pre-created too. However, QEMU vCPU objects are defer-created. Signed-off-by: Keqian Zhu <zhukeqian1@huawei.com>
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
|