loongson3_virt has KVM SMP support in kenrel. This patch adds TCG SMP support by enable IPI controller for machine.
Note that TCG SMP can only support up to 4 CPUs as we didn't implement multi-node support. Signed-off-by: Jiaxun Yang <jiaxun.y...@flygoat.com> --- hw/mips/Kconfig | 1 + hw/mips/loongson3_bootp.h | 1 + hw/mips/loongson3_virt.c | 20 +++++++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/hw/mips/Kconfig b/hw/mips/Kconfig index aadd436bf4..4fb0cc49e8 100644 --- a/hw/mips/Kconfig +++ b/hw/mips/Kconfig @@ -39,6 +39,7 @@ config LOONGSON3V select SERIAL select GOLDFISH_RTC select LOONGSON_LIOINTC + select LOONGSON_IPI if TCG select PCI_DEVICES select PCI_EXPRESS_GENERIC_BRIDGE select MSI_NONBROKEN diff --git a/hw/mips/loongson3_bootp.h b/hw/mips/loongson3_bootp.h index 09f8480abf..4756aa44f6 100644 --- a/hw/mips/loongson3_bootp.h +++ b/hw/mips/loongson3_bootp.h @@ -210,6 +210,7 @@ enum { VIRT_PCIE_ECAM, VIRT_BIOS_ROM, VIRT_UART, + VIRT_IPIS, VIRT_LIOINTC, VIRT_PCIE_MMIO, VIRT_HIGHMEM diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c index d4a82fa536..0684a035b0 100644 --- a/hw/mips/loongson3_virt.c +++ b/hw/mips/loongson3_virt.c @@ -35,6 +35,7 @@ #include "hw/boards.h" #include "hw/char/serial.h" #include "hw/intc/loongson_liointc.h" +#include "hw/intc/loongson_ipi.h" #include "hw/mips/mips.h" #include "hw/mips/cpudevs.h" #include "hw/mips/fw_cfg.h" @@ -59,6 +60,7 @@ #define PM_CNTL_MODE 0x10 +#define LOONGSON_TCG_MAX_VCPUS 4 #define LOONGSON_MAX_VCPUS 16 /* @@ -71,6 +73,7 @@ #define UART_IRQ 0 #define RTC_IRQ 1 #define PCIE_IRQ_BASE 2 +#define IPI_REG_SPACE 0x100 const struct MemmapEntry virt_memmap[] = { [VIRT_LOWMEM] = { 0x00000000, 0x10000000 }, @@ -81,6 +84,7 @@ const struct MemmapEntry virt_memmap[] = { [VIRT_PCIE_ECAM] = { 0x1a000000, 0x2000000 }, [VIRT_BIOS_ROM] = { 0x1fc00000, 0x200000 }, [VIRT_UART] = { 0x1fe001e0, 0x8 }, + [VIRT_IPIS] = { 0x3ff01000, 0x400 }, [VIRT_LIOINTC] = { 0x3ff01400, 0x64 }, [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 }, [VIRT_HIGHMEM] = { 0x80000000, 0x0 }, /* Variable */ @@ -495,6 +499,10 @@ static void mips_loongson3_virt_init(MachineState *machine) error_report("Loongson-3/TCG needs cpu type Loongson-3A1000"); exit(1); } + if (machine->smp.cpus > LOONGSON_TCG_MAX_VCPUS) { + error_report("Loongson-3/TCG supports up to 4 CPUs"); + exit(1); + } } else { if (!machine->cpu_type) { machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A4000"); @@ -545,7 +553,17 @@ static void mips_loongson3_virt_init(MachineState *machine) qemu_register_reset(main_cpu_reset, cpu); if (i >= 4) { - continue; /* Only node-0 can be connected to LIOINTC */ + continue; /* Only node-0 can be connected to LIOINTC and IPI */ + } + + if (!kvm_enabled()) { + /* IPI is handled by kernel for KVM */ + DeviceState *ipi; + ipi = qdev_new(TYPE_LOONGSON_IPI); + sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(ipi), 0, + virt_memmap[VIRT_IPIS].base + IPI_REG_SPACE * i); + sysbus_connect_irq(SYS_BUS_DEVICE(ipi), 0, cpu->env.irq[6]); } for (ip = 0; ip < 4 ; ip++) { -- 2.30.0