All of lore.kernel.org
 help / color / mirror / Atom feed
From: Xiaojuan Yang <yangxiaojuan@loongson.cn>
To: qemu-devel@nongnu.org
Cc: richard.henderson@linaro.org, gaosong@loongson.cn,
	mark.cave-ayland@ilande.co.uk, mst@redhat.com,
	imammedo@redhat.com, ani@anisinha.ca
Subject: [PATCH v4 31/43] hw/loongarch: Add LoongArch ipi interrupt support(IPI)
Date: Tue, 17 May 2022 19:30:11 +0800	[thread overview]
Message-ID: <20220517113023.3051143-32-yangxiaojuan@loongson.cn> (raw)
In-Reply-To: <20220517113023.3051143-1-yangxiaojuan@loongson.cn>

This patch realize the IPI interrupt controller.

Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 MAINTAINERS                     |   2 +
 hw/intc/Kconfig                 |   3 +
 hw/intc/loongarch_ipi.c         | 237 ++++++++++++++++++++++++++++++++
 hw/intc/meson.build             |   1 +
 hw/intc/trace-events            |   4 +
 hw/loongarch/Kconfig            |   1 +
 include/hw/intc/loongarch_ipi.h |  52 +++++++
 include/hw/loongarch/virt.h     |   2 +
 8 files changed, 302 insertions(+)
 create mode 100644 hw/intc/loongarch_ipi.c
 create mode 100644 include/hw/intc/loongarch_ipi.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 1e49e57367..fbc190e19d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1134,6 +1134,8 @@ F: configs/targets/loongarch64-softmmu.mak
 F: configs/devices/loongarch64-softmmu/default.mak
 F: hw/loongarch/
 F: include/hw/loongarch/virt.h
+F: include/hw/intc/loongarch_*.h
+F: hw/intc/loongarch_*.c
 
 M68K Machines
 -------------
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index eded1b557e..1122c33cec 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -87,3 +87,6 @@ config M68K_IRQC
 
 config NIOS2_VIC
     bool
