[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 4/7] Optimize loongarch_irq_init function implementation
From: |
xianglai li |
Subject: |
[PATCH v3 4/7] Optimize loongarch_irq_init function implementation |
Date: |
Tue, 26 Sep 2023 17:54:29 +0800 |
Optimize loongarch_irq_init function implementation
and abstract the function loongarch_cpu_irq_init from it.
Cc: "Bernhard Beschow" <shentey@gmail.com>
Cc: "Salil Mehta" <salil.mehta@opnsrc.net>
Cc: "Salil Mehta" <salil.mehta@huawei.com>
Cc: Xiaojuan Yang <yangxiaojuan@loongson.cn>
Cc: Song Gao <gaosong@loongson.cn>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Igor Mammedov <imammedo@redhat.com>
Cc: Ani Sinha <anisinha@redhat.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Richard Henderson <richard.henderson@linaro.org>
Cc: Eduardo Habkost <eduardo@habkost.net>
Cc: Marcel Apfelbaum <marcel.apfelbaum@gmail.com>
Cc: "Philippe Mathieu-Daudé" <philmd@linaro.org>
Cc: Yanan Wang <wangyanan55@huawei.com>
Cc: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: xianglai li <lixianglai@loongson.cn>
---
hw/loongarch/virt.c | 105 ++++++++++++++++++++----------------
include/hw/loongarch/virt.h | 5 +-
2 files changed, 62 insertions(+), 48 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index b8474e7b94..fb06b4ab4e 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -46,6 +46,8 @@
#include "hw/block/flash.h"
#include "qemu/error-report.h"
+static LoongArchCPU *loongarch_cpu_irq_init(MachineState *machine,
+ LoongArchCPU *cpu, Error **errp);
static void virt_flash_create(LoongArchMachineState *lams)
{
@@ -573,16 +575,16 @@ static void loongarch_devices_init(DeviceState *pch_pic,
LoongArchMachineState *
static void loongarch_irq_init(LoongArchMachineState *lams)
{
MachineState *ms = MACHINE(lams);
- DeviceState *pch_pic, *pch_msi, *cpudev;
- DeviceState *ipi, *extioi;
+ DeviceState *pch_pic, *pch_msi;
+ DeviceState *extioi;
SysBusDevice *d;
LoongArchCPU *lacpu;
- CPULoongArchState *env;
CPUState *cpu_state;
- int cpu, pin, i, start, num;
+ int cpu, i, start, num;
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
+ lams->extioi = extioi;
/*
* The connection of interrupts:
@@ -607,44 +609,8 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
*/
for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
cpu_state = qemu_get_cpu(cpu);
- cpudev = DEVICE(cpu_state);
lacpu = LOONGARCH_CPU(cpu_state);
- env = &(lacpu->env);
-
- ipi = qdev_new(TYPE_LOONGARCH_IPI);
- sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
-
- /* connect ipi irq to cpu irq */
- qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI));
- /* IPI iocsr memory region */
- memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
- 0));
- memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
- 1));
- /*
- * extioi iocsr memory region
- * only one extioi is added on loongarch virt machine
- * external device interrupt can only be routed to cpu 0-3
- */
- if (cpu < EXTIOI_CPUS)
- memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
- sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
- cpu));
- env->ipistate = ipi;
- }
-
- /*
- * connect ext irq to the cpu irq
- * cpu_pin[9:2] <= intc_pin[7:0]
- */
- for (cpu = 0; cpu < MIN(ms->smp.cpus, EXTIOI_CPUS); cpu++) {
- cpudev = DEVICE(qemu_get_cpu(cpu));
- for (pin = 0; pin < LS3A_INTC_IP; pin++) {
- qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
- qdev_get_gpio_in(cpudev, pin + 2));
- }
+ loongarch_cpu_irq_init(ms, lacpu, &error_fatal);
}
pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
@@ -927,11 +893,7 @@ static void loongarch_init(MachineState *machine)
}
}
fdt_add_flash_node(lams);
- /* register reset function */
- for (i = 0; i < machine->smp.cpus; i++) {
- lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
- qemu_register_reset(reset_load_elf, lacpu);
- }
+
/* Initialize the IO interrupt subsystem */
loongarch_irq_init(lams);
fdt_add_irqchip_node(lams);
@@ -1091,6 +1053,57 @@ static void virt_mem_plug(HotplugHandler *hotplug_dev,
dev, &error_abort);
}
+static LoongArchCPU *loongarch_cpu_irq_init(MachineState *machine,
+ LoongArchCPU *cpu, Error **errp)
+{
+ LoongArchMachineState *lsms = LOONGARCH_MACHINE(machine);
+ CPUState *cs = CPU(cpu);
+ unsigned int cpu_index = cs->cpu_index;
+ DeviceState *cpudev = DEVICE(cpu);
+ DeviceState *extioi = lsms->extioi;
+ CPULoongArchState *env = &cpu->env;
+ DeviceState *ipi;
+ int pin;
+
+ qemu_register_reset(reset_load_elf, cpu);
+
+ ipi = qdev_new(TYPE_LOONGARCH_IPI);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), errp);
+
+ /* connect ipi irq to cpu irq */
+ qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI));
+ /* IPI iocsr memory region */
+ memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
+ 0));
+ memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
+ 1));
+ /*
+ * extioi iocsr memory region
+ * only one extioi is added on loongarch virt machine
+ * external device interrupt can only be routed to cpu 0-3
+ */
+ if (cpu_index < EXTIOI_CPUS)
+ memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
+ cpu_index));
+ env->ipistate = ipi;
+
+ /*
+ * connect ext irq to the cpu irq
+ * cpu_pin[9:2] <= intc_pin[7:0]
+ */
+ if (cpu_index < EXTIOI_CPUS) {
+ for (pin = 0; pin < LS3A_INTC_IP; pin++) {
+ qdev_connect_gpio_out(extioi, (cpu_index * 8 + pin),
+ qdev_get_gpio_in(cpudev, pin + 2));
+ }
+ }
+
+ return cpu;
+}
+
static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev,
DeviceState *dev, Error **errp)
{
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index f1659655c6..176dc43a93 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -42,7 +42,7 @@ struct LoongArchMachineState {
MemoryRegion bios;
bool bios_loaded;
/* State for other subsystems/APIs: */
- FWCfgState *fw_cfg;
+ FWCfgState *fw_cfg;
Notifier machine_done;
Notifier powerdown_notifier;
OnOffAuto acpi;
@@ -50,9 +50,10 @@ struct LoongArchMachineState {
char *oem_table_id;
DeviceState *acpi_ged;
int fdt_size;
- DeviceState *platform_bus_dev;
+ DeviceState *platform_bus_dev;
PCIBus *pci_bus;
PFlashCFI01 *flash;
+ DeviceState *extioi;
};
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
--
2.39.1
[PATCH v3 5/7] Add basic CPU hot-(un)plug support for Loongarch, xianglai li, 2023/09/26
[PATCH v3 6/7] Add support of *unrealize* for Loongarch cpu, xianglai li, 2023/09/26
[PATCH v3 4/7] Optimize loongarch_irq_init function implementation,
xianglai li <=
[PATCH v3 7/7] Update the ACPI table for the Loongarch CPU, xianglai li, 2023/09/26
[PATCH v3 3/7] Added CPU topology support for Loongarch, xianglai li, 2023/09/26
[PATCH v3 2/7] Update CPUs AML with cpu-(ctrl)dev change, xianglai li, 2023/09/26