All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] loongson3_virt TCG SMP support
@ 2021-01-14  1:31 Jiaxun Yang
  2021-01-14  1:31 ` [PATCH v2 1/2] hw/intc: Add Loongson Inter Processor Interrupt controller Jiaxun Yang
  2021-01-14  1:31 ` [PATCH v2 2/2] hw/mips/loongson3_virt: Add TCG SMP support Jiaxun Yang
  0 siblings, 2 replies; 7+ messages in thread
From: Jiaxun Yang @ 2021-01-14  1:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Aleksandar Rikalo, Huacai Chen,
	Philippe Mathieu-Daudé

v2:
 - Use enum instead of define (f4bug)
 - Comment about num mbox (f4bug)
 - Use trace instead of log (f4bug)
 - Correct register size (f4bug)


Jiaxun Yang (2):
  hw/intc: Add Loongson Inter Processor Interrupt controller
  hw/mips/loongson3_virt: Add TCG SMP support

 hw/mips/loongson3_bootp.h      |   1 +
 include/hw/intc/loongson_ipi.h |  20 ++++
 hw/intc/loongson_ipi.c         | 174 +++++++++++++++++++++++++++++++++
 hw/mips/loongson3_virt.c       |  20 +++-
 hw/intc/Kconfig                |   3 +
 hw/intc/meson.build            |   1 +
 hw/intc/trace-events           |   4 +
 hw/mips/Kconfig                |   1 +
 8 files changed, 223 insertions(+), 1 deletion(-)
 create mode 100644 include/hw/intc/loongson_ipi.h
 create mode 100644 hw/intc/loongson_ipi.c

-- 
2.30.0



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2 1/2] hw/intc: Add Loongson Inter Processor Interrupt controller
  2021-01-14  1:31 [PATCH v2 0/2] loongson3_virt TCG SMP support Jiaxun Yang