+
+config LOONGARCH_IPI
+    bool
diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c
new file mode 100644
index 0000000000..86cc6f321c
--- /dev/null
+++ b/hw/intc/loongarch_ipi.c
@@ -0,0 +1,237 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch ipi interrupt support
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/intc/loongarch_ipi.h"
+#include "hw/irq.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "exec/address-spaces.h"
+#include "hw/loongarch/virt.h"
+#include "migration/vmstate.h"
+#include "target/loongarch/internals.h"
+#include "trace.h"
+
+static uint64_t loongarch_ipi_readl(void *opaque, hwaddr addr, unsigned size)
+{
+    IPICore *s = opaque;
+    uint64_t ret = 0;
+    int index = 0;
+
+    addr &= 0xff;
+    switch (addr) {
+    case CORE_STATUS_OFF:
+        ret = s->status;
+        break;
+    case CORE_EN_OFF:
+        ret = s->en;
+        break;
+    case CORE_SET_OFF:
+        ret = 0;
+        break;
+    case CORE_CLEAR_OFF:
+        ret = 0;
+        break;
+    case CORE_BUF_20 ... CORE_BUF_38 + 4:
+        index = (addr - CORE_BUF_20) >> 2;
+        ret = s->buf[index];
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "invalid read: %x", (uint32_t)addr);
+        break;
+    }
+
+    trace_loongarch_ipi_read(size, (uint64_t)addr, ret);
+    return ret;
+}
+
+static int get_ipi_data(target_ulong val)
+{
+    int i, mask, data;
+
+    data = val >> 32;
+    mask = (val >> 27) & 0xf;
+
+    for (i = 0; i < 4; i++) {
+        if ((mask >> i) & 1) {
+            data &= ~(0xff << (i * 8));
+        }
+    }
+    return data;
+}
+
+static void ipi_send(uint64_t val)
+{
+    int cpuid, data;
+    CPULoongArchState *env;
+
+    cpuid = (val >> 16) & 0x3ff;
+    /* IPI status vector */
+    data = 1 << (val & 0x1f);
+    qemu_mutex_lock_iothread();
+    CPUState *cs = qemu_get_cpu(cpuid);
+    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+    env = &cpu->env;
+    loongarch_cpu_set_irq(cpu, IRQ_IPI, 1);
+    qemu_mutex_unlock_iothread();
+    address_space_stl(&env->address_space_iocsr, 0x1008,
+                      data, MEMTXATTRS_UNSPECIFIED, NULL);
+
+}
+
+static void mail_send(uint64_t val)
+{
+    int cpuid, data;
+    hwaddr addr;
+    CPULoongArchState *env;
+
+    cpuid = (val >> 16) & 0x3ff;
+    addr = 0x1020 + (val & 0x1c);
+    CPUState *cs = qemu_get_cpu(cpuid);
+    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+    env = &cpu->env;
+    data = get_ipi_data(val);
+    address_space_stl(&env->address_space_iocsr, addr,
+                      data, MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static void any_send(uint64_t val)
+{
+    int cpuid, data;
+    hwaddr addr;
+    CPULoongArchState *env;
+
+    cpuid = (val >> 16) & 0x3ff;
+    addr = val & 0xffff;
+    CPUState *cs = qemu_get_cpu(cpuid);
+    LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+    env = &cpu->env;
+    data = get_ipi_data(val);
+    address_space_stl(&env->address_space_iocsr, addr,
+                      data, MEMTXATTRS_UNSPECIFIED, NULL);
+}
+
+static void loongarch_ipi_writel(void *opaque, hwaddr addr, uint64_t val,
+                                 unsigned size)
+{
+    IPICore *s = opaque;
+    int index = 0;
+
+    addr &= 0xff;
+    trace_loongarch_ipi_write(size, (uint64_t)addr, val);
+    switch (addr) {
+    case CORE_STATUS_OFF:
+        qemu_log_mask(LOG_GUEST_ERROR, "can not be written");
+        break;
+    case CORE_EN_OFF:
+        s->en = val;
+        break;
+    case CORE_SET_OFF:
+        s->status |= val;
+        if (s->status != 0 && (s->status & s->en) != 0) {
+            qemu_irq_raise(s->irq);
+        }
+        break;
+    case CORE_CLEAR_OFF:
+        s->status &= ~val;
+        if (s->status == 0 && s->en != 0) {
+            qemu_irq_lower(s->irq);
+        }
+        break;
+    case CORE_BUF_20 ... CORE_BUF_38 + 4:
+        index = (addr - CORE_BUF_20) >> 2;
+        s->buf[index] = val;
+        break;
+    case IOCSR_IPI_SEND:
+        ipi_send(val);
+        break;
+    case IOCSR_MAIL_SEND:
+        mail_send(val);
+        break;
+    case IOCSR_ANY_SEND:
+        any_send(val);
+        break;
+    default:
+        qemu_log_mask(LOG_UNIMP, "invalid write: %x", (uint32_t)addr);
+        break;
+    }
+}
+
+static const MemoryRegionOps loongarch_ipi_ops = {
+    .read = loongarch_ipi_readl,
+    .write = loongarch_ipi_writel,
+    .impl.min_access_size = 4,
+    .impl.max_access_size = 4,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 8,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void loongarch_ipi_init(Object *obj)
+{
+    LoongArchIPI *s = LOONGARCH_IPI(obj);
+    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
+    int cpu;
+    LoongArchMachineState *lams = LOONGARCH_MACHINE(qdev_get_machine());
+
+    for (cpu = 0; cpu < MAX_IPI_CORE_NUM; cpu++) {
+        memory_region_init_io(&s->ipi_iocsr_mem[cpu], obj, &loongarch_ipi_ops,
+                            &lams->ipi_core[cpu], "loongarch_ipi_iocsr", 0x100);
+        sysbus_init_mmio(sbd, &s->ipi_iocsr_mem[cpu]);
+
+        qdev_init_gpio_out(DEVICE(obj), &lams->ipi_core[cpu].irq, 1);
+    }
+}
+
+static const VMStateDescription vmstate_ipi_core = {
+    .name = "ipi-single",
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(status, IPICore),
+        VMSTATE_UINT32(en, IPICore),
+        VMSTATE_UINT32(set, IPICore),
+        VMSTATE_UINT32(clear, IPICore),
+        VMSTATE_UINT32_ARRAY(buf, IPICore, MAX_IPI_MBX_NUM * 2),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static const VMStateDescription vmstate_loongarch_ipi = {
+    .name = TYPE_LOONGARCH_IPI,
+    .version_id = 0,
+    .minimum_version_id = 0,
+    .fields = (VMStateField[]) {
+        VMSTATE_STRUCT_ARRAY(ipi_core, LoongArchMachineState,
+                             MAX_IPI_CORE_NUM, 0,
+                             vmstate_ipi_core, IPICore),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void loongarch_ipi_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_loongarch_ipi;
+}
+
+static const TypeInfo loongarch_ipi_info = {
+    .name          = TYPE_LOONGARCH_IPI,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(LoongArchIPI),
+    .instance_init = loongarch_ipi_init,
+    .class_init    = loongarch_ipi_class_init,
+};
+
+static void loongarch_ipi_register_types(void)
+{
+    type_register_static(&loongarch_ipi_info);
+}
+
+type_init(loongarch_ipi_register_types)
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 8b35139f82..57af7fb33f 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -63,3 +63,4 @@ specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_XIVE'],
 specific_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c'))
 specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
 specific_ss.add(when: 'CONFIG_NIOS2_VIC', if_true: files('nios2_vic.c'))
+specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c'))
diff --git a/hw/intc/trace-events b/hw/intc/trace-events
index 5271590304..be8d5b167e 100644
--- a/hw/intc/trace-events
+++ b/hw/intc/trace-events
@@ -287,3 +287,7 @@ sh_intc_register(const char *s, int id, unsigned short v, int c, int m) "%s %u -
 sh_intc_read(unsigned size, uint64_t offset, unsigned long val) "size %u 0x%" PRIx64 " -> 0x%lx"
 sh_intc_write(unsigned size, uint64_t offset, unsigned long val) "size %u 0x%" PRIx64 " <- 0x%lx"
 sh_intc_set(int id, int enable) "setting interrupt group %d to %d"
+
+# loongarch_ipi.c
+loongarch_ipi_read(unsigned size, uint64_t addr, unsigned long val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64
+loongarch_ipi_write(unsigned size, uint64_t addr, unsigned long val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 13e8501897..f0dad3329a 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -2,3 +2,4 @@ config LOONGARCH_VIRT
     bool
     select PCI
     select PCI_EXPRESS_GENERIC_BRIDGE
+    select LOONGARCH_IPI
diff --git a/include/hw/intc/loongarch_ipi.h b/include/hw/intc/loongarch_ipi.h
new file mode 100644
index 0000000000..996ed7ea93
--- /dev/null
+++ b/include/hw/intc/loongarch_ipi.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch ipi interrupt header files
+ *
+ * Copyright (C) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef HW_LOONGARCH_IPI_H
+#define HW_LOONGARCH_IPI_H
+
+#include "hw/sysbus.h"
+
+/* Mainy used by iocsr read and write */
+#define SMP_IPI_MAILBOX      0x1000ULL
+#define CORE_STATUS_OFF       0x0
+#define CORE_EN_OFF           0x4
+#define CORE_SET_OFF          0x8
+#define CORE_CLEAR_OFF        0xc
+#define CORE_BUF_20           0x20
+#define CORE_BUF_28           0x28
+#define CORE_BUF_30           0x30
+#define CORE_BUF_38           0x38
+#define IOCSR_IPI_SEND        0x40
+#define IOCSR_MAIL_SEND       0x48
+#define IOCSR_ANY_SEND        0x158
+
+/* IPI system memory address */
+#define IPI_SYSTEM_MEM        0x1fe01000
+
+#define MAX_IPI_CORE_NUM      4
+#define MAX_IPI_MBX_NUM       4
+
+#define TYPE_LOONGARCH_IPI "loongarch_ipi"
+OBJECT_DECLARE_SIMPLE_TYPE(LoongArchIPI, LOONGARCH_IPI)
+
+typedef struct IPICore {
+    uint32_t status;
+    uint32_t en;
+    uint32_t set;
+    uint32_t clear;
+    /* 64bit buf divide into 2 32bit buf */
+    uint32_t buf[MAX_IPI_MBX_NUM * 2];
+    qemu_irq irq;
+} IPICore;
+
+struct LoongArchIPI {
+    SysBusDevice parent_obj;
+    MemoryRegion ipi_iocsr_mem[MAX_IPI_CORE_NUM];
+    MemoryRegion ipi_system_mem[MAX_IPI_CORE_NUM];
+};
+
+#endif
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 4a4bb3f51f..09a816191c 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -11,6 +11,7 @@
 #include "target/loongarch/cpu.h"
 #include "hw/boards.h"
 #include "qemu/queue.h"
+#include "hw/intc/loongarch_ipi.h"
 
 #define LOONGARCH_MAX_VCPUS     4
 
@@ -21,6 +22,7 @@ struct LoongArchMachineState {
     /*< private >*/
     MachineState parent_obj;
 
+    IPICore ipi_core[MAX_IPI_CORE_NUM];
     MemoryRegion lowmem;
     MemoryRegion highmem;
     MemoryRegion isa_io;
-- 
2.31.1



  parent reply	other threads:[~2022-05-17 12:48 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-17 11:29 [PATCH v4 00/43] Add LoongArch softmmu support Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 01/43] target/loongarch: Add README Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 02/43] target/loongarch: Add core definition Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 03/43] target/loongarch: Add main translation routines Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 04/43] target/loongarch: Add fixed point arithmetic instruction translation Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 05/43] target/loongarch: Add fixed point shift " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 06/43] target/loongarch: Add fixed point bit " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 07/43] target/loongarch: Add fixed point load/store " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 08/43] target/loongarch: Add fixed point atomic " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 09/43] target/loongarch: Add fixed point extra " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 10/43] target/loongarch: Add floating point arithmetic " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 11/43] target/loongarch: Add floating point comparison " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 12/43] target/loongarch: Add floating point conversion " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 13/43] target/loongarch: Add floating point move " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 14/43] target/loongarch: Add floating point load/store " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 15/43] target/loongarch: Add branch " Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 16/43] target/loongarch: Add disassembler Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 17/43] target/loongarch: Add target build suport Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 18/43] target/loongarch: Add system emulation introduction Xiaojuan Yang
