* [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support
@ 2025-06-19 2:39 Song Gao
2025-06-19 2:39 ` [PATCH v2 1/9] hw/loongarch: move some machine define to virt.h Song Gao
` (8 more replies)
0 siblings, 9 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
ntroduce the advanced extended interrupt controllers (AVECINTC). This
feature will allow each core to have 256 independent interrupt vectors
and MSI interrupts can be independently routed to any vector on any CPU.
The whole topology of irqchips in LoongArch machines looks like this if
AVECINTC is supported:
+-----+ +-----------------------+ +-------+
| IPI | --> | CPUINTC | <-- | Timer |
+-----+ +-----------------------+ +-------+
^ ^ ^
| | |
+---------+ +----------+ +---------+ +-------+
| EIOINTC | | AVECINTC | | LIOINTC | <-- | UARTs |
+---------+ +----------+ +---------+ +-------+
^ ^
| |
+---------+ +---------+
| PCH-PIC | | PCH-MSI |
+---------+ +---------+
^ ^ ^
| | |
+---------+ +---------+ +---------+
| Devices | | PCH-LPC | | Devices |
+---------+ +---------+ +---------+
^
|
+---------+
| Devices |
+---------+
We can see more about AVECINTC on linux driver code[1]
and loongarch msg interrupts on volI 6.2 Message-Interrupts
Tested the code using the virion-net NIC the start scripts is kernel.sh at[3]
[1]: https://github.com/torvalds/linux/blob/master/drivers/irqchip/irq-loongarch-avec.c
[2]: https://github.com/loongson/LoongArch-Documentation/releases/download/2023.04.20/LoongArch-Vol1-v1.10-EN.pdf
[3]: https://github.com/gaosong715/qemu/releases/download/pull-loongarch-20250514/kernel.sh
v2:
1: Use one irqline for avec parent_irq;
2; Correct avec memroy area;
3; Pch-msi not connecet to avec when avec is enabled and drop patch 7;
4: Add misc_feature and misc_status for misc features an misc
fetures status
5: Define CSR_ESTAT and CSR_ECFG bit15 for msg interupt. clean patch9.
6: Fix test demsg error.
Thanks.
Song Gao
Song Gao (9):
hw/loongarch: move some machine define to virt.h
loongarch: add virt feature avecintc support
loongarch: add a advance interrupt controller device
target/loongarch: add msg interrupt CSR registers
hw/loongarch: AVEC controller add a MemoryRegion
hw/loongarch: Implement avec controller imput and output pins
hw/loongarch: Implement avec set_irq
target/loongarch: loongarch CPU supoort avec irqs
target/loongarch: do_interrupt support msg interrupt
hw/intc/Kconfig | 3 +
hw/intc/loongarch_avec.c | 143 +++++++++++++++++++++++++++++++
hw/intc/meson.build | 1 +
hw/loongarch/Kconfig | 1 +
hw/loongarch/virt.c | 89 ++++++++++++++++++-
include/hw/intc/loongarch_avec.h | 36 ++++++++
include/hw/loongarch/virt.h | 36 ++++++++
include/hw/pci-host/ls7a.h | 2 +
target/loongarch/cpu-csr.h | 6 +-
target/loongarch/cpu.c | 17 ++++
target/loongarch/cpu.h | 34 +++-----
target/loongarch/machine.c | 5 ++
12 files changed, 346 insertions(+), 27 deletions(-)
create mode 100644 hw/intc/loongarch_avec.c
create mode 100644 include/hw/intc/loongarch_avec.h
--
2.34.1
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/9] hw/loongarch: move some machine define to virt.h
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-19 2:39 ` [PATCH v2 2/9] loongarch: add virt feature avecintc support Song Gao
` (7 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
move som machine define to virt.h and define avec feature and status bit.
Use the IOCSRF_AVEC bit for avdance interrupt controller drivers
avecintc_enable[1] and set the default value of the MISC_FUNC_REG bit IOCSRM_AVEC_EN.
and set the default value of the MISC_FUNC_REG bit IOCSRM_AVEC_EN.
[1]:https://github.com/torvalds/linux/blob/master/drivers/irqchip/irq-loongarch-avec.c
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/loongarch/virt.c | 4 ++++
include/hw/loongarch/virt.h | 20 ++++++++++++++++++++
target/loongarch/cpu.h | 21 ---------------------
3 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 1b504047db..90d4643721 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -548,6 +548,8 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
break;
case FEATURE_REG:
ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI);
+ /*TODO: check bit IOCSRF_AVEC with virt_is_avec_enabled */
+ ret |= BIT(IOCSRF_AVEC);
if (kvm_enabled()) {
ret |= BIT(IOCSRF_VM);
}
@@ -573,6 +575,8 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) {
ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
}
+ /* enable avec default */
+ ret |= BIT_ULL(IOCSRM_AVEC_EN);
break;
default:
g_assert_not_reached();
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 2b7d19953f..671b47a986 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -13,6 +13,26 @@
#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 IOCSRF_AVEC 15
+
+#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 IOCSRM_AVEC_EN 51
#define LOONGARCH_MAX_CPUS 256
#define VIRT_FWCFG_BASE 0x1e020000UL
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 262bf87f7b..1169768632 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.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 2/9] loongarch: add virt feature avecintc support
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
2025-06-19 2:39 ` [PATCH v2 1/9] hw/loongarch: move some machine define to virt.h Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-19 2:39 ` [PATCH v2 3/9] loongarch: add a advance interrupt controller device Song Gao
` (6 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
LoongArchVirtMachinState add avecintc features, and
it use to check whether virt machine support advance interrupt controller
and default set avecintc = ON_OFF_AUTO_ON.
LoongArchVirtMachineState add misc_feature and misc_status for
misc fetures and status. and set default avec feture bit.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/loongarch/virt.c | 43 +++++++++++++++++++++++++++++++++----
include/hw/loongarch/virt.h | 15 +++++++++++++
2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 90d4643721..3ad165af36 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -47,6 +47,28 @@
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
+static void virt_get_avecintc(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+ OnOffAuto avecintc = lvms->avecintc;
+
+ visit_type_OnOffAuto(v, name, &avecintc, errp);
+
+}
+static void virt_set_avecintc(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
+
+ if (lvms->avecintc == ON_OFF_AUTO_OFF) {
+ lvms->misc_feature &= ~BIT(IOCSRF_AVEC);
+ lvms->misc_status &= ~BIT(IOCSRM_AVEC_EN);
+ }
+
+ visit_type_OnOffAuto(v, name, &lvms->avecintc, errp);
+}
+
static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -523,6 +545,10 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
}
+ if (val & BIT(IOCSRM_AVEC_EN)) {
+ lvms->misc_status |= BIT(IOCSRM_AVEC_EN);
+ }
+
address_space_stl(&lvms->as_iocsr,
EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
features, attrs, NULL);
@@ -548,8 +574,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);
- /*TODO: check bit IOCSRF_AVEC with virt_is_avec_enabled */
- ret |= BIT(IOCSRF_AVEC);
+ if (virt_is_avecintc_enabled(lvms)) {
+ ret |= BIT(IOCSRF_AVEC);
+ }
if (kvm_enabled()) {
ret |= BIT(IOCSRF_VM);
}
@@ -575,8 +602,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);
}
- /* enable avec default */
- ret |= BIT_ULL(IOCSRM_AVEC_EN);
+ if (virt_is_avecintc_enabled(lvms) &&
+ (lvms->misc_status & BIT(IOCSRM_AVEC_EN))) {
+ ret |= BIT_ULL(IOCSRM_AVEC_EN);
+ }
break;
default:
g_assert_not_reached();
@@ -820,6 +849,8 @@ static void virt_initfn(Object *obj)
if (tcg_enabled()) {
lvms->veiointc = ON_OFF_AUTO_OFF;
}
+ lvms->misc_feature = BIT(IOCSRF_AVEC);
+ lvms->avecintc = ON_OFF_AUTO_ON;
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);
@@ -1212,6 +1243,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, "avecintc", "OnOffAuto",
+ virt_get_avecintc, virt_set_avecintc, NULL, NULL);
+ object_class_property_set_description(oc, "avecintc",
+ "Enable Advance Interrupt 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 671b47a986..c594421cd2 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -70,6 +70,7 @@ struct LoongArchVirtMachineState {
Notifier powerdown_notifier;
OnOffAuto acpi;
OnOffAuto veiointc;
+ OnOffAuto avecintc;
char *oem_id;
char *oem_table_id;
DeviceState *acpi_ged;
@@ -83,6 +84,8 @@ struct LoongArchVirtMachineState {
struct loongarch_boot_info bootinfo;
DeviceState *ipi;
DeviceState *extioi;
+ uint64_t misc_feature;
+ uint64_t misc_status;
};
#define TYPE_LOONGARCH_VIRT_MACHINE MACHINE_TYPE_NAME("virt")
@@ -90,6 +93,18 @@ OBJECT_DECLARE_SIMPLE_TYPE(LoongArchVirtMachineState, LOONGARCH_VIRT_MACHINE)
void virt_acpi_setup(LoongArchVirtMachineState *lvms);
void virt_fdt_setup(LoongArchVirtMachineState *lvms);
+static inline bool virt_is_avecintc_enabled(LoongArchVirtMachineState *lvms)
+{
+ if (!(lvms->misc_feature & BIT(IOCSRF_AVEC))) {
+ return false;
+ }
+
+ if (lvms->avecintc == ON_OFF_AUTO_OFF) {
+ return false;
+ }
+ return true;
+}
+
static inline bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
{
if (lvms->veiointc == ON_OFF_AUTO_OFF) {
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 3/9] loongarch: add a advance interrupt controller device
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
2025-06-19 2:39 ` [PATCH v2 1/9] hw/loongarch: move some machine define to virt.h Song Gao
2025-06-19 2:39 ` [PATCH v2 2/9] loongarch: add virt feature avecintc support Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-19 2:39 ` [PATCH v2 4/9] target/loongarch: add msg interrupt CSR registers Song Gao
` (5 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
Add Loongarch advance interrupt controller device base Definition.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/Kconfig | 3 ++
hw/intc/loongarch_avec.c | 68 ++++++++++++++++++++++++++++++++
hw/intc/meson.build | 1 +
hw/loongarch/Kconfig | 1 +
include/hw/intc/loongarch_avec.h | 35 ++++++++++++++++
5 files changed, 108 insertions(+)
create mode 100644 hw/intc/loongarch_avec.c
create mode 100644 include/hw/intc/loongarch_avec.h
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
index 7547528f2c..b9266dc269 100644
--- a/hw/intc/Kconfig
+++ b/hw/intc/Kconfig
@@ -109,3 +109,6 @@ config LOONGARCH_PCH_MSI
config LOONGARCH_EXTIOI
bool
+
+config LOONGARCH_AVEC
+ bool
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
new file mode 100644
index 0000000000..5a3e7ecc03
--- /dev/null
+++ b/hw/intc/loongarch_avec.c
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU Loongson Advance 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_avec.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_avec_realize(DeviceState *dev, Error **errp)
+{
+ LoongArchAVECClass *lac = LOONGARCH_AVEC_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_avec_unrealize(DeviceState *dev)
+{
+ return;
+}
+
+static void loongarch_avec_init(Object *obj)
+{
+ return;
+}
+
+static void loongarch_avec_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ LoongArchAVECClass *lac = LOONGARCH_AVEC_CLASS(klass);
+
+ dc->unrealize = loongarch_avec_unrealize;
+ device_class_set_parent_realize(dc, loongarch_avec_realize,
+ &lac->parent_realize);
+}
+
+static const TypeInfo loongarch_avec_info = {
+ .name = TYPE_LOONGARCH_AVEC,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(LoongArchAVECState),
+ .instance_init = loongarch_avec_init,
+ .class_init = loongarch_avec_class_init,
+};
+
+static void loongarch_avec_register_types(void)
+{
+ type_register_static(&loongarch_avec_info);
+}
+
+type_init(loongarch_avec_register_types)
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
index 602da304b0..6c7c0c6468 100644
--- a/hw/intc/meson.build
+++ b/hw/intc/meson.build
@@ -74,3 +74,4 @@ specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c', 'loongarch_pic_common.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c'))
specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c', 'loongarch_extioi_common.c'))
+specific_ss.add(when: 'CONFIG_LOONGARCH_AVEC', if_true: files('loongarch_avec.c'))
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index bb2838b7b5..1bf240b1e2 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_AVEC
select LS7A_RTC
select SMBIOS
select ACPI_CPU_HOTPLUG
diff --git a/include/hw/intc/loongarch_avec.h b/include/hw/intc/loongarch_avec.h
new file mode 100644
index 0000000000..92e2ca9590
--- /dev/null
+++ b/include/hw/intc/loongarch_avec.h
@@ -0,0 +1,35 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * LoongArch Advance 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_AVEC "loongarch_avec"
+OBJECT_DECLARE_TYPE(LoongArchAVECState, LoongArchAVECClass, LOONGARCH_AVEC)
+
+typedef struct AVECCore {
+ CPUState *cpu;
+ qemu_irq parent_irq;
+ uint64_t arch_id;
+} AVECCore;
+
+struct LoongArchAVECState {
+ SysBusDevice parent_obj;
+ AVECCore *cpu;
+ uint32_t num_cpu;
+};
+
+struct LoongArchAVECClass {
+ SysBusDeviceClass parent_class;
+
+ DeviceRealize parent_realize;
+ DeviceUnrealize parent_unrealize;
+};
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 4/9] target/loongarch: add msg interrupt CSR registers
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (2 preceding siblings ...)
2025-06-19 2:39 ` [PATCH v2 3/9] loongarch: add a advance interrupt controller device Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-20 7:05 ` Bibo Mao
2025-06-19 2:39 ` [PATCH v2 5/9] hw/loongarch: AVEC controller add a MemoryRegion Song Gao
` (4 subsequent siblings)
8 siblings, 1 reply; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
include CSR_MSGIS0-3, CSR_MSGIR and CSR_MSGIE.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
target/loongarch/cpu.c | 7 +++++++
target/loongarch/cpu.h | 10 ++++++++++
target/loongarch/machine.c | 5 +++++
3 files changed, 22 insertions(+)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index abad84c054..bde9f917fc 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -523,6 +523,13 @@ 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);
+ env->CSR_MSGIS[0] = 0;
+ env->CSR_MSGIS[1] = 0;
+ env->CSR_MSGIS[2] = 0;
+ env->CSR_MSGIS[3] = 0;
+ env->CSR_MSGIR = 0;
+ env->CSR_MSGIE = 0;
+
loongarch_la464_init_csr(obj);
loongarch_cpu_post_init(obj);
}
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 1169768632..231ad5a7cb 100644
--- a/target/loongarch/cpu.h
+++ b/target/loongarch/cpu.h
@@ -233,6 +233,12 @@ FIELD(TLB_MISC, ASID, 1, 10)
FIELD(TLB_MISC, VPPN, 13, 35)
FIELD(TLB_MISC, PS, 48, 6)
+/*Msg interrupt registers */
+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 +356,10 @@ typedef struct CPUArchState {
uint64_t CSR_DBG;
uint64_t CSR_DERA;
uint64_t CSR_DSAVE;
+ /* Msg interrupt registers */
+ uint64_t CSR_MSGIS[4];
+ 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..7d5ee34f90 100644
--- a/target/loongarch/machine.c
+++ b/target/loongarch/machine.c
@@ -231,6 +231,11 @@ const VMStateDescription vmstate_loongarch_cpu = {
VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU),
VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
+ /* Msg interrupt CSRs */
+ VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, 4),
+ VMSTATE_UINT64(env.CSR_MSGIR, LoongArchCPU),
+ VMSTATE_UINT64(env.CSR_MSGIE, LoongArchCPU),
+
VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
/* PV steal time */
VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU),
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 5/9] hw/loongarch: AVEC controller add a MemoryRegion
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (3 preceding siblings ...)
2025-06-19 2:39 ` [PATCH v2 4/9] target/loongarch: add msg interrupt CSR registers Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-19 2:39 ` [PATCH v2 6/9] hw/loongarch: Implement avec controller imput and output pins Song Gao
` (3 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
the AVEC controller use [2fe00000-2ff000000) Memory.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_avec.c | 25 ++++++++++++++++++++
hw/loongarch/virt.c | 39 +++++++++++++++++++++++++++++++-
include/hw/intc/loongarch_avec.h | 1 +
include/hw/loongarch/virt.h | 1 +
include/hw/pci-host/ls7a.h | 2 ++
5 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 5a3e7ecc03..4bd431220a 100644
--- a/hw/intc/loongarch_avec.c
+++ b/hw/intc/loongarch_avec.c
@@ -17,6 +17,24 @@
#include "trace.h"
#include "hw/qdev-properties.h"
+static uint64_t loongarch_avec_mem_read(void *opaque,
+ hwaddr addr, unsigned size)
+{
+ return 0;
+}
+
+static void loongarch_avec_mem_write(void *opaque, hwaddr addr,
+ uint64_t val, unsigned size)
+{
+ return;
+}
+
+
+static const MemoryRegionOps loongarch_avec_ops = {
+ .read = loongarch_avec_mem_read,
+ .write = loongarch_avec_mem_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+};
static void loongarch_avec_realize(DeviceState *dev, Error **errp)
{
@@ -39,6 +57,13 @@ static void loongarch_avec_unrealize(DeviceState *dev)
static void loongarch_avec_init(Object *obj)
{
+ LoongArchAVECState *s = LOONGARCH_AVEC(obj);
+ SysBusDevice *shd = SYS_BUS_DEVICE(obj);
+ memory_region_init_io(&s->avec_mmio, OBJECT(s), &loongarch_avec_ops,
+ s, TYPE_LOONGARCH_AVEC, VIRT_AVEC_MSG_OFFSET);
+ sysbus_init_mmio(shd, &s->avec_mmio);
+ msi_nonbroken = true;
+
return;
}
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 3ad165af36..664705ce6e 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_avec.h"
#include "hw/pci-host/ls7a.h"
#include "hw/pci-host/gpex.h"
#include "hw/misc/unimp.h"
@@ -370,7 +371,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, *avec;
SysBusDevice *d;
int i, start, num;
@@ -416,6 +417,33 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
* +--------+ +---------+ +---------+
* | UARTs | | Devices | | Devices |
* +--------+ +---------+ +---------+
+ *
+ *
+ * Advanced Extended IRQ model
+ *
+ * +-----+ +-----------------------+ +-------+
+ * | IPI | --> | CPUINTC | <-- | Timer |
+ * +-----+ +-----------------------+ +-------+
+ * ^ ^ ^
+ * | | |
+ * +---------+ +----------+ +---------+ +-------+
+ * | EIOINTC | | AVECINTC | | LIOINTC | <-- | UARTs |
+ * +---------+ +----------+ +---------+ +-------+
+ * ^ ^
+ * | |
+ * +---------+ +---------+
+ * | PCH-PIC | | PCH-MSI |
+ * +---------+ +---------+
+ * ^ ^ ^
+ * | | |
+ * +---------+ +---------+ +---------+
+ * | Devices | | PCH-LPC | | Devices |
+ * +---------+ +---------+ +---------+
+ * ^
+ * |
+ * +---------+
+ * | Devices |
+ * +---------+
*/
/* Create IPI device */
@@ -429,6 +457,15 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
+ /* Create AVEC device*/
+ if (virt_is_avecintc_enabled(lvms)) {
+ avec = qdev_new(TYPE_LOONGARCH_AVEC);
+ lvms->avec = avec;
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(avec), &error_fatal);
+ memory_region_add_subregion(get_system_memory(), VIRT_AVEC_BASE,
+ sysbus_mmio_get_region(SYS_BUS_DEVICE(avec), 0));
+ }
+
/* Create EXTIOI device */
extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
lvms->extioi = extioi;
diff --git a/include/hw/intc/loongarch_avec.h b/include/hw/intc/loongarch_avec.h
index 92e2ca9590..3e8cf7d2c1 100644
--- a/include/hw/intc/loongarch_avec.h
+++ b/include/hw/intc/loongarch_avec.h
@@ -23,6 +23,7 @@ typedef struct AVECCore {
struct LoongArchAVECState {
SysBusDevice parent_obj;
+ MemoryRegion avec_mmio;
AVECCore *cpu;
uint32_t num_cpu;
};
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index c594421cd2..8811418b96 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -86,6 +86,7 @@ struct LoongArchVirtMachineState {
DeviceState *extioi;
uint64_t misc_feature;
uint64_t misc_status;
+ DeviceState *avec;
};
#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..17f047c188 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_AVEC_MSG_OFFSET 0x1000000
+#define VIRT_AVEC_BASE (VIRT_PCH_MSI_ADDR_LOW - VIRT_AVEC_MSG_OFFSET)
#define VIRT_PCH_REG_SIZE 0x400
#define VIRT_PCH_MSI_SIZE 0x8
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 6/9] hw/loongarch: Implement avec controller imput and output pins
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (4 preceding siblings ...)
2025-06-19 2:39 ` [PATCH v2 5/9] hw/loongarch: AVEC controller add a MemoryRegion Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-19 2:39 ` [PATCH v2 7/9] hw/loongarch: Implement avec set irq Song Gao
` (2 subsequent siblings)
8 siblings, 0 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
the AVEC controller supports 256*256 irqs input, all the irqs connect CPU INT_AVEC irq
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_avec.c | 21 +++++++++++++++++++++
hw/loongarch/virt.c | 11 +++++++++--
target/loongarch/cpu.h | 3 ++-
3 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 4bd431220a..7dd8bac696 100644
--- a/hw/intc/loongarch_avec.c
+++ b/hw/intc/loongarch_avec.c
@@ -38,7 +38,12 @@ static const MemoryRegionOps loongarch_avec_ops = {
static void loongarch_avec_realize(DeviceState *dev, Error **errp)
{
+ LoongArchAVECState *s = LOONGARCH_AVEC(dev);
LoongArchAVECClass *lac = LOONGARCH_AVEC_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,6 +52,22 @@ static void loongarch_avec_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(AVECCore, s->num_cpu);
+ if (s->cpu == NULL) {
+ error_setg(errp, "Memory allocation for AVECCore 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);
+ }
+ qdev_init_gpio_in(dev, NULL, NR_VECTORS * s->num_cpu);
+
return;
}
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 664705ce6e..18ff41f2ad 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -368,7 +368,7 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
}
}
-static void virt_irq_init(LoongArchVirtMachineState *lvms)
+static void virt_irq_init(LoongArchVirtMachineState *lvms, MachineState *ms)
{
DeviceState *pch_pic, *pch_msi;
DeviceState *ipi, *extioi, *avec;
@@ -464,6 +464,13 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
sysbus_realize_and_unref(SYS_BUS_DEVICE(avec), &error_fatal);
memory_region_add_subregion(get_system_memory(), VIRT_AVEC_BASE,
sysbus_mmio_get_region(SYS_BUS_DEVICE(avec), 0));
+ CPUState *cpu_state;
+ DeviceState *cpudev;
+ for (int cpu = 0; cpu < ms->smp.cpus; cpu++) {
+ cpu_state = qemu_get_cpu(cpu);
+ cpudev = DEVICE(cpu_state);
+ qdev_connect_gpio_out(avec, cpu, qdev_get_gpio_in(cpudev, INT_AVEC));
+ }
}
/* Create EXTIOI device */
@@ -809,7 +816,7 @@ static void virt_init(MachineState *machine)
}
/* Initialize the IO interrupt subsystem */
- virt_irq_init(lvms);
+ virt_irq_init(lvms, machine);
lvms->machine_done.notify = virt_done;
qemu_add_machine_init_done_notifier(&lvms->machine_done);
/* connect powerdown request */
diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
index 231ad5a7cb..d5e64c5e8e 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_AVEC 14
#define LOONGARCH_STLB 2048 /* 2048 STLB */
#define LOONGARCH_MTLB 64 /* 64 MTLB */
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 7/9] hw/loongarch: Implement avec set irq
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (5 preceding siblings ...)
2025-06-19 2:39 ` [PATCH v2 6/9] hw/loongarch: Implement avec controller imput and output pins Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-20 7:30 ` Bibo Mao
2025-06-19 2:39 ` [PATCH v2 8/9] target/loongarch: CSR_ESTAT enable msg interrupts Song Gao
2025-06-19 2:39 ` [PATCH v2 9/9] target/loongarch: CSR_ECFG enable msg interrupt Song Gao
8 siblings, 1 reply; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
Implement avec set irq and update CSR_MSIS and CSR_MSGIR.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_avec.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 7dd8bac696..bbd1b48c7d 100644
--- a/hw/intc/loongarch_avec.c
+++ b/hw/intc/loongarch_avec.c
@@ -16,6 +16,12 @@
#include "migration/vmstate.h"
#include "trace.h"
#include "hw/qdev-properties.h"
+#include "target/loongarch/cpu.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_avec_mem_read(void *opaque,
hwaddr addr, unsigned size)
@@ -23,12 +29,33 @@ static uint64_t loongarch_avec_mem_read(void *opaque,
return 0;
}
+static void avec_set_irq(LoongArchAVECState *s, int cpu_num, int irq_num, int level)
+{
+ MachineState *machine = MACHINE(qdev_get_machine());
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
+ const CPUArchIdList *id_list = NULL;
+ assert(mc->possible_cpu_arch_ids(machine));
+ id_list = mc->possible_cpu_arch_ids(machine);
+ CPUState *cpu = id_list->cpus[cpu_num].cpu;
+ CPULoongArchState *env = &LOONGARCH_CPU(cpu)->env;
+
+ set_bit(irq_num, &env->CSR_MSGIS[irq_num / 64]);
+ qemu_set_irq(s->cpu[cpu_num].parent_irq, 1);
+ env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, INTNUM, irq_num);
+ env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, ACTIVE, 0);
+}
+
static void loongarch_avec_mem_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
- return;
-}
+ int irq_num, cpu_num = 0;
+ LoongArchAVECState *s = LOONGARCH_AVEC(opaque);
+ uint64_t msg_addr = addr + VIRT_AVEC_BASE;
+ cpu_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_NUM);
+ irq_num = FIELD_EX64(msg_addr, MSG_ADDR, CPU_NUM);
+ avec_set_irq(s, cpu_num, irq_num, 1);
+}
static const MemoryRegionOps loongarch_avec_ops = {
.read = loongarch_avec_mem_read,
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 8/9] target/loongarch: CSR_ESTAT enable msg interrupts.
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (6 preceding siblings ...)
2025-06-19 2:39 ` [PATCH v2 7/9] hw/loongarch: Implement avec set irq Song Gao
@ 2025-06-19 2:39 ` Song Gao
2025-06-19 2:39 ` [PATCH v2 9/9] target/loongarch: CSR_ECFG enable msg interrupt Song Gao
8 siblings, 0 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
when loongarch cpu set irq is INT_AVEC, we need set CSR_ESTAT.MSGINT bit.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
target/loongarch/cpu-csr.h | 1 +
target/loongarch/cpu.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 0834e91f30..83f6cb081a 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -39,6 +39,7 @@ FIELD(CSR_ECFG, VS, 16, 3)
#define LOONGARCH_CSR_ESTAT 0x5 /* Exception status */
FIELD(CSR_ESTAT, IS, 0, 13)
+FIELD(CSR_ESTAT, MSGINT, 14, 1)
FIELD(CSR_ESTAT, ECODE, 16, 6)
FIELD(CSR_ESTAT, ESUBCODE, 22, 9)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index bde9f917fc..28b23743f9 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -127,6 +127,15 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
return;
}
+ /* do INTC_AVEC irqs */
+ if (irq == INT_AVEC) {
+ for (int i = 256; i >= 0; i--) {
+ if (test_bit(i, &(env->CSR_MSGIS[i / 64]))) {
+ env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 1);
+ }
+ }
+ }
+
if (kvm_enabled()) {
kvm_loongarch_set_interrupt(cpu, irq, level);
} else if (tcg_enabled()) {
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v2 9/9] target/loongarch: CSR_ECFG enable msg interrupt
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (7 preceding siblings ...)
2025-06-19 2:39 ` [PATCH v2 8/9] target/loongarch: CSR_ESTAT enable msg interrupts Song Gao
@ 2025-06-19 2:39 ` Song Gao
8 siblings, 0 replies; 13+ messages in thread
From: Song Gao @ 2025-06-19 2:39 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
when loongarch cpu set irq is INT_AVEC, we need set CSR_ECFG MSGINT bit.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
target/loongarch/cpu-csr.h | 5 +++--
target/loongarch/cpu.c | 1 +
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 83f6cb081a..b1e251a72b 100644
--- a/target/loongarch/cpu-csr.h
+++ b/target/loongarch/cpu-csr.h
@@ -34,11 +34,12 @@ 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)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index 28b23743f9..c5924bb94f 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -132,6 +132,7 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
for (int i = 256; i >= 0; i--) {
if (test_bit(i, &(env->CSR_MSGIS[i / 64]))) {
env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 1);
+ env->CSR_ECFG = FIELD_DP64(env->CSR_ECFG, CSR_ECFG, MSGINT, 1);
}
}
}
--
2.34.1
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 4/9] target/loongarch: add msg interrupt CSR registers
2025-06-19 2:39 ` [PATCH v2 4/9] target/loongarch: add msg interrupt CSR registers Song Gao
@ 2025-06-20 7:05 ` Bibo Mao
2025-06-25 8:38 ` gaosong
0 siblings, 1 reply; 13+ messages in thread
From: Bibo Mao @ 2025-06-20 7:05 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/6/19 上午10:39, Song Gao wrote:
> include CSR_MSGIS0-3, CSR_MSGIR and CSR_MSGIE.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> target/loongarch/cpu.c | 7 +++++++
> target/loongarch/cpu.h | 10 ++++++++++
> target/loongarch/machine.c | 5 +++++
> 3 files changed, 22 insertions(+)
>
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> index abad84c054..bde9f917fc 100644
> --- a/target/loongarch/cpu.c
> +++ b/target/loongarch/cpu.c
> @@ -523,6 +523,13 @@ 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);
>
> + env->CSR_MSGIS[0] = 0;
> + env->CSR_MSGIS[1] = 0;
> + env->CSR_MSGIS[2] = 0;
> + env->CSR_MSGIS[3] = 0;
> + env->CSR_MSGIR = 0;
> + env->CSR_MSGIE = 0;
> +
> loongarch_la464_init_csr(obj);
> loongarch_cpu_post_init(obj);
> }
> diff --git a/target/loongarch/cpu.h b/target/loongarch/cpu.h
> index 1169768632..231ad5a7cb 100644
> --- a/target/loongarch/cpu.h
> +++ b/target/loongarch/cpu.h
> @@ -233,6 +233,12 @@ FIELD(TLB_MISC, ASID, 1, 10)
> FIELD(TLB_MISC, VPPN, 13, 35)
> FIELD(TLB_MISC, PS, 48, 6)
>
> +/*Msg interrupt registers */
> +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 +356,10 @@ typedef struct CPUArchState {
> uint64_t CSR_DBG;
> uint64_t CSR_DERA;
> uint64_t CSR_DSAVE;
> + /* Msg interrupt registers */
> + uint64_t CSR_MSGIS[4];
> + 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..7d5ee34f90 100644
> --- a/target/loongarch/machine.c
> +++ b/target/loongarch/machine.c
> @@ -231,6 +231,11 @@ const VMStateDescription vmstate_loongarch_cpu = {
> VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU),
> VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
>
> + /* Msg interrupt CSRs */
> + VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, 4),
> + VMSTATE_UINT64(env.CSR_MSGIR, LoongArchCPU),
> + VMSTATE_UINT64(env.CSR_MSGIE, LoongArchCPU),
> +
Can it be appended with one subsection in the end of structure
vmstate_loongarch_cpu? So that it is compatible with old machine.
Regards
Bibo Mao
> VMSTATE_UINT64(kvm_state_counter, LoongArchCPU),
> /* PV steal time */
> VMSTATE_UINT64(env.stealtime.guest_addr, LoongArchCPU),
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 7/9] hw/loongarch: Implement avec set irq
2025-06-19 2:39 ` [PATCH v2 7/9] hw/loongarch: Implement avec set irq Song Gao
@ 2025-06-20 7:30 ` Bibo Mao
0 siblings, 0 replies; 13+ messages in thread
From: Bibo Mao @ 2025-06-20 7:30 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/6/19 上午10:39, Song Gao wrote:
> Implement avec set irq and update CSR_MSIS and CSR_MSGIR.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_avec.c | 31 +++++++++++++++++++++++++++++--
> 1 file changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
> index 7dd8bac696..bbd1b48c7d 100644
> --- a/hw/intc/loongarch_avec.c
> +++ b/hw/intc/loongarch_avec.c
> @@ -16,6 +16,12 @@
> #include "migration/vmstate.h"
> #include "trace.h"
> #include "hw/qdev-properties.h"
> +#include "target/loongarch/cpu.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_avec_mem_read(void *opaque,
> hwaddr addr, unsigned size)
> @@ -23,12 +29,33 @@ static uint64_t loongarch_avec_mem_read(void *opaque,
> return 0;
> }
>
> +static void avec_set_irq(LoongArchAVECState *s, int cpu_num, int irq_num, int level)
> +{
> + MachineState *machine = MACHINE(qdev_get_machine());
> + MachineClass *mc = MACHINE_GET_CLASS(machine);
> + const CPUArchIdList *id_list = NULL;
> + assert(mc->possible_cpu_arch_ids(machine));
> + id_list = mc->possible_cpu_arch_ids(machine);
> + CPUState *cpu = id_list->cpus[cpu_num].cpu;
> + CPULoongArchState *env = &LOONGARCH_CPU(cpu)->env;
> +
> + set_bit(irq_num, &env->CSR_MSGIS[irq_num / 64]);
> + qemu_set_irq(s->cpu[cpu_num].parent_irq, 1);
> + env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, INTNUM, irq_num);
> + env->CSR_MSGIR = FIELD_DP64(env->CSR_MSGIR, CSR_MSGIR, ACTIVE, 0);
I think that CSR_MSGIR should be set in this function. CSR_MSGIR is read
only logic register, it get and clear nearest bit about CSR_MSGIS[4] in
CSR register emulation.
And when all bits about CSR_MSGIS[4] are cleared, parent irq can be set
with 0 such as:
qemu_set_irq(s->cpu[cpu_num].parent_irq, 0);
Regards
Bibo Mao
> +}
> +
> static void loongarch_avec_mem_write(void *opaque, hwaddr addr,
> uint64_t val, unsigned size)
> {
> - return;
> -}
> + int irq_num, cpu_num = 0;
> + LoongArchAVECState *s = LOONGARCH_AVEC(opaque);
> + uint64_t msg_addr = addr + VIRT_AVEC_BASE;
>
> + cpu_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_NUM);
> + irq_num = FIELD_EX64(msg_addr, MSG_ADDR, CPU_NUM);
> + avec_set_irq(s, cpu_num, irq_num, 1);
> +}
>
> static const MemoryRegionOps loongarch_avec_ops = {
> .read = loongarch_avec_mem_read,
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 4/9] target/loongarch: add msg interrupt CSR registers
2025-06-20 7:05 ` Bibo Mao
@ 2025-06-25 8:38 ` gaosong
0 siblings, 0 replies; 13+ messages in thread
From: gaosong @ 2025-06-25 8:38 UTC (permalink / raw)
To: Bibo Mao; +Cc: qemu-devel, philmd, jiaxun.yang
在 2025/6/20 下午3:05, Bibo Mao 写道:
>> --- a/target/loongarch/machine.c
>> +++ b/target/loongarch/machine.c
>> @@ -231,6 +231,11 @@ const VMStateDescription vmstate_loongarch_cpu = {
>> VMSTATE_UINT64(env.CSR_DERA, LoongArchCPU),
>> VMSTATE_UINT64(env.CSR_DSAVE, LoongArchCPU),
>> + /* Msg interrupt CSRs */
>> + VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, 4),
>> + VMSTATE_UINT64(env.CSR_MSGIR, LoongArchCPU),
>> + VMSTATE_UINT64(env.CSR_MSGIE, LoongArchCPU),
>> +
> Can it be appended with one subsection in the end of structure
> vmstate_loongarch_cpu? So that it is compatible with old machine.
>
Yes, I 'll add it on v3 .
Thanks.
Song Gao
> Regards
> Bibo Mao
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-06-25 8:36 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-19 2:39 [PATCH v2 0/9] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
2025-06-19 2:39 ` [PATCH v2 1/9] hw/loongarch: move some machine define to virt.h Song Gao
2025-06-19 2:39 ` [PATCH v2 2/9] loongarch: add virt feature avecintc support Song Gao
2025-06-19 2:39 ` [PATCH v2 3/9] loongarch: add a advance interrupt controller device Song Gao
2025-06-19 2:39 ` [PATCH v2 4/9] target/loongarch: add msg interrupt CSR registers Song Gao
2025-06-20 7:05 ` Bibo Mao
2025-06-25 8:38 ` gaosong
2025-06-19 2:39 ` [PATCH v2 5/9] hw/loongarch: AVEC controller add a MemoryRegion Song Gao
2025-06-19 2:39 ` [PATCH v2 6/9] hw/loongarch: Implement avec controller imput and output pins Song Gao
2025-06-19 2:39 ` [PATCH v2 7/9] hw/loongarch: Implement avec set irq Song Gao
2025-06-20 7:30 ` Bibo Mao
2025-06-19 2:39 ` [PATCH v2 8/9] target/loongarch: CSR_ESTAT enable msg interrupts Song Gao
2025-06-19 2:39 ` [PATCH v2 9/9] target/loongarch: CSR_ECFG enable msg interrupt Song Gao
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).