@ 2021-01-14  1:31 ` Jiaxun Yang
  2021-01-14 15:08   ` Philippe Mathieu-Daudé
  2021-01-14  1:31 ` [PATCH v2 2/2] hw/mips/loongson3_virt: Add TCG SMP support Jiaxun Yang
  1 sibling, 1 reply; 7+ messages in thread
From: Jiaxun Yang @ 2021-01-14  1:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Aleksandar Rikalo, Huacai Chen,
	Philippe Mathieu-Daudé

Loongson IPI controller is a MMIO based simple level triggered
interrupt controller. It will trigger IRQ to it's upstream
processor when set register is written.

It also has 4 64bit mailboxes to pass boot information to
secondary processor.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 include/hw/intc/loongson_ipi.h |  20 ++++
 hw/intc/loongson_ipi.c         | 174 +++++++++++++++++++++++++++++++++
 hw/intc/Kconfig                |   3 +
 hw/intc/meson.build            |   1 +
 hw/intc/trace-events           |   4 +
 5 files changed, 202 insertions(+)
 create mode 100644 include/hw/intc/loongson_ipi.h
 create mode 100644 hw/intc/loongson_ipi.c

diff --git a/include/hw/intc/loongson_ipi.h b/include/hw/intc/loongson_ipi.h
new file mode 100644
index 0000000000..a535c467bf
--- /dev/null
+++ b/include/hw/intc/loongson_ipi.h
@@ -0,0 +1,20 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (c) 2020-2021 Jiaxun Yang <jiaxun.yang@flygoat.com>
+ *
+ */
+
+#ifndef LOONGSON_IPI_H
+#define LOONGSON_IPI_H
+
+#include "qemu/units.h"
+#include "hw/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_LOONGSON_IPI "loongson.ipi"
+#define LOONGSON_IPI(obj) OBJECT_CHECK(struct loongson_ipi, (obj), TYPE_LOONGSON_IPI)
+
+#endif /* LOONGSON_IPI_H */
diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c
new file mode 100644
index 0000000000..cce1da8fb9
--- /dev/null
+++ b/hw/intc/loongson_ipi.c
@@ -0,0 +1,174 @@
+/*
+ * QEMU Loongson Inter Processor Interrupt Controller
+ *
+ * Copyright (c) 2020-2021 Jiaxun Yang <jiaxun.yang@flygoat.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "qemu/module.h"
+#include "qemu/log.h"
+#include "hw/irq.h"
+#include "hw/qdev-properties.h"
+#include "hw/intc/loongson_ipi.h"
+#include "sysemu/reset.h"
+#include "trace.h"
+
+/*
+ * Mailboxes are actually 4 64bit registers but we treat it as 8 32bit
+ * to simplify implementation.
+ */
+#define NUM_MBOX  8
+
+enum {
+    R_ISR = 0,
+    R_IEN = 1,
+    R_SET = 2,
+    R_CLR = 3,
+    /* No register at 0x10~0x20 */
+    R_MBOX0 = 8,
+    R_END = R_MBOX0 + NUM_MBOX
+};
+
+struct loongson_ipi {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+    qemu_irq parent_irq;
+
+    uint32_t isr;
+    uint32_t ien;
+    uint32_t mbox[NUM_MBOX];
+};
+
+static uint64_t
+ipi_read(void *opaque, hwaddr addr, unsigned int size)
+{
+    struct loongson_ipi *p = opaque;
+    uint64_t r = 0;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_ISR:
+        r = p->isr;
+        break;
+    case R_IEN:
+        r = p->ien;
+        break;
+    case R_SET:
+    case R_CLR:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Reading write only reg: 0x%" HWADDR_PRIx "\n",
+                      __func__, addr);
+        break;
+    case R_MBOX0 ... (R_END - 1):
+        r = p->mbox[addr - R_MBOX0];
+        break;
+    default:
+        break;
+    }
+
+    trace_loongson_ipi_read(addr, r);
+
+    return r;
+}
+
+static void
+ipi_write(void *opaque, hwaddr addr,
+          uint64_t val64, unsigned int size)
+{
+    struct loongson_ipi *p = opaque;
+    uint32_t value = val64;
+
+    addr >>= 2;
+    switch (addr) {
+    case R_ISR:
+        /* Do nothing */
+        break;
+    case R_IEN:
+        p->ien = value;
+        break;
+    case R_SET:
+        p->isr |= value;
+        break;
+    case R_CLR:
+        p->isr &= ~value;
+        break;
+    case R_MBOX0 ... (R_END - 1):
+        p->mbox[addr - R_MBOX0] = value;
+        break;
+    default:
+        break;
+    }
+    p->isr &= p->ien;
+
+    trace_loongson_ipi_write(addr, value);
+
+    qemu_set_irq(p->parent_irq, !!p->isr);
+}
+
+static void ipi_reset(void *opaque)
+{
+    int i;
+    struct loongson_ipi *p = opaque;
+
+    p->ien = 0;
+    p->isr = 0;
+    for (i = 0; i < NUM_MBOX; i++) {
+        p->mbox[i] = 0;
+    }
+}
+
+static const MemoryRegionOps pic_mmio_ops = {
+    .read = ipi_read,
+    .write = ipi_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .impl = {
+        .min_access_size = 4,
+        .max_access_size = 4
+    },
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 8
+    },
+};
+
+static void loongson_ipi_init(Object *obj)
+{
+    struct loongson_ipi *p = LOONGSON_IPI(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq);
+
+    memory_region_init_io(&p->mmio, obj, &pic_mmio_ops, p,
+                          "loongson.ipi", R_END * 4);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &p->mmio);
+    qemu_register_reset(ipi_reset, p);
+}
+
+static const TypeInfo loongson_ipi_info = {
+    .name          = TYPE_LOONGSON_IPI,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(struct loongson_ipi),
+    .instance_init = loongson_ipi_init,
+};
+
+static void loongson_ipi_register_types(void)
+{
+    type_register_static(&loongson_ipi_info);
+}
+
+type_init(loongson_ipi_register_types)
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index c18d11142a..0e15102662 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -59,6 +59,9 @@ config RX_ICU
 config LOONGSON_LIOINTC
     bool
 
+config LOONGSON_IPI
+    bool
+
 config SIFIVE_CLINT
     bool
 
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 53cba11569..5257c5fb94 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -36,6 +36,7 @@ specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c'))
 specific_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_plic.c'))
 specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
 specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: files('loongson_liointc.c'))
+specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: files('loongson_ipi.c'))
 specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
 specific_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_intc.c'))
 specific_ss.add(when: 'CONFIG_OMPIC', if_true: files('ompic.c'))
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 8ed397a0d5..e43e318be0 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -60,6 +60,10 @@ lm32_pic_set_ip(uint32_t ip) "ip 0x%08x"
 lm32_pic_get_im(uint32_t im) "im 0x%08x"
 lm32_pic_get_ip(uint32_t ip) "ip 0x%08x"
 
+# loongson_ipi.c
+loongson_ipi_read(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64
+loongson_ipi_write(uint64_t addr, uint64_t value) "addr 0x%02" PRIx64 " value 0x%08" PRIx64
+
 # xics.c
 xics_icp_check_ipi(int server, uint8_t mfrr) "CPU %d can take IPI mfrr=0x%x"
 xics_icp_accept(uint32_t old_xirr, uint32_t new_xirr) "icp_accept: XIRR 0x%"PRIx32"->0x%"PRIx32
-- 
2.30.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v2 2/2] hw/mips/loongson3_virt: Add TCG SMP support
  2021-01-14  1:31 [PATCH v2 0/2] loongson3_virt TCG SMP support Jiaxun Yang
  2021-01-14  1:31 ` [PATCH v2 1/2] hw/intc: Add Loongson Inter Processor Interrupt controller Jiaxun Yang