2022-05-17 11:29 ` [PATCH v4 19/43] target/loongarch: Add CSRs definition Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 20/43] target/loongarch: Add basic vmstate description of CPU Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 21/43] target/loongarch: Implement qmp_query_cpu_definitions() Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 22/43] target/loongarch: Add MMU support for LoongArch CPU Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 23/43] target/loongarch: Add LoongArch interrupt and exception handle Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 24/43] target/loongarch: Add constant timer support Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 25/43] target/loongarch: Add LoongArch CSR instruction Xiaojuan Yang
2022-05-18 17:18   ` Richard Henderson
2022-05-17 11:30 ` [PATCH v4 26/43] target/loongarch: Add LoongArch IOCSR instruction Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 27/43] target/loongarch: Add TLB instruction support Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 28/43] target/loongarch: Add other core instructions support Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 29/43] target/loongarch: Add timer related " Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 30/43] hw/loongarch: Add support loongson3 virt machine type Xiaojuan Yang
2022-05-17 11:30 ` Xiaojuan Yang [this message]
2022-05-17 11:30 ` [PATCH v4 32/43] hw/intc: Add LoongArch ls7a interrupt controller support(PCH-PIC) Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 33/43] hw/intc: Add LoongArch ls7a msi interrupt controller support(PCH-MSI) Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 34/43] hw/intc: Add LoongArch extioi interrupt controller(EIOINTC) Xiaojuan Yang
2022-05-18 18:04   ` Richard Henderson
2022-05-19  3:03     ` yangxiaojuan
2022-05-17 11:30 ` [PATCH v4 35/43] hw/loongarch: Add irq hierarchy for the system Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 36/43] Enable common virtio pci support for LoongArch Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 37/43] hw/loongarch: Add some devices support for 3A5000 Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 38/43] hw/loongarch: Add LoongArch ls7a rtc device support Xiaojuan Yang
2022-05-18 19:59   ` Richard Henderson
2022-05-19 13:04     ` yangxiaojuan
2022-05-19 15:24       ` Richard Henderson
2022-05-20 10:07         ` yangxiaojuan
2022-05-17 11:30 ` [PATCH v4 39/43] hw/loongarch: Add LoongArch load elf function Xiaojuan Yang
2022-05-18 20:01   ` Richard Henderson
2022-05-17 11:30 ` [PATCH v4 40/43] hw/loongarch: Add LoongArch ls7a acpi device support Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 41/43] target/loongarch: Add gdb support Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 42/43] tests/tcg/loongarch64: Add hello/memory test in loongarch64 system Xiaojuan Yang
2022-05-17 11:30 ` [PATCH v4 43/43] target/loongarch: 'make check-tcg' support Xiaojuan Yang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220517113023.3051143-32-yangxiaojuan@loongson.cn \
    --to=yangxiaojuan@loongson.cn \
    --cc=ani@anisinha.ca \
    --cc=gaosong@loongson.cn \
    --cc=imammedo@redhat.com \
    --cc=mark.cave-ayland@ilande.co.uk \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.