Wire up loongarch_ipi device for loongson3_virt machine, so we can have SMP support for TCG backend as well.
Signed-off-by: Jiaxun Yang <jiaxun.y...@flygoat.com> --- hw/mips/Kconfig | 1 + hw/mips/loongson3_bootp.c | 2 -- hw/mips/loongson3_bootp.h | 3 +++ hw/mips/loongson3_virt.c | 20 ++++++++++++++++++-- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index da3a37e215ec..7cb6c1def16c 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -40,6 +40,7 @@ config LOONGSON3V imply QXL if SPICE select SERIAL select GOLDFISH_RTC + select LOONGARCH_IPI select LOONGSON_LIOINTC select PCI_DEVICES select PCI_EXPRESS_GENERIC_BRIDGE diff --git a/hw/mips/loongson3_bootp.c b/hw/mips/loongson3_bootp.c index f99af229327a..474d3556b2e5 100644 --- a/hw/mips/loongson3_bootp.c +++ b/hw/mips/loongson3_bootp.c @@ -25,8 +25,6 @@ #include "hw/boards.h" #include "hw/mips/loongson3_bootp.h" -#define LOONGSON3_CORE_PER_NODE 4 - static void init_cpu_info(void *g_cpuinfo, uint64_t cpu_freq) { struct efi_cpuinfo_loongson *c = g_cpuinfo; diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h index d525ab745a69..55f98858a5f4 100644 --- a/hw/mips/loongson3_bootp.h +++ b/hw/mips/loongson3_bootp.h @@ -200,6 +200,8 @@ struct boot_params { struct efi_reset_system_t reset_system; }; +#define LOONGSON3_CORE_PER_NODE 4 + /* Overall MMIO & Memory layout */ enum { VIRT_LOWMEM, @@ -211,6 +213,7 @@ enum { VIRT_BIOS_ROM, VIRT_UART, VIRT_LIOINTC, + VIRT_IPI, VIRT_PCIE_MMIO, VIRT_HIGHMEM }; diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c index 25534288dd81..a57245012598 100644 --- a/hw/mips/loongson3_virt.c +++ b/hw/mips/loongson3_virt.c @@ -38,6 +38,7 @@ #include "hw/mips/loongson3_bootp.h" #include "hw/misc/unimp.h" #include "hw/intc/i8259.h" +#include "hw/intc/loongarch_ipi.h" #include "hw/loader.h" #include "hw/isa/superio.h" #include "hw/pci/msi.h" @@ -76,6 +77,7 @@ const MemMapEntry virt_memmap[] = { [VIRT_PCIE_ECAM] = { 0x1a000000, 0x2000000 }, [VIRT_BIOS_ROM] = { 0x1fc00000, 0x200000 }, [VIRT_UART] = { 0x1fe001e0, 0x8 }, + [VIRT_IPI] = { 0x3ff01000, 0x400 }, [VIRT_LIOINTC] = { 0x3ff01400, 0x64 }, [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 }, [VIRT_HIGHMEM] = { 0x80000000, 0x0 }, /* Variable */ @@ -529,6 +531,8 @@ static void mips_loongson3_virt_init(MachineState *machine) clock_set_hz(cpuclk, DEF_LOONGSON3_FREQ); for (i = 0; i < machine->smp.cpus; i++) { + int node = i / LOONGSON3_CORE_PER_NODE; + int core = i % LOONGSON3_CORE_PER_NODE; int ip; /* init CPUs */ @@ -539,12 +543,24 @@ static void mips_loongson3_virt_init(MachineState *machine) cpu_mips_clock_init(cpu); qemu_register_reset(main_cpu_reset, cpu); - if (i >= 4) { + /* IPI controller is in kernel for KVM */ + if (!kvm_enabled()) { + DeviceState *ipi; + + hwaddr base = ((hwaddr)node << 44) + virt_memmap[VIRT_IPI].base; + base += core * 0x100; + ipi = qdev_new(TYPE_LOONGARCH_IPI); + sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); + qdev_connect_gpio_out(ipi, 0, cpu->env.irq[6]); + sysbus_mmio_map(SYS_BUS_DEVICE(ipi), 0, base); + } + + if (node > 0) { continue; /* Only node-0 can be connected to LIOINTC */ } for (ip = 0; ip < 4 ; ip++) { - int pin = i * 4 + ip; + int pin = core * LOONGSON3_CORE_PER_NODE + ip; sysbus_connect_irq(SYS_BUS_DEVICE(liointc), pin, cpu->env.irq[ip + 2]); } -- 2.39.2 (Apple Git-143)