@ 2021-01-14  1:31 ` Jiaxun Yang
  2021-01-17 22:46   ` Philippe Mathieu-Daudé
  1 sibling, 1 reply; 7+ messages in thread
From: Jiaxun Yang @ 2021-01-14  1:31 UTC (permalink / raw)
  To: qemu-devel
  Cc: Aurelien Jarno, Aleksandar Rikalo, Huacai Chen,
	Philippe Mathieu-Daudé

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.yang@flygoat.com>
---
 hw/mips/loongson3_bootp.h |  1 +
 hw/mips/loongson3_virt.c  | 20 +++++++++++++++++++-
 hw/mips/Kconfig           |  1 +
 3 files changed, 21 insertions(+), 1 deletion(-)

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++) {
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



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] hw/intc: Add Loongson Inter Processor Interrupt controller
  2021-01-14  1:31 ` [PATCH v2 1/2] hw/intc: Add Loongson Inter Processor Interrupt controller Jiaxun Yang
@ 2021-01-14 15:08   ` Philippe Mathieu-Daudé
  2021-01-14 15:21     ` Peter Maydell
  0 siblings, 1 reply; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-14 15:08 UTC (permalink / raw)
  To: Jiaxun Yang, qemu-devel; +Cc: Aleksandar Rikalo, Huacai Chen, Aurelien Jarno

Hi Jiaxun,

On 1/14/21 2:31 AM, Jiaxun Yang wrote:
> Loongson IPI controller is a MMIO based simple level triggered
> interrupt controller. It will trigger IRQ to it's upstream
> processor when set register is written.
> 
> It also has 4 64bit mailboxes to pass boot information to
> secondary processor.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
>  include/hw/intc/loongson_ipi.h |  20 ++++
>  hw/intc/loongson_ipi.c         | 174 +++++++++++++++++++++++++++++++++
>  hw/intc/Kconfig                |   3 +
>  hw/intc/meson.build            |   1 +
>  hw/intc/trace-events           |   4 +
>  5 files changed, 202 insertions(+)
>  create mode 100644 include/hw/intc/loongson_ipi.h
>  create mode 100644 hw/intc/loongson_ipi.c
...

Thanks for addressing v1 comments.

> +static void loongson_ipi_init(Object *obj)
> +{
> +    struct loongson_ipi *p = LOONGSON_IPI(obj);
> +
> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq);
> +
> +    memory_region_init_io(&p->mmio, obj, &pic_mmio_ops, p,
> +                          "loongson.ipi", R_END * 4);
> +    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &p->mmio);
> +    qemu_register_reset(ipi_reset, p);

A SysBusDevice should use DeviceReset. qemu_register_reset()
should be restricted to non-SysBusDevice devices. If there
are no other comments on this series, I can fix this when
applying.

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> +}
> +
> +static const TypeInfo loongson_ipi_info = {
> +    .name          = TYPE_LOONGSON_IPI,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(struct loongson_ipi),
> +    .instance_init = loongson_ipi_init,
> +};


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 1/2] hw/intc: Add Loongson Inter Processor Interrupt controller
  2021-01-14 15:08   ` Philippe Mathieu-Daudé
@ 2021-01-14 15:21     ` Peter Maydell
  0 siblings, 0 replies; 7+ messages in thread
From: Peter Maydell @ 2021-01-14 15:21 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé
  Cc: Aurelien Jarno, Aleksandar Rikalo, Huacai Chen, QEMU Developers

On Thu, 14 Jan 2021 at 15:15, Philippe Mathieu-Daudé <f4bug@amsat.org> wrote:
> A SysBusDevice should use DeviceReset. qemu_register_reset()
> should be restricted to non-SysBusDevice devices. If there
> are no other comments on this series, I can fix this when
> applying.

The device also seems to be missing a vmstate struct.

thanks
-- PMM


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/2] hw/mips/loongson3_virt: Add TCG SMP support
  2021-01-14  1:31 ` [PATCH v2 2/2] hw/mips/loongson3_virt: Add TCG SMP support Jiaxun Yang
