[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 2/2] hw/mips/loongson3_virt: Add TCG SMP support
From: |
Jiaxun Yang |
Subject: |
[PATCH v3 2/2] hw/mips/loongson3_virt: Add TCG SMP support |
Date: |
Mon, 18 Jan 2021 09:17:06 +0800 |
loongson3_virt has KVM SMP support in kenrel.
This patch adds TCG SMP support by enable IPI controller
for machine.
Also add definition about IRQs to enhance readability.
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.yang@flygoat.com>
---
hw/mips/loongson3_bootp.h | 1 +
hw/mips/loongson3_virt.c | 41 ++++++++++++++++++++++++++++++++-------
hw/mips/Kconfig | 1 +
3 files changed, 36 insertions(+), 7 deletions(-)
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..0765addb7f 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,7 +60,11 @@
#define PM_CNTL_MODE 0x10
-#define LOONGSON_MAX_VCPUS 16
+#define VCPU_PER_NODE 4
+#define TCG_MAX_NODES 1
+#define KVM_MAX_NODES 4
+#define TCG_MAX_VCPUS (TCG_MAX_NODES * VCPU_PER_NODE)
+#define KVM_MAX_VCPUS (KVM_MAX_NODES * VCPU_PER_NODE)
/*
* Loongson-3's virtual machine BIOS can be obtained here:
@@ -68,9 +73,16 @@
*/
#define LOONGSON3_BIOSNAME "bios_loongson3.bin"
+/* IRQ allocation of CPU IP */
+#define LIOINTC_IP_START 2
+#define LIOINTC_IP_END 5
+#define IPI_IP 6
+
+/* IRQ allcation of LIOINTC */
#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 +93,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 +508,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 > TCG_MAX_VCPUS) {
+ error_report("Loongson-3/TCG supports up to %d CPUs",
TCG_MAX_VCPUS);
+ exit(1);
+ }
} else {
if (!machine->cpu_type) {
machine->cpu_type = MIPS_CPU_TYPE_NAME("Loongson-3A4000");
@@ -544,14 +561,24 @@ static void mips_loongson3_virt_init(MachineState
*machine)
cpu_mips_clock_init(cpu);
qemu_register_reset(main_cpu_reset, cpu);
- if (i >= 4) {
- continue; /* Only node-0 can be connected to LIOINTC */
+ if (i >= VCPU_PER_NODE) {
+ 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[IPI_IP]);
}
- for (ip = 0; ip < 4 ; ip++) {
- int pin = i * 4 + ip;
+ for (ip = LIOINTC_IP_START; ip <= LIOINTC_IP_END ; ip++) {
+ int pin = i * 4 + (ip - LIOINTC_IP_START);
sysbus_connect_irq(SYS_BUS_DEVICE(liointc),
- pin, cpu->env.irq[ip + 2]);
+ pin, cpu->env.irq[ip]);
}
}
env = &MIPS_CPU(first_cpu)->env;
@@ -619,7 +646,7 @@ static void loongson3v_machine_class_init(ObjectClass *oc,
void *data)
mc->desc = "Loongson-3 Virtualization Platform";
mc->init = mips_loongson3_virt_init;
mc->block_default_type = IF_IDE;
- mc->max_cpus = LOONGSON_MAX_VCPUS;
+ mc->max_cpus = KVM_MAX_VCPUS;
mc->default_ram_id = "loongson3.highram";
mc->default_ram_size = 1600 * MiB;
mc->kvm_type = mips_kvm_type;
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
--
2.30.0