* [PULL v2 00/11] loongarch-to-apply queue
@ 2025-09-28 9:23 Song Gao
2025-09-28 9:23 ` [PULL v2 01/11] target/loongarch: move some machine define to virt.h Song Gao
` (11 more replies)
0 siblings, 12 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:23 UTC (permalink / raw)
To: qemu-devel
The following changes since commit d6dfd8d40cebebc3378d379cd28879e0345fbf91:
Merge tag 'pull-target-arm-20250926' of https://gitlab.com/pm215/qemu into staging (2025-09-26 13:27:01 -0700)
are available in the Git repository at:
https://github.com/gaosong715/qemu.git tags/pull-loongarch-20250928
for you to fetch changes up to 7470657ec157d4526752147165b2d368e2c7002e:
hw/loongarch: Implement DINTC plug/unplug interfaces (2025-09-28 17:31:04 +0800)
----------------------------------------------------------------
pull-loongarch-20250928
v2: fix build win64 errors.
----------------------------------------------------------------
Song Gao (11):
target/loongarch: move some machine define to virt.h
hw/loongarch: add virt feature dmsi support
hw/loongarch: add misc register support dmsi
loongarch: add a direct interrupt controller device
target/loongarch: add msg interrupt CSR registers
hw/loongarch: DINTC add a MemoryRegion
hw/loongarch: Implement dintc realize and unrealize
hw/loongarch: Implement dintc set irq
target/loongarch: Add CSR_ESTAT.bit15 and CSR_ECFG.bit15 for msg interrupts.
target/loongarch:Implement csrrd CSR_MSGIR register
hw/loongarch: Implement DINTC plug/unplug interfaces
hw/intc/Kconfig | 3 +
hw/intc/loongarch_dintc.c | 212 +++++++++++++++++++++
hw/intc/meson.build | 1 +
hw/loongarch/Kconfig | 1 +
hw/loongarch/virt.c | 110 ++++++++++-
include/hw/intc/loongarch_dintc.h | 36 ++++
include/hw/loongarch/virt.h | 34 ++++
include/hw/pci-host/ls7a.h | 2 +
target/loongarch/cpu-csr.h | 9 +-
target/loongarch/cpu.c | 29 +++
target/loongarch/cpu.h | 36 ++--
target/loongarch/csr.c | 5 +
target/loongarch/machine.c | 25 ++-
target/loongarch/tcg/csr_helper.c | 21 ++
target/loongarch/tcg/helper.h | 1 +
.../tcg/insn_trans/trans_privileged.c.inc | 1 +
16 files changed, 499 insertions(+), 27 deletions(-)
create mode 100644 hw/intc/loongarch_dintc.c
create mode 100644 include/hw/intc/loongarch_dintc.h
^ permalink raw reply [flat|nested] 14+ messages in thread
* [PULL v2 01/11] target/loongarch: move some machine define to virt.h
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
@ 2025-09-28 9:23 ` Song Gao
2025-09-28 9:23 ` [PULL v2 02/11] hw/loongarch: add virt feature dmsi support Song Gao
` (10 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
move some machine define to virt.h
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-2-gaosong@loongson.cn>
---
include/hw/loongarch/virt.h | 19 +++++++++++++++++++
target/loongarch/cpu.h | 21 ---------------------
2 files changed, 19 insertions(+), 21 deletions(-)
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 602feab0f0..7120b46714 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -13,6 +13,25 @@
#include "hw/block/flash.h"
#include "hw/loongarch/boot.h"
+#define IOCSRF_TEMP 0
+#define IOCSRF_NODECNT 1
+#define IOCSRF_MSI 2
+#define IOCSRF_EXTIOI 3
+#define IOCSRF_CSRIPI 4
+#define IOCSRF_FREQCSR 5
+#define IOCSRF_FREQSCALE 6
+#define IOCSRF_DVFSV1 7
+#define IOCSRF_GMOD 9
+#define IOCSRF_VM 11
+
+#define VERSION_REG 0x0
+#define FEATURE_REG 0x8
+#define VENDOR_REG 0x10
+#define CPUNAME_REG 0x20
+#define MISC_FUNC_REG 0x420
+#define IOCSRM_EXTIOI_EN 48
+#define IOCSRM_EXTIOI_INT_ENCODE 49
+
#define LOONGARCH_MAX_CPUS 256
#define VIRT_FWCFG_BASE 0x1e020000UL
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index c8b96f74dc..8c35bf120a 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -21,27 +21,6 @@
#include "cpu-csr.h"
#include "cpu-qom.h"
-#define IOCSRF_TEMP 0
-#define IOCSRF_NODECNT 1
-#define IOCSRF_MSI 2
-#define IOCSRF_EXTIOI 3
-#define IOCSRF_CSRIPI 4
-#define IOCSRF_FREQCSR 5
-#define IOCSRF_FREQSCALE 6
-#define IOCSRF_DVFSV1 7
-#define IOCSRF_GMOD 9
-#define IOCSRF_VM 11
-
-#define VERSION_REG 0x0
-#define FEATURE_REG 0x8
-#define VENDOR_REG 0x10
-#define CPUNAME_REG 0x20
-#define MISC_FUNC_REG 0x420
-#define IOCSRM_EXTIOI_EN 48
-#define IOCSRM_EXTIOI_INT_ENCODE 49
-
-#define IOCSR_MEM_SIZE 0x428
-
#define FCSR0_M1 0x1f /* FCSR1 mask, Enables */
#define FCSR0_M2 0x1f1f0000 /* FCSR2 mask, Cause and Flags */
#define FCSR0_M3 0x300 /* FCSR3 mask, Round Mode */
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 02/11] hw/loongarch: add virt feature dmsi support
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
2025-09-28 9:23 ` [PULL v2 01/11] target/loongarch: move some machine define to virt.h Song Gao
@ 2025-09-28 9:23 ` Song Gao
2025-09-28 9:24 ` [PULL v2 03/11] hw/loongarch: add misc register support dmsi Song Gao
` (9 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:23 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
dmsi feature is added in LoongArchVirtMachinState, and it is used
to check whether virt machine supports the directy Message-Interrupts.
and by default set dmsi with ON_OFF_AUTO_AUTO.
LoongArchVirtMachineState adds misc_feature and misc_status for misc
features and status. and set the default dintc feature bit.
Msgint feature is added in LoongArchCPU, and it is used to check
whether th cpu supports the Message-Interrupts and by default set
mesgint with ON_OFF_AUTO_AUTO.
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-3-gaosong@loongson.cn>
---
hw/loongarch/virt.c | 50 +++++++++++++++++++++++++++++++++++++
include/hw/loongarch/virt.h | 14 +++++++++++
target/loongarch/cpu.c | 29 +++++++++++++++++++++
target/loongarch/cpu.h | 1 +
4 files changed, 94 insertions(+)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index bd5cff1f1e..256af63d73 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -48,6 +48,30 @@
#include "qemu/error-report.h"
#include "kvm/kvm_loongarch.h"
+static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+ OnOffAuto dmsi = lvms->dmsi;
+
+ visit_type_OnOffAuto(v, name, &dmsi, errp);
+
+}
+static void virt_set_dmsi(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+
+ visit_type_OnOffAuto(v, name, &lvms->dmsi, errp);
+
+ if (lvms->dmsi == ON_OFF_AUTO_OFF) {
+ lvms->misc_feature &= ~BIT(IOCSRF_DMSI);
+ lvms->misc_status &= ~BIT_ULL(IOCSRM_DMSI_EN);
+ } else if (lvms->dmsi == ON_OFF_AUTO_ON) {
+ lvms->misc_feature = BIT(IOCSRF_DMSI);
+ }
+}
+
static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -683,6 +707,25 @@ static void fw_cfg_add_memory(MachineState *ms)
}
}
+static void virt_check_dmsi(MachineState *machine)
+{
+ LoongArchCPU *cpu;
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
+
+ cpu = LOONGARCH_CPU(first_cpu);
+ if (lvms->dmsi == ON_OFF_AUTO_AUTO) {
+ if (cpu->msgint != ON_OFF_AUTO_OFF) {
+ lvms->misc_feature = BIT(IOCSRF_DMSI);
+ }
+ }
+
+ if (lvms->dmsi == ON_OFF_AUTO_ON && cpu->msgint == ON_OFF_AUTO_OFF) {
+ error_report("Fail to enable dmsi , cpu msgint is off "
+ "pleass add cpu feature mesgint=on.");
+ exit(EXIT_FAILURE);
+ }
+}
+
static void virt_init(MachineState *machine)
{
const char *cpu_model = machine->cpu_type;
@@ -717,6 +760,7 @@ static void virt_init(MachineState *machine)
}
qdev_realize_and_unref(DEVICE(cpuobj), NULL, &error_fatal);
}
+ virt_check_dmsi(machine);
fw_cfg_add_memory(machine);
/* Node0 memory */
@@ -847,6 +891,8 @@ static void virt_initfn(Object *obj)
if (tcg_enabled()) {
lvms->veiointc = ON_OFF_AUTO_OFF;
}
+
+ lvms->dmsi = ON_OFF_AUTO_AUTO;
lvms->acpi = ON_OFF_AUTO_AUTO;
lvms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
lvms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
@@ -1241,6 +1287,10 @@ static void virt_class_init(ObjectClass *oc, const void *data)
NULL, NULL);
object_class_property_set_description(oc, "v-eiointc",
"Enable Virt Extend I/O Interrupt Controller.");
+ object_class_property_add(oc, "dmsi", "OnOffAuto",
+ virt_get_dmsi, virt_set_dmsi, NULL, NULL);
+ object_class_property_set_description(oc, "dmsi",
+ "Enable direct Message-interrupts Controller.");
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
#ifdef CONFIG_TPM
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 7120b46714..98e9bf0737 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -23,6 +23,7 @@
#define IOCSRF_DVFSV1 7
#define IOCSRF_GMOD 9
#define IOCSRF_VM 11
+#define IOCSRF_DMSI 15
#define VERSION_REG 0x0
#define FEATURE_REG 0x8
@@ -31,6 +32,7 @@
#define MISC_FUNC_REG 0x420
#define IOCSRM_EXTIOI_EN 48
#define IOCSRM_EXTIOI_INT_ENCODE 49
+#define IOCSRM_DMSI_EN 51
#define LOONGARCH_MAX_CPUS 256
@@ -69,6 +71,7 @@ struct LoongArchVirtMachineState {
Notifier powerdown_notifier;
OnOffAuto acpi;
OnOffAuto veiointc;
+ OnOffAuto dmsi;
char *oem_id;
char *oem_table_id;
DeviceState *acpi_ged;
@@ -84,6 +87,8 @@ struct LoongArchVirtMachineState {
DeviceState *extioi;
struct memmap_entry *memmap_table;
unsigned int memmap_entries;
+ uint64_t misc_feature;
+ uint64_t misc_status;
};
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
@@ -91,6 +96,15 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
void virt_acpi_setup(LoongArchVirtMachineState *lvms);
void virt_fdt_setup(LoongArchVirtMachineState *lvms);
+static inline bool virt_has_dmsi(LoongArchVirtMachineState *lvms)
+{
+ if (!(lvms->misc_feature & BIT(IOCSRF_DMSI))) {
+ return false;
+ }
+
+ return true;
+}
+
static inline bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
{
if (lvms->veiointc == ON_OFF_AUTO_OFF) {
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 55ee317bf2..993602fb8c 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -495,6 +495,25 @@ static void loongarch_set_lasx(Object *obj, bool value, Error **errp)
cpu->env.cpucfg[2] = FIELD_DP32(val, CPUCFG2, LASX, value);
}
+static bool loongarch_get_msgint(Object *obj, Error **errp)
+{
+ return LOONGARCH_CPU(obj)->msgint != ON_OFF_AUTO_OFF;
+}
+
+static void loongarch_set_msgint(Object *obj, bool value, Error **errp)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
+
+ cpu->msgint = value ? ON_OFF_AUTO_ON : ON_OFF_AUTO_OFF;
+
+ if (kvm_enabled()) {
+ /* kvm feature detection in function kvm_arch_init_vcpu */
+ return;
+ }
+
+ cpu->env.cpucfg[1] = FIELD_DP32(cpu->env.cpucfg[1], CPUCFG1, MSG_INT, value);
+}
+
static void loongarch_cpu_post_init(Object *obj)
{
LoongArchCPU *cpu = LOONGARCH_CPU(obj);
@@ -507,6 +526,8 @@ static void loongarch_cpu_post_init(Object *obj)
loongarch_set_lsx);
object_property_add_bool(obj, "lasx", loongarch_get_lasx,
loongarch_set_lasx);
+ object_property_add_bool(obj, "msgint", loongarch_get_msgint,
+ loongarch_set_msgint);
/* lbt is enabled only in kvm mode, not supported in tcg mode */
if (kvm_enabled()) {
kvm_loongarch_cpu_post_init(cpu);
@@ -614,6 +635,7 @@ static void loongarch_la464_initfn(Object *obj)
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_WAYS, 7);
env->CSR_PRCFG3 = FIELD_DP64(env->CSR_PRCFG3, CSR_PRCFG3, STLB_SETS, 8);
+ cpu->msgint = ON_OFF_AUTO_OFF;
loongarch_la464_init_csr(obj);
loongarch_cpu_post_init(obj);
}
@@ -644,12 +666,19 @@ static void loongarch_la132_initfn(Object *obj)
data = FIELD_DP32(data, CPUCFG1, HP, 1);
data = FIELD_DP32(data, CPUCFG1, CRC, 1);
env->cpucfg[1] = data;
+ cpu->msgint = ON_OFF_AUTO_OFF;
}
static void loongarch_max_initfn(Object *obj)
{
+ LoongArchCPU *cpu = LOONGARCH_CPU(obj);
/* '-cpu max' for TCG: we use cpu la464. */
loongarch_la464_initfn(obj);
+
+ if (tcg_enabled()) {
+ cpu->env.cpucfg[1] = FIELD_DP32(cpu->env.cpucfg[1], CPUCFG1, MSG_INT, 1);
+ cpu->msgint = ON_OFF_AUTO_AUTO;
+ }
}
static void loongarch_cpu_reset_hold(Object *obj, ResetType type)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 8c35bf120a..19e00325ca 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -392,6 +392,7 @@ struct ArchCPU {
OnOffAuto pmu;
OnOffAuto lsx;
OnOffAuto lasx;
+ OnOffAuto msgint;
OnOffAuto kvm_pv_ipi;
OnOffAuto kvm_steal_time;
int32_t socket_id; /* socket-id of this CPU */
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 03/11] hw/loongarch: add misc register support dmsi
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
2025-09-28 9:23 ` [PULL v2 01/11] target/loongarch: move some machine define to virt.h Song Gao
2025-09-28 9:23 ` [PULL v2 02/11] hw/loongarch: add virt feature dmsi support Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 9:24 ` [PULL v2 04/11] loongarch: add a direct interrupt controller device Song Gao
` (8 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
Add feature register and misc register for dmsi feature checking and
setting
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-4-gaosong@loongson.cn>
---
hw/loongarch/virt.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 256af63d73..a89d1a1ca1 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -564,6 +564,10 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
return MEMTX_OK;
}
+ if (virt_has_dmsi(lvms) && val & BIT_ULL(IOCSRM_DMSI_EN)) {
+ lvms->misc_status |= BIT_ULL(IOCSRM_DMSI_EN);
+ }
+
features = address_space_ldl(&lvms->as_iocsr,
EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
attrs, NULL);
@@ -599,6 +603,9 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
break;
case FEATURE_REG:
ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI);
+ if (virt_has_dmsi(lvms)) {
+ ret |= BIT(IOCSRF_DMSI);
+ }
if (kvm_enabled()) {
ret |= BIT(IOCSRF_VM);
}
@@ -628,6 +635,10 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) {
ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
}
+ if (virt_has_dmsi(lvms) &&
+ (lvms->misc_status & BIT_ULL(IOCSRM_DMSI_EN))) {
+ ret |= BIT_ULL(IOCSRM_DMSI_EN);
+ }
break;
default:
g_assert_not_reached();
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 04/11] loongarch: add a direct interrupt controller device
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (2 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 03/11] hw/loongarch: add misc register support dmsi Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-10-06 20:59 ` Richard Henderson
2025-09-28 9:24 ` [PULL v2 05/11] target/loongarch: add msg interrupt CSR registers Song Gao
` (7 subsequent siblings)
11 siblings, 1 reply; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
Add Loongarch direct interrupt controller device base Definition.
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-5-gaosong@loongson.cn>
---
hw/intc/Kconfig | 3 ++
hw/intc/loongarch_dintc.c | 68 +++++++++++++++++++++++++++++++
hw/intc/meson.build | 1 +
hw/loongarch/Kconfig | 1 +
include/hw/intc/loongarch_dintc.h | 35 ++++++++++++++++
5 files changed, 108 insertions(+)
create mode 100644 hw/intc/loongarch_dintc.c
create mode 100644 include/hw/intc/loongarch_dintc.h
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 7547528f2c..9f456d7e43 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -109,3 +109,6 @@ config LOONGARCH_PCH_MSI
config LOONGARCH_EXTIOI
bool
+
+config LOONGARCH_DINTC
+ bool
diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c
new file mode 100644
index 0000000000..b2465cb022
--- /dev/null
+++ b/hw/intc/loongarch_dintc.c
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU LoongArch direct interrupt controller.
+ *
+ * Copyright (C) 2025 Loongson Technology Corporation Limited
+ */
+
+#include "qemu/osdep.h"
+#include "hw/sysbus.h"
+#include "hw/irq.h"
+#include "hw/intc/loongarch_pch_msi.h"
+#include "hw/intc/loongarch_pch_pic.h"
+#include "hw/intc/loongarch_dintc.h"
+#include "hw/pci/msi.h"
+#include "hw/misc/unimp.h"
+#include "migration/vmstate.h"
+#include "trace.h"
+#include "hw/qdev-properties.h"
+
+
+static void loongarch_dintc_realize(DeviceState *dev, Error **errp)
+{
+ LoongArchDINTCClass *lac = LOONGARCH_DINTC_GET_CLASS(dev);
+
+ Error *local_err = NULL;
+ lac->parent_realize(dev, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ return;
+}
+
+static void loongarch_dintc_unrealize(DeviceState *dev)
+{
+ return;
+}
+
+static void loongarch_dintc_init(Object *obj)
+{
+ return;
+}
+
+static void loongarch_dintc_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ LoongArchDINTCClass *lac = LOONGARCH_DINTC_CLASS(klass);
+
+ dc->unrealize = loongarch_dintc_unrealize;
+ device_class_set_parent_realize(dc, loongarch_dintc_realize,
+ &lac->parent_realize);
+}
+
+static const TypeInfo loongarch_dintc_info = {
+ .name = TYPE_LOONGARCH_DINTC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(LoongArchDINTCState),
+ .instance_init = loongarch_dintc_init,
+ .class_init = loongarch_dintc_class_init,
+};
+
+static void loongarch_dintc_register_types(void)
+{
+ type_register_static(&loongarch_dintc_info);
+}
+
+type_init(loongarch_dintc_register_types)
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 3efb276b6e..faae20b93d 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -80,3 +80,4 @@ specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_
specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c', 'loongarch_extioi_common.c'))
specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_LOONGARCH_EXTIOI'],
if_true: files('loongarch_extioi_kvm.c'))
+specific_ss.add(when: 'CONFIG_LOONGARCH_DINTC', if_true: files('loongarch_dintc.c'))
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index bb2838b7b5..8024ddf1f3 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -15,6 +15,7 @@ config LOONGARCH_VIRT
select LOONGARCH_PCH_PIC
select LOONGARCH_PCH_MSI
select LOONGARCH_EXTIOI
+ select LOONGARCH_DINTC
select LS7A_RTC
select SMBIOS
select ACPI_CPU_HOTPLUG
diff --git a/include/hw/intc/loongarch_dintc.h b/include/hw/intc/loongarch_dintc.h
new file mode 100644
index 0000000000..aa94cd1003
--- /dev/null
+++ b/include/hw/intc/loongarch_dintc.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch direct interrupt controller definitions
+ *
+ * Copyright (C) 2025 Loongson Technology Corporation Limited
+ */
+
+#include "qom/object.h"
+#include "hw/sysbus.h"
+#include "hw/loongarch/virt.h"
+
+
+#define NR_VECTORS 256
+
+#define TYPE_LOONGARCH_DINTC "loongarch_dintc"
+OBJECT_DECLARE_TYPE(LoongArchDINTCState, LoongArchDINTCClass, LOONGARCH_DINTC)
+
+typedef struct DINTCCore {
+ CPUState *cpu;
+ qemu_irq parent_irq;
+ uint64_t arch_id;
+} DINTCCore;
+
+struct LoongArchDINTCState {
+ SysBusDevice parent_obj;
+ DINTCCore *cpu;
+ uint32_t num_cpu;
+};
+
+struct LoongArchDINTCClass {
+ SysBusDeviceClass parent_class;
+
+ DeviceRealize parent_realize;
+ DeviceUnrealize parent_unrealize;
+};
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 05/11] target/loongarch: add msg interrupt CSR registers
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (3 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 04/11] loongarch: add a direct interrupt controller device Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 9:24 ` [PULL v2 06/11] hw/loongarch: DINTC add a MemoryRegion Song Gao
` (6 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
include CSR_MSGIS0-3, CSR_MSGIR and CSR_MSGIE.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-ID: <20250916122109.749813-6-gaosong@loongson.cn>
---
target/loongarch/cpu-csr.h | 3 +++
target/loongarch/cpu.h | 11 +++++++++++
target/loongarch/machine.c | 25 +++++++++++++++++++++++--
3 files changed, 37 insertions(+), 2 deletions(-)
diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 0834e91f30..4792677086 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -186,6 +186,9 @@ FIELD(CSR_MERRCTL, ISMERR, 0, 1)
#define LOONGARCH_CSR_CTAG 0x98 /* TagLo + TagHi */
+#define LOONGARCH_CSR_MSGIS(N) (0xa0 + N)
+#define LOONGARCH_CSR_MSGIR 0xa4
+
/* Direct map windows CSRs*/
#define LOONGARCH_CSR_DMW(N) (0x180 + N)
FIELD(CSR_DMW, PLV0, 0, 1)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 19e00325ca..78210a46d8 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -233,6 +233,13 @@ FIELD(TLB_MISC, ASID, 1, 10)
FIELD(TLB_MISC, VPPN, 13, 35)
FIELD(TLB_MISC, PS, 48, 6)
+/*Msg interrupt registers */
+#define N_MSGIS 4
+FIELD(CSR_MSGIS, IS, 0, 63)
+FIELD(CSR_MSGIR, INTNUM, 0, 8)
+FIELD(CSR_MSGIR, ACTIVE, 31, 1)
+FIELD(CSR_MSGIE, PT, 0, 8)
+
#define LSX_LEN (128)
#define LASX_LEN (256)
@@ -350,6 +357,10 @@ typedef struct CPUArchState {
uint64_t CSR_DBG;
uint64_t CSR_DERA;
uint64_t CSR_DSAVE;
+ /* Msg interrupt registers */
+ uint64_t CSR_MSGIS[N_MSGIS];
+ uint64_t CSR_MSGIR;
+ uint64_t CSR_MSGIE;
struct {
uint64_t guest_addr;
} stealtime;
diff --git a/target/loongarch/machine.c b/target/loongarch/machine.c
index 4e70f5c879..73190fb367 100644
--- a/target/loongarch/machine.c
+++ b/target/loongarch/machine.c
@@ -45,6 +45,26 @@ static const VMStateDescription vmstate_fpu = {
},
};
+static bool msgint_needed(void *opaque)
+{
+ LoongArchCPU *cpu = opaque;
+
+ return FIELD_EX64(cpu->env.cpucfg[1], CPUCFG1, MSG_INT);
+}
+
+static const VMStateDescription vmstate_msgint = {
+ .name = "cpu/msgint",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = msgint_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, N_MSGIS),
+ VMSTATE_UINT64(env.CSR_MSGIR, LoongArchCPU),
+ VMSTATE_UINT64(env.CSR_MSGIE, LoongArchCPU),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
static const VMStateDescription vmstate_lsxh_reg = {
.name = "lsxh_reg",
.version_id = 1,
@@ -168,8 +188,8 @@ static const VMStateDescription vmstate_tlb = {
/* LoongArch CPU state */
const VMStateDescription vmstate_loongarch_cpu = {
.name = "cpu",
- .version_id = 3,
- .minimum_version_id = 3,
+ .version_id = 4,
+ .minimum_version_id = 4,
.fields = (const VMStateField[]) {
VMSTATE_UINTTL_ARRAY(env.gpr, LoongArchCPU, 32),
VMSTATE_UINTTL(env.pc, LoongArchCPU),
@@ -245,6 +265,7 @@ const VMStateDescription vmstate_loongarch_cpu = {
&vmstate_tlb,
#endif
&vmstate_lbt,
+ &vmstate_msgint,
NULL
}
};
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 06/11] hw/loongarch: DINTC add a MemoryRegion
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (4 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 05/11] target/loongarch: add msg interrupt CSR registers Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 9:24 ` [PULL v2 07/11] hw/loongarch: Implement dintc realize and unrealize Song Gao
` (5 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
the DINTC use [2fe00000-2ff00000) Memory.
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-7-gaosong@loongson.cn>
---
hw/intc/loongarch_dintc.c | 24 +++++++++++++++++++
hw/loongarch/virt.c | 38 ++++++++++++++++++++++++++++++-
include/hw/intc/loongarch_dintc.h | 1 +
include/hw/loongarch/virt.h | 1 +
include/hw/pci-host/ls7a.h | 2 ++
5 files changed, 65 insertions(+), 1 deletion(-)
diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c
index b2465cb022..7173a6aa29 100644
--- a/hw/intc/loongarch_dintc.c
+++ b/hw/intc/loongarch_dintc.c
@@ -17,6 +17,24 @@
#include "trace.h"
#include "hw/qdev-properties.h"
+static uint64_t loongarch_dintc_mem_read(void *opaque,
+ hwaddr addr, unsigned size)
+{
+ return 0;
+}
+
+static void loongarch_dintc_mem_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ return;
+}
+
+
+static const MemoryRegionOps loongarch_dintc_ops = {
+ .read = loongarch_dintc_mem_read,
+ .write = loongarch_dintc_mem_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
static void loongarch_dintc_realize(DeviceState *dev, Error **errp)
{
@@ -39,6 +57,12 @@ static void loongarch_dintc_unrealize(DeviceState *dev)
static void loongarch_dintc_init(Object *obj)
{
+ LoongArchDINTCState *s = LOONGARCH_DINTC(obj);
+ SysBusDevice *shd = SYS_BUS_DEVICE(obj);
+ memory_region_init_io(&s->dintc_mmio, OBJECT(s), &loongarch_dintc_ops,
+ s, TYPE_LOONGARCH_DINTC, VIRT_DINTC_SIZE);
+ sysbus_init_mmio(shd, &s->dintc_mmio);
+ msi_nonbroken = true;
return;
}
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index a89d1a1ca1..a7171a5ecc 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -28,6 +28,7 @@
#include "hw/intc/loongarch_extioi.h"
#include "hw/intc/loongarch_pch_pic.h"
#include "hw/intc/loongarch_pch_msi.h"
+#include "hw/intc/loongarch_dintc.h"
#include "hw/pci-host/ls7a.h"
#include "hw/pci-host/gpex.h"
#include "hw/misc/unimp.h"
@@ -386,7 +387,7 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
static void virt_irq_init(LoongArchVirtMachineState *lvms)
{
DeviceState *pch_pic, *pch_msi;
- DeviceState *ipi, *extioi;
+ DeviceState *ipi, *extioi, *dintc;
SysBusDevice *d;
int i, start, num;
@@ -432,6 +433,33 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
* +--------+ +---------+ +---------+
* | UARTs | | Devices | | Devices |
* +--------+ +---------+ +---------+
+ *
+ *
+ * Advanced Extended IRQ model
+ *
+ * +-----+ +---------------------------------+ +-------+
+ * | IPI | --> | CPUINTC | <-- | Timer |
+ * +-----+ +---------------------------------+ +-------+
+ * ^ ^ ^
+ * | | |
+ * +-------------+ +----------+ +---------+ +-------+
+ * | EIOINTC | | DINTC | | LIOINTC | <-- | UARTs |
+ * +-------------+ +----------+ +---------+ +-------+
+ * ^ ^ ^
+ * | | |
+ * +---------+ +---------+ |
+ * | PCH-PIC | | PCH-MSI | |
+ * +---------+ +---------+ |
+ * ^ ^ ^ |
+ * | | | |
+ * +---------+ +---------+ +---------+
+ * | Devices | | PCH-LPC | | Devices |
+ * +---------+ +---------+ +---------+
+ * ^
+ * |
+ * +---------+
+ * | Devices |
+ * +---------+
*/
/* Create IPI device */
@@ -439,6 +467,14 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
lvms->ipi = ipi;
sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
+ /* Create DINTC device*/
+ if (virt_has_dmsi(lvms)) {
+ dintc = qdev_new(TYPE_LOONGARCH_DINTC);
+ lvms->dintc = dintc;
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dintc), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dintc), 0, VIRT_DINTC_BASE);
+ }
+
/* Create EXTIOI device */
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
lvms->extioi = extioi;
diff --git a/include/hw/intc/loongarch_dintc.h b/include/hw/intc/loongarch_dintc.h
index aa94cd1003..0b0b5347b2 100644
--- a/include/hw/intc/loongarch_dintc.h
+++ b/include/hw/intc/loongarch_dintc.h
@@ -23,6 +23,7 @@ typedef struct DINTCCore {
struct LoongArchDINTCState {
SysBusDevice parent_obj;
+ MemoryRegion dintc_mmio;
DINTCCore *cpu;
uint32_t num_cpu;
};
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 98e9bf0737..cd97bdfb8d 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -89,6 +89,7 @@ struct LoongArchVirtMachineState {
unsigned int memmap_entries;
uint64_t misc_feature;
uint64_t misc_status;
+ DeviceState *dintc;
};
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index 79d4ea8501..bfdbfe3614 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -24,6 +24,8 @@
#define VIRT_PCH_REG_BASE 0x10000000UL
#define VIRT_IOAPIC_REG_BASE (VIRT_PCH_REG_BASE)
#define VIRT_PCH_MSI_ADDR_LOW 0x2FF00000UL
+#define VIRT_DINTC_SIZE 0x100000UL
+#define VIRT_DINTC_BASE 0x2FE00000UL
#define VIRT_PCH_REG_SIZE 0x400
#define VIRT_PCH_MSI_SIZE 0x8
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 07/11] hw/loongarch: Implement dintc realize and unrealize
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (5 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 06/11] hw/loongarch: DINTC add a MemoryRegion Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 9:24 ` [PULL v2 08/11] hw/loongarch: Implement dintc set irq Song Gao
` (4 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
Implement th DINTC realize and unrealize.
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Message-ID: <20250916122109.749813-8-gaosong@loongson.cn>
---
hw/intc/loongarch_dintc.c | 23 ++++++++++++++++++++++-
target/loongarch/cpu.h | 3 ++-
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c
index 7173a6aa29..598c666ec6 100644
--- a/hw/intc/loongarch_dintc.c
+++ b/hw/intc/loongarch_dintc.c
@@ -38,7 +38,12 @@ static const MemoryRegionOps loongarch_dintc_ops = {
static void loongarch_dintc_realize(DeviceState *dev, Error **errp)
{
+ LoongArchDINTCState *s = LOONGARCH_DINTC(dev);
LoongArchDINTCClass *lac = LOONGARCH_DINTC_GET_CLASS(dev);
+ MachineState *machine = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const CPUArchIdList *id_list;
+ int i;
Error *local_err = NULL;
lac->parent_realize(dev, &local_err);
@@ -47,12 +52,28 @@ static void loongarch_dintc_realize(DeviceState *dev, Error **errp)
return;
}
+ assert(mc->possible_cpu_arch_ids);
+ id_list = mc->possible_cpu_arch_ids(machine);
+ s->num_cpu = id_list->len;
+ s->cpu = g_new(DINTCCore, s->num_cpu);
+ if (s->cpu == NULL) {
+ error_setg(errp, "Memory allocation for DINTCCore fail");
+ return;
+ }
+
+ for (i = 0; i < s->num_cpu; i++) {
+ s->cpu[i].arch_id = id_list->cpus[i].arch_id;
+ s->cpu[i].cpu = CPU(id_list->cpus[i].cpu);
+ qdev_init_gpio_out(dev, &s->cpu[i].parent_irq, 1);
+ }
+
return;
}
static void loongarch_dintc_unrealize(DeviceState *dev)
{
- return;
+ LoongArchDINTCState *s = LOONGARCH_DINTC(dev);
+ g_free(s->cpu);
}
static void loongarch_dintc_init(Object *obj)
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 78210a46d8..b8e3b46c3a 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -217,9 +217,10 @@ FIELD(CSR_CRMD, WE, 9, 1)
extern const char * const regnames[32];
extern const char * const fregnames[32];
-#define N_IRQS 13
+#define N_IRQS 15
#define IRQ_TIMER 11
#define IRQ_IPI 12
+#define INT_DMSI 14
#define LOONGARCH_STLB 2048 /* 2048 STLB */
#define LOONGARCH_MTLB 64 /* 64 MTLB */
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 08/11] hw/loongarch: Implement dintc set irq
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (6 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 07/11] hw/loongarch: Implement dintc realize and unrealize Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 9:24 ` [PULL v2 09/11] target/loongarch: Add CSR_ESTAT.bit15 and CSR_ECFG.bit15 for msg interrupts Song Gao
` (3 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
Implement dintc set irq and update CSR_MSGIS.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-ID: <20250916122109.749813-9-gaosong@loongson.cn>
---
hw/intc/loongarch_dintc.c | 32 ++++++++++++++++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c
index 598c666ec6..962fe10bf8 100644
--- a/hw/intc/loongarch_dintc.c
+++ b/hw/intc/loongarch_dintc.c
@@ -16,6 +16,14 @@
#include "migration/vmstate.h"
#include "trace.h"
#include "hw/qdev-properties.h"
+#include "target/loongarch/cpu.h"
+#include "qemu/error-report.h"
+#include "system/hw_accel.h"
+
+/* msg addr field */
+FIELD(MSG_ADDR, IRQ_NUM, 4, 8)
+FIELD(MSG_ADDR, CPU_NUM, 12, 8)
+FIELD(MSG_ADDR, FIX, 28, 12)
static uint64_t loongarch_dintc_mem_read(void *opaque,
hwaddr addr, unsigned size)
@@ -23,13 +31,33 @@ static uint64_t loongarch_dintc_mem_read(void *opaque,
return 0;
}
+static void do_set_vcpu_dintc_irq(CPUState *cs, run_on_cpu_data data)
+{
+ int irq = data.host_int;
+ CPULoongArchState *env;
+
+ env = &LOONGARCH_CPU(cs)->env;
+ cpu_synchronize_state(cs);
+ set_bit(irq, (unsigned long *)&env->CSR_MSGIS);
+}
+
static void loongarch_dintc_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
- return;
+ int irq_num, cpu_num = 0;
+ LoongArchDINTCState *s = LOONGARCH_DINTC(opaque);
+ uint64_t msg_addr = addr + VIRT_DINTC_BASE;
+ CPUState *cs;
+
+ cpu_num = FIELD_EX64(msg_addr, MSG_ADDR, CPU_NUM);
+ cs = cpu_by_arch_id(cpu_num);
+ irq_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_NUM);
+
+ async_run_on_cpu(cs, do_set_vcpu_dintc_irq,
+ RUN_ON_CPU_HOST_INT(irq_num));
+ qemu_set_irq(s->cpu[cpu_num].parent_irq, 1);
}
-
static const MemoryRegionOps loongarch_dintc_ops = {
.read = loongarch_dintc_mem_read,
.write = loongarch_dintc_mem_write,
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 09/11] target/loongarch: Add CSR_ESTAT.bit15 and CSR_ECFG.bit15 for msg interrupts.
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (7 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 08/11] hw/loongarch: Implement dintc set irq Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 9:24 ` [PULL v2 10/11] target/loongarch:Implement csrrd CSR_MSGIR register Song Gao
` (2 subsequent siblings)
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
Add CSR_ESTAT.bit15 and CSR_ECFG.bit15 for DINTC irq.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-ID: <20250916122109.749813-10-gaosong@loongson.cn>
---
target/loongarch/cpu-csr.h | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 4792677086..f296eb8d06 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -34,11 +34,13 @@ FIELD(CSR_MISC, ALCL, 12, 4)
FIELD(CSR_MISC, DWPL, 16, 3)
#define LOONGARCH_CSR_ECFG 0x4 /* Exception config */
-FIELD(CSR_ECFG, LIE, 0, 13)
+FIELD(CSR_ECFG, LIE, 0, 15) /* bit 15 is msg interrupt enabled */
+FIELD(CSR_ECFG, MSGINT, 14, 1)
FIELD(CSR_ECFG, VS, 16, 3)
#define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */
-FIELD(CSR_ESTAT, IS, 0, 13)
+FIELD(CSR_ESTAT, IS, 0, 15) /* bit 15 is msg interrupt enabled */
+FIELD(CSR_ESTAT, MSGINT, 14, 1)
FIELD(CSR_ESTAT, ECODE, 16, 6)
FIELD(CSR_ESTAT, ESUBCODE, 22, 9)
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 10/11] target/loongarch:Implement csrrd CSR_MSGIR register
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (8 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 09/11] target/loongarch: Add CSR_ESTAT.bit15 and CSR_ECFG.bit15 for msg interrupts Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 9:24 ` [PULL v2 11/11] hw/loongarch: Implement DINTC plug/unplug interfaces Song Gao
2025-09-28 19:25 ` [PULL v2 00/11] loongarch-to-apply queue Richard Henderson
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
implement the read-clear feature for CSR_MSGIR register.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-ID: <20250916122109.749813-11-gaosong@loongson.cn>
---
target/loongarch/csr.c | 5 +++++
target/loongarch/tcg/csr_helper.c | 21 +++++++++++++++++++
target/loongarch/tcg/helper.h | 1 +
.../tcg/insn_trans/trans_privileged.c.inc | 1 +
4 files changed, 28 insertions(+)
diff --git a/target/loongarch/csr.c b/target/loongarch/csr.c
index 7ea0a30450..f973780bba 100644
--- a/target/loongarch/csr.c
+++ b/target/loongarch/csr.c
@@ -97,6 +97,11 @@ static CSRInfo csr_info[] = {
CSR_OFF(DBG),
CSR_OFF(DERA),
CSR_OFF(DSAVE),
+ CSR_OFF_ARRAY(MSGIS, 0),
+ CSR_OFF_ARRAY(MSGIS, 1),
+ CSR_OFF_ARRAY(MSGIS, 2),
+ CSR_OFF_ARRAY(MSGIS, 3),
+ CSR_OFF(MSGIR),
};
CSRInfo *get_csr(unsigned int csr_num)
diff --git a/target/loongarch/tcg/csr_helper.c b/target/loongarch/tcg/csr_helper.c
index 0d99e2c92b..7bfe6c6c0c 100644
--- a/target/loongarch/tcg/csr_helper.c
+++ b/target/loongarch/tcg/csr_helper.c
@@ -73,6 +73,27 @@ target_ulong helper_csrrd_tval(CPULoongArchState *env)
return cpu_loongarch_get_constant_timer_ticks(cpu);
}
+target_ulong helper_csrrd_msgir(CPULoongArchState *env)
+{
+ int irq, new;
+
+ irq = find_first_bit((unsigned long *)env->CSR_MSGIS, 256);
+ if (irq < 256) {
+ clear_bit(irq, (unsigned long *)env->CSR_MSGIS);
+ new = find_first_bit((unsigned long *)env->CSR_MSGIS, 256);
+ if (new < 256) {
+ return irq;
+ }
+
+ env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 0);
+ } else {
+ /* bit 31 set 1 for no invalid irq */
+ irq = BIT(31);
+ }
+
+ return irq;
+}
+
target_ulong helper_csrwr_estat(CPULoongArchState *env, target_ulong val)
{
int64_t old_v = env->CSR_ESTAT;
diff --git a/target/loongarch/tcg/helper.h b/target/loongarch/tcg/helper.h
index 1d5cb0198c..db57dbfc16 100644
--- a/target/loongarch/tcg/helper.h
+++ b/target/loongarch/tcg/helper.h
@@ -100,6 +100,7 @@ DEF_HELPER_1(rdtime_d, i64, env)
DEF_HELPER_1(csrrd_pgd, i64, env)
DEF_HELPER_1(csrrd_cpuid, i64, env)
DEF_HELPER_1(csrrd_tval, i64, env)
+DEF_HELPER_1(csrrd_msgir, i64, env)
DEF_HELPER_2(csrwr_stlbps, i64, env, tl)
DEF_HELPER_2(csrwr_estat, i64, env, tl)
DEF_HELPER_2(csrwr_asid, i64, env, tl)
diff --git a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
index 34cfab8879..a407ab51b7 100644
--- a/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
+++ b/target/loongarch/tcg/insn_trans/trans_privileged.c.inc
@@ -83,6 +83,7 @@ void loongarch_csr_translate_init(void)
SET_CSR_FUNC(TCFG, NULL, gen_helper_csrwr_tcfg);
SET_CSR_FUNC(TVAL, gen_helper_csrrd_tval, NULL);
SET_CSR_FUNC(TICLR, NULL, gen_helper_csrwr_ticlr);
+ SET_CSR_FUNC(MSGIR, gen_helper_csrrd_msgir, NULL);
}
#undef SET_CSR_FUNC
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PULL v2 11/11] hw/loongarch: Implement DINTC plug/unplug interfaces
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (9 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 10/11] target/loongarch:Implement csrrd CSR_MSGIR register Song Gao
@ 2025-09-28 9:24 ` Song Gao
2025-09-28 19:25 ` [PULL v2 00/11] loongarch-to-apply queue Richard Henderson
11 siblings, 0 replies; 14+ messages in thread
From: Song Gao @ 2025-09-28 9:24 UTC (permalink / raw)
To: qemu-devel; +Cc: Bibo Mao
when cpu added, connect dintc irq to cpu INT_DMSI irq pin.
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
Signed-off-by: Song Gao <gaosong@loongson.cn>
Message-ID: <20250916122109.749813-12-gaosong@loongson.cn>
---
hw/intc/loongarch_dintc.c | 71 +++++++++++++++++++++++++++++++++++++++
hw/loongarch/virt.c | 11 ++++++
2 files changed, 82 insertions(+)
diff --git a/hw/intc/loongarch_dintc.c b/hw/intc/loongarch_dintc.c
index 962fe10bf8..dc8f7ffdf6 100644
--- a/hw/intc/loongarch_dintc.c
+++ b/hw/intc/loongarch_dintc.c
@@ -115,14 +115,81 @@ static void loongarch_dintc_init(Object *obj)
return;
}
+static DINTCCore *loongarch_dintc_get_cpu(LoongArchDINTCState *s,
+ DeviceState *dev)
+{
+ CPUClass *k = CPU_GET_CLASS(dev);
+ uint64_t arch_id = k->get_arch_id(CPU(dev));
+ int i;
+
+ for (i = 0; i < s->num_cpu; i++) {
+ if (s->cpu[i].arch_id == arch_id) {
+ return &s->cpu[i];
+ }
+ }
+
+ return NULL;
+}
+
+static void loongarch_dintc_cpu_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ LoongArchDINTCState *s = LOONGARCH_DINTC(hotplug_dev);
+ Object *obj = OBJECT(dev);
+ DINTCCore *core;
+ int index;
+
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
+ warn_report("LoongArch DINTC: Invalid %s device type",
+ object_get_typename(obj));
+ return;
+ }
+ core = loongarch_dintc_get_cpu(s, dev);
+ if (!core) {
+ return;
+ }
+
+ core->cpu = CPU(dev);
+ index = core - s->cpu;
+
+ /* connect dintc msg irq to cpu irq */
+ qdev_connect_gpio_out(DEVICE(s), index, qdev_get_gpio_in(dev, INT_DMSI));
+ return;
+}
+
+static void loongarch_dintc_cpu_unplug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ LoongArchDINTCState *s = LOONGARCH_DINTC(hotplug_dev);
+ Object *obj = OBJECT(dev);
+ DINTCCore *core;
+
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
+ warn_report("LoongArch DINTC: Invalid %s device type",
+ object_get_typename(obj));
+ return;
+ }
+
+ core = loongarch_dintc_get_cpu(s, dev);
+
+ if (!core) {
+ return;
+ }
+
+ core->cpu = NULL;
+}
+
static void loongarch_dintc_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
LoongArchDINTCClass *lac = LOONGARCH_DINTC_CLASS(klass);
dc->unrealize = loongarch_dintc_unrealize;
device_class_set_parent_realize(dc, loongarch_dintc_realize,
&lac->parent_realize);
+ hc->plug = loongarch_dintc_cpu_plug;
+ hc->unplug = loongarch_dintc_cpu_unplug;
}
static const TypeInfo loongarch_dintc_info = {
@@ -131,6 +198,10 @@ static const TypeInfo loongarch_dintc_info = {
.instance_size = sizeof(LoongArchDINTCState),
.instance_init = loongarch_dintc_init,
.class_init = loongarch_dintc_class_init,
+ .interfaces = (const InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ },
};
static void loongarch_dintc_register_types(void)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index a7171a5ecc..c1760423ee 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -381,6 +381,10 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
&error_abort);
hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), DEVICE(cs),
&error_abort);
+ if (lvms->dintc) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->dintc), DEVICE(cs),
+ &error_abort);
+ }
}
}
@@ -1103,6 +1107,9 @@ static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
/* Notify ipi and extioi irqchip to remove interrupt routing to CPU */
hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->ipi), dev, &error_abort);
hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->extioi), dev, &error_abort);
+ if (lvms->dintc) {
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->dintc), dev, &error_abort);
+ }
/* Notify acpi ged CPU removed */
hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &error_abort);
@@ -1127,6 +1134,10 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev,
hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), dev, &error_abort);
}
+ if (lvms->dintc) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->dintc), dev, &error_abort);
+ }
+
if (lvms->acpi_ged) {
hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged), dev,
&error_abort);
--
2.47.0
^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PULL v2 00/11] loongarch-to-apply queue
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
` (10 preceding siblings ...)
2025-09-28 9:24 ` [PULL v2 11/11] hw/loongarch: Implement DINTC plug/unplug interfaces Song Gao
@ 2025-09-28 19:25 ` Richard Henderson
11 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2025-09-28 19:25 UTC (permalink / raw)
To: Song Gao, qemu-devel
On 9/28/25 02:23, Song Gao wrote:
> The following changes since commit d6dfd8d40cebebc3378d379cd28879e0345fbf91:
>
> Merge tag 'pull-target-arm-20250926' of https://gitlab.com/pm215/qemu into staging (2025-09-26 13:27:01 -0700)
>
> are available in the Git repository at:
>
> https://github.com/gaosong715/qemu.git tags/pull-loongarch-20250928
>
> for you to fetch changes up to 7470657ec157d4526752147165b2d368e2c7002e:
>
> hw/loongarch: Implement DINTC plug/unplug interfaces (2025-09-28 17:31:04 +0800)
>
> ----------------------------------------------------------------
> pull-loongarch-20250928
>
> v2: fix build win64 errors.
>
> ----------------------------------------------------------------
> Song Gao (11):
> target/loongarch: move some machine define to virt.h
> hw/loongarch: add virt feature dmsi support
> hw/loongarch: add misc register support dmsi
> loongarch: add a direct interrupt controller device
> target/loongarch: add msg interrupt CSR registers
> hw/loongarch: DINTC add a MemoryRegion
> hw/loongarch: Implement dintc realize and unrealize
> hw/loongarch: Implement dintc set irq
> target/loongarch: Add CSR_ESTAT.bit15 and CSR_ECFG.bit15 for msg interrupts.
> target/loongarch:Implement csrrd CSR_MSGIR register
> hw/loongarch: Implement DINTC plug/unplug interfaces
>
> hw/intc/Kconfig | 3 +
> hw/intc/loongarch_dintc.c | 212 +++++++++++++++++++++
> hw/intc/meson.build | 1 +
> hw/loongarch/Kconfig | 1 +
> hw/loongarch/virt.c | 110 ++++++++++-
> include/hw/intc/loongarch_dintc.h | 36 ++++
> include/hw/loongarch/virt.h | 34 ++++
> include/hw/pci-host/ls7a.h | 2 +
> target/loongarch/cpu-csr.h | 9 +-
> target/loongarch/cpu.c | 29 +++
> target/loongarch/cpu.h | 36 ++--
> target/loongarch/csr.c | 5 +
> target/loongarch/machine.c | 25 ++-
> target/loongarch/tcg/csr_helper.c | 21 ++
> target/loongarch/tcg/helper.h | 1 +
> .../tcg/insn_trans/trans_privileged.c.inc | 1 +
> 16 files changed, 499 insertions(+), 27 deletions(-)
> create mode 100644 hw/intc/loongarch_dintc.c
> create mode 100644 include/hw/intc/loongarch_dintc.h
>
>
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PULL v2 04/11] loongarch: add a direct interrupt controller device
2025-09-28 9:24 ` [PULL v2 04/11] loongarch: add a direct interrupt controller device Song Gao
@ 2025-10-06 20:59 ` Richard Henderson
0 siblings, 0 replies; 14+ messages in thread
From: Richard Henderson @ 2025-10-06 20:59 UTC (permalink / raw)
To: Song Gao, qemu-devel; +Cc: Bibo Mao
On 9/28/25 02:24, Song Gao wrote:
> Add Loongarch direct interrupt controller device base Definition.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> Reviewed-by: Bibo Mao <maobibo@loongson.cn>
> Message-ID: <20250916122109.749813-5-gaosong@loongson.cn>
> ---
> hw/intc/Kconfig | 3 ++
> hw/intc/loongarch_dintc.c | 68 +++++++++++++++++++++++++++++++
> hw/intc/meson.build | 1 +
> hw/loongarch/Kconfig | 1 +
> include/hw/intc/loongarch_dintc.h | 35 ++++++++++++++++
> 5 files changed, 108 insertions(+)
> create mode 100644 hw/intc/loongarch_dintc.c
> create mode 100644 include/hw/intc/loongarch_dintc.h
...> +static const TypeInfo loongarch_dintc_info = {
> + .name = TYPE_LOONGARCH_DINTC,
> + .parent = TYPE_SYS_BUS_DEVICE,
> + .instance_size = sizeof(LoongArchDINTCState),
> + .instance_init = loongarch_dintc_init,
> + .class_init = loongarch_dintc_class_init,
> +};
Missing .class_size = sizeof(LoongArchDINTCClass).
This clobbers the malloc arena. Irritatingly, it didn't fail when first merged, but now
it's consistent on Alpine. I'll apply the fix to master to get CI in the green.
r~
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-10-06 21:00 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-28 9:23 [PULL v2 00/11] loongarch-to-apply queue Song Gao
2025-09-28 9:23 ` [PULL v2 01/11] target/loongarch: move some machine define to virt.h Song Gao
2025-09-28 9:23 ` [PULL v2 02/11] hw/loongarch: add virt feature dmsi support Song Gao
2025-09-28 9:24 ` [PULL v2 03/11] hw/loongarch: add misc register support dmsi Song Gao
2025-09-28 9:24 ` [PULL v2 04/11] loongarch: add a direct interrupt controller device Song Gao
2025-10-06 20:59 ` Richard Henderson
2025-09-28 9:24 ` [PULL v2 05/11] target/loongarch: add msg interrupt CSR registers Song Gao
2025-09-28 9:24 ` [PULL v2 06/11] hw/loongarch: DINTC add a MemoryRegion Song Gao
2025-09-28 9:24 ` [PULL v2 07/11] hw/loongarch: Implement dintc realize and unrealize Song Gao
2025-09-28 9:24 ` [PULL v2 08/11] hw/loongarch: Implement dintc set irq Song Gao
2025-09-28 9:24 ` [PULL v2 09/11] target/loongarch: Add CSR_ESTAT.bit15 and CSR_ECFG.bit15 for msg interrupts Song Gao
2025-09-28 9:24 ` [PULL v2 10/11] target/loongarch:Implement csrrd CSR_MSGIR register Song Gao
2025-09-28 9:24 ` [PULL v2 11/11] hw/loongarch: Implement DINTC plug/unplug interfaces Song Gao
2025-09-28 19:25 ` [PULL v2 00/11] loongarch-to-apply queue Richard Henderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).