@@ -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)
{
@@ -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")
Optimize loongarch_irq_init function implementation and abstract the function loongarch_cpu_irq_init from it. Cc: "Salil Mehta" <salil.mehta@opnsrc.net> 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(-)