@ 2021-01-17 22:46   ` Philippe Mathieu-Daudé
  2021-01-17 22:58     ` Philippe Mathieu-Daudé
  0 siblings, 1 reply; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-17 22:46 UTC (permalink / raw)
  To: Jiaxun Yang, qemu-devel; +Cc: Aleksandar Rikalo, Huacai Chen, Aurelien Jarno

Hi Jiaxun,

On 1/14/21 2:31 AM, Jiaxun Yang wrote:
> 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.yang@flygoat.com>
> ---
>  hw/mips/loongson3_bootp.h |  1 +
>  hw/mips/loongson3_virt.c  | 20 +++++++++++++++++++-
>  hw/mips/Kconfig           |  1 +
>  3 files changed, 21 insertions(+), 1 deletion(-)
> 
> 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

A GS464V node has 4 cores, right? What about:

#define LOONGSON_VCPUS_PER_NODE 4

#define LOONGSON_NODES_MAX_TCG  1
#define LOONGSON_NODES_MAX_KVM  4

>  
>  /*
> @@ -71,6 +73,7 @@
>  #define UART_IRQ            0
>  #define RTC_IRQ             1
>  #define PCIE_IRQ_BASE       2

Can you add a definition for the number 6? Maybe:

   #define IPI_IRQ             6

> +#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]);

While this works, it is very fragile. If multiple IRQs share the same
CPU pin, the better way is to use an OR gate (modeled as TYPE_OR_IRQ
device).

>          }
>  
>          for (ip = 0; ip < 4 ; ip++) {
>              int pin = i * 4 + ip;
>              sysbus_connect_irq(SYS_BUS_DEVICE(liointc),
>                                 pin, cpu->env.irq[ip + 2]);

Oops, we already use it without OR gate :/

Regards,

Phil.


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2 2/2] hw/mips/loongson3_virt: Add TCG SMP support
  2021-01-17 22:46   ` Philippe Mathieu-Daudé
@ 2021-01-17 22:58     ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 7+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-01-17 22:58 UTC (permalink / raw)
  To: Jiaxun Yang, qemu-devel; +Cc: Aleksandar Rikalo, Huacai Chen, Aurelien Jarno

On 1/17/21 11:46 PM, Philippe Mathieu-Daudé wrote:
> Hi Jiaxun,
> 
> On 1/14/21 2:31 AM, Jiaxun Yang wrote:
>> 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.yang@flygoat.com>
>> ---
>>  hw/mips/loongson3_bootp.h |  1 +
>>  hw/mips/loongson3_virt.c  | 20 +++++++++++++++++++-
>>  hw/mips/Kconfig           |  1 +
>>  3 files changed, 21 insertions(+), 1 deletion(-)
...
>> +        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]);
> 
> While this works, it is very fragile. If multiple IRQs share the same
> CPU pin, the better way is to use an OR gate (modeled as TYPE_OR_IRQ
> device).

Doh I misread, I thought it was a signal from a core to the IPI, but
this is a signal from each IPI to its CPU core, so this is good.

> 
>>          }
>>  
>>          for (ip = 0; ip < 4 ; ip++) {
>>              int pin = i * 4 + ip;
>>              sysbus_connect_irq(SYS_BUS_DEVICE(liointc),
>>                                 pin, cpu->env.irq[ip + 2]);
> 
> Oops, we already use it without OR gate :/

Ditto, I misread, code is correct (4 outputs from LIOINTC to
4 input of CPU core).

> 
> Regards,
> 
> Phil.
> 


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-01-17 22:59 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-14  1:31 [PATCH v2 0/2] loongson3_virt TCG SMP support Jiaxun Yang
2021-01-14  1:31 ` [PATCH v2 1/2] hw/intc: Add Loongson Inter Processor Interrupt controller Jiaxun Yang
2021-01-14 15:08   ` Philippe Mathieu-Daudé
2021-01-14 15:21     ` Peter Maydell
2021-01-14  1:31 ` [PATCH v2 2/2] hw/mips/loongson3_virt: Add TCG SMP support Jiaxun Yang
2021-01-17 22:46   ` Philippe Mathieu-Daudé
2021-01-17 22:58     ` Philippe Mathieu-Daudé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.