* [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support
@ 2025-07-11 8:59 Song Gao
2025-07-11 8:59 ` [PATCH v5 01/11] target/loongarch: move some machine define to virt.h Song Gao
` (10 more replies)
0 siblings, 11 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
Hi,
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] and then
run 'ifconfig eth0 192.168.122.12' or
test avec plug and unplug interfaces
1 run kernel.sh[3]
2 telnet localhost 4418;
3 run QOM 'device_add la464-loongarch-cpu,socket-id=2,core-id=0,thread-id=0,id=cpu-2'
4 run vm 'ifconfig eth0 192.168.122.12';
5 run QOM 'device_de cpu-2'
6 run vm 'ifconfig eth0 192.168.122.11';
[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
v5:
1: rebase and R_b;
2; change patch2 and patch3 commit message;
3, change virt_is_avecintc_enabled() to virt_has_avecintc();
4: remove set and clean CSR_ECFG.bit15;
5; patch11 add some check lvms->avec, beacuse someone my set avecintc=off.
v4:
1: Implemetnt the AVEC plug/unplug interface. test with devcice-add
cpu and device-add and then setup the virtio-net nic. new patch11;
2: add a new patch1 move some machine define to virt.h;
3; add a new patch3 to implemet write/raad misc' avec feature and
status bit.
4: Simplification of patch8 and patch10 as per bibo's suggestion.
v3:
1: Implement the read-clear feature for CSR_MSGIR register
2: Fix some code style;
3: Merge patch8 and patch9 into one patch8;
4: Fix patch7 get wrong cpu_num and irq_num;
5: Add vmstate_msg for messag-interrupt registers migrate;
6: Update test scripts use '-bios', because kernel use avec need acpi
support. the bios is qemu/pc_bios/edk2-loongarch64-code.fd.bz2.
Thanks.
Song Gao
Song Gao (11):
target/loongarch: move some machine dfine to virt.h
hw/loongarch: add virt feature avecintc support
hw/loongarch: add misc register supoort avecintc
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: CPU enable msg interrupts.
target/loongarch:Implement csrrd CSR_MSGIR register
hw/loongarch: Implement AVEC plug/unplug interfaces
hw/intc/Kconfig | 3 +
hw/intc/loongarch_avec.c | 214 ++++++++++++++++++
hw/intc/meson.build | 1 +
hw/loongarch/Kconfig | 1 +
hw/loongarch/virt.c | 98 +++++++-
include/hw/intc/loongarch_avec.h | 36 +++
include/hw/loongarch/virt.h | 33 +++
include/hw/pci-host/ls7a.h | 2 +
target/loongarch/cpu-csr.h | 9 +-
target/loongarch/cpu.c | 10 +
target/loongarch/cpu.h | 34 +--
target/loongarch/csr.c | 5 +
target/loongarch/machine.c | 27 ++-
target/loongarch/tcg/csr_helper.c | 22 ++
target/loongarch/tcg/helper.h | 1 +
.../tcg/insn_trans/trans_privileged.c.inc | 1 +
16 files changed, 468 insertions(+), 29 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] 20+ messages in thread
* [PATCH v5 01/11] target/loongarch: move some machine define to virt.h
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-11 8:59 ` [PATCH v5 02/11] hw/loongarch: add virt feature avecintc support Song Gao
` (9 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
move some machine define to virt.h
Signed-off-by: Song Gao <gaosong@loongson.cn>
Reviewed-by: Bibo Mao <maobibo@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 9538e8d61d..56fc4a1459 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] 20+ messages in thread
* [PATCH v5 02/11] hw/loongarch: add virt feature avecintc support
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
2025-07-11 8:59 ` [PATCH v5 01/11] target/loongarch: move some machine define to virt.h Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-15 1:02 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 03/11] hw/loongarch: add misc register supoort avecintc Song Gao
` (8 subsequent siblings)
10 siblings, 1 reply; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
Avecintc feature is added in LoongArchVirtMachinState, and it is used
to check whether virt machine supports the advanced interrupt controller
and by default set avecintc with ON_OFF_AUTO_ON.
LoongArchVirtMachineState adds misc_feature and misc_status for misc
features and status. and set the default avec feature bit.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/loongarch/virt.c | 30 ++++++++++++++++++++++++++++++
include/hw/loongarch/virt.h | 14 ++++++++++++++
2 files changed, 44 insertions(+)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index b15ada2078..112cf9a9db 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -47,6 +47,27 @@
#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);
+
+ visit_type_OnOffAuto(v, name, &lvms->avecintc, errp);
+ if (lvms->avecintc == ON_OFF_AUTO_OFF) {
+ lvms->misc_feature &= ~BIT(IOCSRF_AVEC);
+ lvms->misc_status &= ~BIT(IOCSRM_AVEC_EN);
+ }
+}
+
static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
@@ -846,6 +867,9 @@ 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);
@@ -1238,6 +1262,12 @@ 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.");
+#ifdef CONFIG_TCG
+ 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.");
+#endif
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..68b8e92e99 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_AVEC 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_AVEC_EN 51
#define LOONGARCH_MAX_CPUS 256
@@ -69,6 +71,7 @@ struct LoongArchVirtMachineState {
Notifier powerdown_notifier;
OnOffAuto acpi;
OnOffAuto veiointc;
+ OnOffAuto avecintc;
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_avecintc(LoongArchVirtMachineState *lvms)
+{
+ if (!(lvms->misc_feature & BIT(IOCSRF_AVEC))) {
+ 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] 20+ messages in thread
* [PATCH v5 03/11] hw/loongarch: add misc register supoort avecintc
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
2025-07-11 8:59 ` [PATCH v5 01/11] target/loongarch: move some machine define to virt.h Song Gao
2025-07-11 8:59 ` [PATCH v5 02/11] hw/loongarch: add virt feature avecintc support Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-11 8:59 ` [PATCH v5 04/11] loongarch: add a advance interrupt controller device Song Gao
` (7 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
Add feature register and misc register for avecintc feature checking and
setting
Signed-off-by: Song Gao <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 112cf9a9db..0d05404eb5 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -560,6 +560,10 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
return MEMTX_OK;
}
+ if (val & BIT(IOCSRM_AVEC_EN)) {
+ lvms->misc_status |= BIT(IOCSRM_AVEC_EN);
+ }
+
features = address_space_ldl(&lvms->as_iocsr,
EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
attrs, NULL);
@@ -595,6 +599,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_avecintc(lvms)) {
+ ret |= BIT(IOCSRF_AVEC);
+ }
if (kvm_enabled()) {
ret |= BIT(IOCSRF_VM);
}
@@ -624,6 +631,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_avecintc(lvms) &&
+ (lvms->misc_status & BIT(IOCSRM_AVEC_EN))) {
+ ret |= BIT_ULL(IOCSRM_AVEC_EN);
+ }
break;
default:
g_assert_not_reached();
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 04/11] loongarch: add a advance interrupt controller device
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (2 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 03/11] hw/loongarch: add misc register supoort avecintc Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-11 8:59 ` [PATCH v5 05/11] target/loongarch: add msg interrupt CSR registers Song Gao
` (6 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 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 3137521a4a..cf2c47cd53 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_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] 20+ messages in thread
* [PATCH v5 05/11] target/loongarch: add msg interrupt CSR registers
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (3 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 04/11] loongarch: add a advance interrupt controller device Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-14 9:35 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 06/11] hw/loongarch: AVEC controller add a MemoryRegion Song Gao
` (5 subsequent siblings)
10 siblings, 1 reply; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 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-csr.h | 3 +++
target/loongarch/cpu.h | 10 ++++++++++
target/loongarch/machine.c | 27 +++++++++++++++++++++++++--
3 files changed, 38 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 56fc4a1459..208d3e0cd3 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..9eddb9341a 100644
--- a/target/loongarch/machine.c
+++ b/target/loongarch/machine.c
@@ -10,6 +10,7 @@
#include "migration/cpu.h"
#include "system/tcg.h"
#include "vec.h"
+#include "hw/loongarch/virt.h"
static const VMStateDescription vmstate_fpu_reg = {
.name = "fpu_reg",
@@ -45,6 +46,27 @@ static const VMStateDescription vmstate_fpu = {
},
};
+static bool msg_needed(void *opaque)
+{
+ MachineState *ms = MACHINE(qdev_get_machine());
+ LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
+
+ return !!(lvms->misc_feature & BIT(IOCSRF_AVEC));
+}
+
+static const VMStateDescription vmstate_msg = {
+ .name = "cpu/msg",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = msg_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, 4),
+ 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 +190,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 +267,7 @@ const VMStateDescription vmstate_loongarch_cpu = {
&vmstate_tlb,
#endif
&vmstate_lbt,
+ &vmstate_msg,
NULL
}
};
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 06/11] hw/loongarch: AVEC controller add a MemoryRegion
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (4 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 05/11] target/loongarch: add msg interrupt CSR registers Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-11 8:59 ` [PATCH v5 07/11] hw/loongarch: Implement avec controller imput and output pins Song Gao
` (4 subsequent siblings)
10 siblings, 0 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 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 | 24 ++++++++++++++++++++
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, 66 insertions(+), 1 deletion(-)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 5a3e7ecc03..253bab5461 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,12 @@ 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 0d05404eb5..b420d1def9 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"
@@ -382,7 +383,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;
@@ -428,6 +429,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 */
@@ -435,6 +463,15 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms)
lvms->ipi = ipi;
sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
+ /* Create AVEC device*/
+ if (virt_has_avecintc(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 68b8e92e99..bc3cee705d 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 *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..199f47ecc0 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 0x1000000UL
+#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] 20+ messages in thread
* [PATCH v5 07/11] hw/loongarch: Implement avec controller imput and output pins
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (5 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 06/11] hw/loongarch: AVEC controller add a MemoryRegion Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-14 9:38 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 08/11] hw/loongarch: Implement avec set irq Song Gao
` (3 subsequent siblings)
10 siblings, 1 reply; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 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 | 20 ++++++++++++++++++++
hw/loongarch/virt.c | 11 +++++++++--
target/loongarch/cpu.h | 3 ++-
3 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 253bab5461..1f9f376898 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,21 @@ 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);
+ }
+
return;
}
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index b420d1def9..e3ab165cc5 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -380,7 +380,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;
@@ -470,6 +470,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 */
@@ -838,7 +845,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 208d3e0cd3..556e9dabb9 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] 20+ messages in thread
* [PATCH v5 08/11] hw/loongarch: Implement avec set irq
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (6 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 07/11] hw/loongarch: Implement avec controller imput and output pins Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-14 9:29 ` Bibo Mao
2025-08-28 8:34 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 09/11] target/loongarch: CPU enable msg interrupts Song Gao
` (2 subsequent siblings)
10 siblings, 2 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
Implement avec set irq and update CSR_MSIS.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_avec.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 1f9f376898..af6c75c4a9 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,36 @@ 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;
+ CPUState *cpu;
+ CPULoongArchState *env;
+
+ assert(mc->possible_cpu_arch_ids(machine));
+ id_list = mc->possible_cpu_arch_ids(machine);
+ cpu = id_list->cpus[cpu_num].cpu;
+ env = &LOONGARCH_CPU(cpu)->env;
+
+ if (level) {
+ set_bit(irq_num, &env->CSR_MSGIS[irq_num / 64]);
+ }
+ qemu_set_irq(s->cpu[cpu_num].parent_irq, level);
+}
+
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, CPU_NUM);
+ irq_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_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] 20+ messages in thread
* [PATCH v5 09/11] target/loongarch: CPU enable msg interrupts.
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (7 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 08/11] hw/loongarch: Implement avec set irq Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-14 9:46 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 10/11] target/loongarch:Implement csrrd CSR_MSGIR register Song Gao
2025-07-11 8:59 ` [PATCH v5 11/11] hw/loongarch: Implement AVEC plug/unplug interfaces Song Gao
10 siblings, 1 reply; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 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 | 6 ++++--
target/loongarch/cpu.c | 10 +++++++++-
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
index 4792677086..6ec13d13d1 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)
diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
index abad84c054..9e21ed1d07 100644
--- a/target/loongarch/cpu.c
+++ b/target/loongarch/cpu.c
@@ -130,7 +130,15 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
if (kvm_enabled()) {
kvm_loongarch_set_interrupt(cpu, irq, level);
} else if (tcg_enabled()) {
- env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
+ /* do INTC_AVEC irqs */
+ if (irq == INT_AVEC) {
+ irq = find_first_bit(env->CSR_MSGIS, 256);
+ if (irq < 256) {
+ env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 1);
+ }
+ } else {
+ env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
+ }
if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
} else {
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 10/11] target/loongarch:Implement csrrd CSR_MSGIR register
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (8 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 09/11] target/loongarch: CPU enable msg interrupts Song Gao
@ 2025-07-11 8:59 ` Song Gao
2025-07-11 8:59 ` [PATCH v5 11/11] hw/loongarch: Implement AVEC plug/unplug interfaces Song Gao
10 siblings, 0 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
implement the read-clear feature for CSR_MSGIR register.
Signed-off-by: Song Gao <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 2942d7feb8..48996b62f7 100644
--- a/target/loongarch/tcg/csr_helper.c
+++ b/target/loongarch/tcg/csr_helper.c
@@ -68,6 +68,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(env->CSR_MSGIS, 256);
+ if (irq < 256) {
+ clear_bit(irq, env->CSR_MSGIS);
+ new = find_first_bit(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 ecbfe23b63..2619b5342b 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.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH v5 11/11] hw/loongarch: Implement AVEC plug/unplug interfaces
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
` (9 preceding siblings ...)
2025-07-11 8:59 ` [PATCH v5 10/11] target/loongarch:Implement csrrd CSR_MSGIR register Song Gao
@ 2025-07-11 8:59 ` Song Gao
10 siblings, 0 replies; 20+ messages in thread
From: Song Gao @ 2025-07-11 8:59 UTC (permalink / raw)
To: maobibo; +Cc: qemu-devel, philmd, jiaxun.yang
when cpu added, connect avec irq to cpu INT_AVEC irq pin.
Signed-off-by: Song Gao <gaosong@loongson.cn>
---
hw/intc/loongarch_avec.c | 71 ++++++++++++++++++++++++++++++++++++++++
hw/loongarch/virt.c | 11 +++++++
2 files changed, 82 insertions(+)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index af6c75c4a9..820d6655ef 100644
--- a/hw/intc/loongarch_avec.c
+++ b/hw/intc/loongarch_avec.c
@@ -116,14 +116,81 @@ static void loongarch_avec_init(Object *obj)
return;
}
+static AVECCore *loongarch_avec_get_cpu(LoongArchAVECState *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_avec_cpu_plug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ LoongArchAVECState *s = LOONGARCH_AVEC(hotplug_dev);
+ Object *obj = OBJECT(dev);
+ AVECCore *core;
+ int index;
+
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
+ warn_report("LoongArch AVEC: Invalid %s device type",
+ object_get_typename(obj));
+ return;
+ }
+ core = loongarch_avec_get_cpu(s, dev);
+ if (!core) {
+ return;
+ }
+
+ core->cpu = CPU(dev);
+ index = core - s->cpu;
+
+ /* connect avec msg irq to cpu irq */
+ qdev_connect_gpio_out(DEVICE(s), index, qdev_get_gpio_in(dev, INT_AVEC));
+ return;
+}
+
+static void loongarch_avec_cpu_unplug(HotplugHandler *hotplug_dev,
+ DeviceState *dev, Error **errp)
+{
+ LoongArchAVECState *s = LOONGARCH_AVEC(hotplug_dev);
+ Object *obj = OBJECT(dev);
+ AVECCore *core;
+
+ if (!object_dynamic_cast(obj, TYPE_LOONGARCH_CPU)) {
+ warn_report("LoongArch AVEC: Invalid %s device type",
+ object_get_typename(obj));
+ return;
+ }
+
+ core = loongarch_avec_get_cpu(s, dev);
+
+ if (!core) {
+ return;
+ }
+
+ core->cpu = NULL;
+}
+
static void loongarch_avec_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ HotplugHandlerClass *hc = HOTPLUG_HANDLER_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);
+ hc->plug = loongarch_avec_cpu_plug;
+ hc->unplug = loongarch_avec_cpu_unplug;
}
static const TypeInfo loongarch_avec_info = {
@@ -132,6 +199,10 @@ static const TypeInfo loongarch_avec_info = {
.instance_size = sizeof(LoongArchAVECState),
.instance_init = loongarch_avec_init,
.class_init = loongarch_avec_class_init,
+ .interfaces = (const InterfaceInfo[]) {
+ { TYPE_HOTPLUG_HANDLER },
+ { }
+ },
};
static void loongarch_avec_register_types(void)
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index e3ab165cc5..7ea9b58f15 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -377,6 +377,10 @@ static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
&error_abort);
hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), DEVICE(cs),
&error_abort);
+ if (lvms->avec) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->avec), DEVICE(cs),
+ &error_abort);
+ }
}
}
@@ -1088,6 +1092,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->avec) {
+ hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->avec), dev, &error_abort);
+ }
/* Notify acpi ged CPU removed */
hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &error_abort);
@@ -1111,6 +1118,10 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev,
hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), dev, &error_abort);
}
+ if (lvms->avec) {
+ hotplug_handler_plug(HOTPLUG_HANDLER(lvms->avec), dev, &error_abort);
+ }
+
if (lvms->acpi_ged) {
hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged), dev,
&error_abort);
--
2.34.1
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH v5 08/11] hw/loongarch: Implement avec set irq
2025-07-11 8:59 ` [PATCH v5 08/11] hw/loongarch: Implement avec set irq Song Gao
@ 2025-07-14 9:29 ` Bibo Mao
2025-07-17 8:33 ` gaosong
2025-08-28 8:34 ` Bibo Mao
1 sibling, 1 reply; 20+ messages in thread
From: Bibo Mao @ 2025-07-14 9:29 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/7/11 下午4:59, Song Gao wrote:
> Implement avec set irq and update CSR_MSIS.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_avec.c | 34 ++++++++++++++++++++++++++++++++--
> 1 file changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
> index 1f9f376898..af6c75c4a9 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,36 @@ 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;
> + CPUState *cpu;
> + CPULoongArchState *env;
> +
> + assert(mc->possible_cpu_arch_ids(machine));
> + id_list = mc->possible_cpu_arch_ids(machine);
> + cpu = id_list->cpus[cpu_num].cpu;
> + env = &LOONGARCH_CPU(cpu)->env;
> +
> + if (level) {
> + set_bit(irq_num, &env->CSR_MSGIS[irq_num / 64]);
> + }
> + qemu_set_irq(s->cpu[cpu_num].parent_irq, level);
> +}
> +
> 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, CPU_NUM);
Here is physical cpuid rather than logic cpu index. We need convert
physical cpuid to logic cpu index.
Regards
Bibo Mao
> + irq_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_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] 20+ messages in thread
* Re: [PATCH v5 05/11] target/loongarch: add msg interrupt CSR registers
2025-07-11 8:59 ` [PATCH v5 05/11] target/loongarch: add msg interrupt CSR registers Song Gao
@ 2025-07-14 9:35 ` Bibo Mao
0 siblings, 0 replies; 20+ messages in thread
From: Bibo Mao @ 2025-07-14 9:35 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/7/11 下午4:59, Song Gao wrote:
> include CSR_MSGIS0-3, CSR_MSGIR and CSR_MSGIE.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> target/loongarch/cpu-csr.h | 3 +++
> target/loongarch/cpu.h | 10 ++++++++++
> target/loongarch/machine.c | 27 +++++++++++++++++++++++++--
> 3 files changed, 38 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 56fc4a1459..208d3e0cd3 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];
It will better if there is macro replaced with 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..9eddb9341a 100644
> --- a/target/loongarch/machine.c
> +++ b/target/loongarch/machine.c
> @@ -10,6 +10,7 @@
> #include "migration/cpu.h"
> #include "system/tcg.h"
> #include "vec.h"
> +#include "hw/loongarch/virt.h"
>
> static const VMStateDescription vmstate_fpu_reg = {
> .name = "fpu_reg",
> @@ -45,6 +46,27 @@ static const VMStateDescription vmstate_fpu = {
> },
> };
>
> +static bool msg_needed(void *opaque)
> +{
> + MachineState *ms = MACHINE(qdev_get_machine());
> + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
> +
> + return !!(lvms->misc_feature & BIT(IOCSRF_AVEC));
how about use virt_has_avecintc() like this?
return virt_has_avecintc(lvms);
> +}
> +
> +static const VMStateDescription vmstate_msg = {
> + .name = "cpu/msg",
> + .version_id = 1,
> + .minimum_version_id = 1,
> + .needed = msg_needed,
> + .fields = (const VMStateField[]) {
> + VMSTATE_UINT64_ARRAY(env.CSR_MSGIS, LoongArchCPU, 4),
ditto, it will be better if there is macro replaced with 4.
Regards
Bibo Mao
> + 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 +190,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 +267,7 @@ const VMStateDescription vmstate_loongarch_cpu = {
> &vmstate_tlb,
> #endif
> &vmstate_lbt,
> + &vmstate_msg,
> NULL
> }
> };
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 07/11] hw/loongarch: Implement avec controller imput and output pins
2025-07-11 8:59 ` [PATCH v5 07/11] hw/loongarch: Implement avec controller imput and output pins Song Gao
@ 2025-07-14 9:38 ` Bibo Mao
0 siblings, 0 replies; 20+ messages in thread
From: Bibo Mao @ 2025-07-14 9:38 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/7/11 下午4:59, Song Gao wrote:
> 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 | 20 ++++++++++++++++++++
> hw/loongarch/virt.c | 11 +++++++++--
> target/loongarch/cpu.h | 3 ++-
> 3 files changed, 31 insertions(+), 3 deletions(-)
>
> diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
> index 253bab5461..1f9f376898 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,21 @@ 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);
> + }
> +
> return;
> }
>
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index b420d1def9..e3ab165cc5 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -380,7 +380,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)
The extra parameter machine is not necessary, it can be acquired from
the first parameter lvms, such as:
MachineState *ms = MACHINE(lvms);
> {
> DeviceState *pch_pic, *pch_msi;
> DeviceState *ipi, *extioi, *avec;
> @@ -470,6 +470,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;
It is strange to declare new variable between sentences, I think it
should be put in the beginning of function.
Regards
Bibo Mao
> + 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 */
> @@ -838,7 +845,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 208d3e0cd3..556e9dabb9 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 */
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 09/11] target/loongarch: CPU enable msg interrupts.
2025-07-11 8:59 ` [PATCH v5 09/11] target/loongarch: CPU enable msg interrupts Song Gao
@ 2025-07-14 9:46 ` Bibo Mao
0 siblings, 0 replies; 20+ messages in thread
From: Bibo Mao @ 2025-07-14 9:46 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/7/11 下午4:59, Song Gao wrote:
> 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 | 6 ++++--
> target/loongarch/cpu.c | 10 +++++++++-
> 2 files changed, 13 insertions(+), 3 deletions(-)
>
> diff --git a/target/loongarch/cpu-csr.h b/target/loongarch/cpu-csr.h
> index 4792677086..6ec13d13d1 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)
>
> diff --git a/target/loongarch/cpu.c b/target/loongarch/cpu.c
> index abad84c054..9e21ed1d07 100644
> --- a/target/loongarch/cpu.c
> +++ b/target/loongarch/cpu.c
> @@ -130,7 +130,15 @@ void loongarch_cpu_set_irq(void *opaque, int irq, int level)
> if (kvm_enabled()) {
> kvm_loongarch_set_interrupt(cpu, irq, level);
> } else if (tcg_enabled()) {
> - env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
> + /* do INTC_AVEC irqs */
> + if (irq == INT_AVEC) {
> + irq = find_first_bit(env->CSR_MSGIS, 256);
> + if (irq < 256) {
> + env->CSR_ESTAT = FIELD_DP64(env->CSR_ESTAT, CSR_ESTAT, MSGINT, 1);
> + }
Why is there such checking for bitmap? Can the original sentence work?
env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
This piece of code is a little strange.
Regards
Bibo Mao
> + } else {
> + env->CSR_ESTAT = deposit64(env->CSR_ESTAT, irq, 1, level != 0);
> + }
> if (FIELD_EX64(env->CSR_ESTAT, CSR_ESTAT, IS)) {
> cpu_interrupt(cs, CPU_INTERRUPT_HARD);
> } else {
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 02/11] hw/loongarch: add virt feature avecintc support
2025-07-11 8:59 ` [PATCH v5 02/11] hw/loongarch: add virt feature avecintc support Song Gao
@ 2025-07-15 1:02 ` Bibo Mao
2025-07-15 1:32 ` gaosong
0 siblings, 1 reply; 20+ messages in thread
From: Bibo Mao @ 2025-07-15 1:02 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/7/11 下午4:59, Song Gao wrote:
> Avecintc feature is added in LoongArchVirtMachinState, and it is used
> to check whether virt machine supports the advanced interrupt controller
> and by default set avecintc with ON_OFF_AUTO_ON.
> LoongArchVirtMachineState adds misc_feature and misc_status for misc
> features and status. and set the default avec feature bit.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/loongarch/virt.c | 30 ++++++++++++++++++++++++++++++
> include/hw/loongarch/virt.h | 14 ++++++++++++++
> 2 files changed, 44 insertions(+)
>
> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
> index b15ada2078..112cf9a9db 100644
> --- a/hw/loongarch/virt.c
> +++ b/hw/loongarch/virt.c
> @@ -47,6 +47,27 @@
> #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);
> +
> + visit_type_OnOffAuto(v, name, &lvms->avecintc, errp);
> + if (lvms->avecintc == ON_OFF_AUTO_OFF) {
> + lvms->misc_feature &= ~BIT(IOCSRF_AVEC);
> + lvms->misc_status &= ~BIT(IOCSRM_AVEC_EN);
> + }
> +}
> +
> static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
> void *opaque, Error **errp)
> {
> @@ -846,6 +867,9 @@ 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);
> @@ -1238,6 +1262,12 @@ 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.");
> +#ifdef CONFIG_TCG
I think it will be better if tcg_enabled() is used here, since
CONFIG_TCG and CONFIG_KVM is enabled by default. It should be supported
in KVM mode now. It is suggested in V4 review process :)
Regards
Bibo Mao
> + 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.");
> +#endif
> 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..68b8e92e99 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_AVEC 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_AVEC_EN 51
>
> #define LOONGARCH_MAX_CPUS 256
>
> @@ -69,6 +71,7 @@ struct LoongArchVirtMachineState {
> Notifier powerdown_notifier;
> OnOffAuto acpi;
> OnOffAuto veiointc;
> + OnOffAuto avecintc;
> 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_avecintc(LoongArchVirtMachineState *lvms)
> +{
> + if (!(lvms->misc_feature & BIT(IOCSRF_AVEC))) {
> + return false;
> + }
> +
> + return true;
> +}
> +
> static inline bool virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
> {
> if (lvms->veiointc == ON_OFF_AUTO_OFF) {
>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 02/11] hw/loongarch: add virt feature avecintc support
2025-07-15 1:02 ` Bibo Mao
@ 2025-07-15 1:32 ` gaosong
0 siblings, 0 replies; 20+ messages in thread
From: gaosong @ 2025-07-15 1:32 UTC (permalink / raw)
To: Bibo Mao
Cc: qemu-devel, philmd, jiaxun.yang, Richard Henderson, Peter Maydell
在 2025/7/15 上午9:02, Bibo Mao 写道:
>
>
> On 2025/7/11 下午4:59, Song Gao wrote:
>> Avecintc feature is added in LoongArchVirtMachinState, and it is used
>> to check whether virt machine supports the advanced interrupt controller
>> and by default set avecintc with ON_OFF_AUTO_ON.
>> LoongArchVirtMachineState adds misc_feature and misc_status for misc
>> features and status. and set the default avec feature bit.
>>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>> hw/loongarch/virt.c | 30 ++++++++++++++++++++++++++++++
>> include/hw/loongarch/virt.h | 14 ++++++++++++++
>> 2 files changed, 44 insertions(+)
>>
>> diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
>> index b15ada2078..112cf9a9db 100644
>> --- a/hw/loongarch/virt.c
>> +++ b/hw/loongarch/virt.c
>> @@ -47,6 +47,27 @@
>> #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);
>> +
>> + visit_type_OnOffAuto(v, name, &lvms->avecintc, errp);
>> + if (lvms->avecintc == ON_OFF_AUTO_OFF) {
>> + lvms->misc_feature &= ~BIT(IOCSRF_AVEC);
>> + lvms->misc_status &= ~BIT(IOCSRM_AVEC_EN);
>> + }
>> +}
>> +
>> static void virt_get_veiointc(Object *obj, Visitor *v, const char
>> *name,
>> void *opaque, Error **errp)
>> {
>> @@ -846,6 +867,9 @@ 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);
>> @@ -1238,6 +1262,12 @@ 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.");
>> +#ifdef CONFIG_TCG
> I think it will be better if tcg_enabled() is used here, since
> CONFIG_TCG and CONFIG_KVM is enabled by default. It should be
> supported in KVM mode now. It is suggested in V4 review process :)
>
emm, I had tested again , this may be a bug , here tcg_allowed is not
set so the tcg_enabled() not work, the same with kvm_enabled()
Thanks.,
Song Gao
> Regads
> Bibo Mao
>> + 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.");
>> +#endif
>> 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..68b8e92e99 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_AVEC 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_AVEC_EN 51
>> #define LOONGARCH_MAX_CPUS 256
>> @@ -69,6 +71,7 @@ struct LoongArchVirtMachineState {
>> Notifier powerdown_notifier;
>> OnOffAuto acpi;
>> OnOffAuto veiointc;
>> + OnOffAuto avecintc;
>> 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_avecintc(LoongArchVirtMachineState *lvms)
>> +{
>> + if (!(lvms->misc_feature & BIT(IOCSRF_AVEC))) {
>> + return false;
>> + }
>> +
>> + return true;
>> +}
>> +
>> static inline bool
>> virt_is_veiointc_enabled(LoongArchVirtMachineState *lvms)
>> {
>> if (lvms->veiointc == ON_OFF_AUTO_OFF) {
>>
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH v5 08/11] hw/loongarch: Implement avec set irq
2025-07-14 9:29 ` Bibo Mao
@ 2025-07-17 8:33 ` gaosong
0 siblings, 0 replies; 20+ messages in thread
From: gaosong @ 2025-07-17 8:33 UTC (permalink / raw)
To: Bibo Mao; +Cc: qemu-devel, philmd, jiaxun.yang
在 2025/7/14 下午5:29, Bibo Mao 写道:
>
>
> On 2025/7/11 下午4:59, Song Gao wrote:
>> Implement avec set irq and update CSR_MSIS.
>>
>> Signed-off-by: Song Gao <gaosong@loongson.cn>
>> ---
>> hw/intc/loongarch_avec.c | 34 ++++++++++++++++++++++++++++++++--
>> 1 file changed, 32 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
>> index 1f9f376898..af6c75c4a9 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,36 @@ 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;
>> + CPUState *cpu;
>> + CPULoongArchState *env;
>> +
>> + assert(mc->possible_cpu_arch_ids(machine));
>> + id_list = mc->possible_cpu_arch_ids(machine);
>> + cpu = id_list->cpus[cpu_num].cpu;
>> + env = &LOONGARCH_CPU(cpu)->env;
>> +
>> + if (level) {
>> + set_bit(irq_num, &env->CSR_MSGIS[irq_num / 64]);
>> + }
>> + qemu_set_irq(s->cpu[cpu_num].parent_irq, level);
>> +}
>> +
>> 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, CPU_NUM);
> Here is physical cpuid rather than logic cpu index. We need convert
> physical cpuid to logic cpu index.
How about the following code;
+ CPUState * cpu = cpu_by_arch_id(cpu_num);
+ cpu_num = cpu->cpu_index;
or like the IPI device add an function pointer in LoongsonIPICommonClass
LoongsonIPICommonClass {
[..]
int (*cpu_by_arch_id)(LoongsonIPICommonState *lics, int64_t id,
int *index, CPUState **pcs);
[...]
Thanks.
Song Gao
>
> Regards
> Bibo Mao
>> + irq_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_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] 20+ messages in thread
* Re: [PATCH v5 08/11] hw/loongarch: Implement avec set irq
2025-07-11 8:59 ` [PATCH v5 08/11] hw/loongarch: Implement avec set irq Song Gao
2025-07-14 9:29 ` Bibo Mao
@ 2025-08-28 8:34 ` Bibo Mao
1 sibling, 0 replies; 20+ messages in thread
From: Bibo Mao @ 2025-08-28 8:34 UTC (permalink / raw)
To: Song Gao; +Cc: qemu-devel, philmd, jiaxun.yang
On 2025/7/11 下午4:59, Song Gao wrote:
> Implement avec set irq and update CSR_MSIS.
>
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> ---
> hw/intc/loongarch_avec.c | 34 ++++++++++++++++++++++++++++++++--
> 1 file changed, 32 insertions(+), 2 deletions(-)
>
> diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
> index 1f9f376898..af6c75c4a9 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,36 @@ 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;
> + CPUState *cpu;
> + CPULoongArchState *env;
> +
> + assert(mc->possible_cpu_arch_ids(machine));
> + id_list = mc->possible_cpu_arch_ids(machine);
> + cpu = id_list->cpus[cpu_num].cpu;
> + env = &LOONGARCH_CPU(cpu)->env;
> +
> + if (level) {
> + set_bit(irq_num, &env->CSR_MSGIS[irq_num / 64]);
After a second thought, it has problem in KVM mode. In KVM mode, AVEC
irqchip is hardware-assisted rather than SW emulated.
CSR register CSR_MSGIS[] can only be set on vCPU itself and cannot be
set by other QEMU threads, since it will be overwritten when vCPU is
kicked out/in.
Maybe we need further investigation about how to inject CPU IRQ such as
IPI/timer, and then inject AVEC sub-irqchip IRQ.
Regards
Bibo Mao
> + }
> + qemu_set_irq(s->cpu[cpu_num].parent_irq, level);
> +}
> +
> 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, CPU_NUM);
> + irq_num = FIELD_EX64(msg_addr, MSG_ADDR, IRQ_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] 20+ messages in thread
end of thread, other threads:[~2025-08-28 8:37 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-11 8:59 [PATCH v5 00/11] hw/loongarch: add the advanced extended interrupt controllers (AVECINTC) support Song Gao
2025-07-11 8:59 ` [PATCH v5 01/11] target/loongarch: move some machine define to virt.h Song Gao
2025-07-11 8:59 ` [PATCH v5 02/11] hw/loongarch: add virt feature avecintc support Song Gao
2025-07-15 1:02 ` Bibo Mao
2025-07-15 1:32 ` gaosong
2025-07-11 8:59 ` [PATCH v5 03/11] hw/loongarch: add misc register supoort avecintc Song Gao
2025-07-11 8:59 ` [PATCH v5 04/11] loongarch: add a advance interrupt controller device Song Gao
2025-07-11 8:59 ` [PATCH v5 05/11] target/loongarch: add msg interrupt CSR registers Song Gao
2025-07-14 9:35 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 06/11] hw/loongarch: AVEC controller add a MemoryRegion Song Gao
2025-07-11 8:59 ` [PATCH v5 07/11] hw/loongarch: Implement avec controller imput and output pins Song Gao
2025-07-14 9:38 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 08/11] hw/loongarch: Implement avec set irq Song Gao
2025-07-14 9:29 ` Bibo Mao
2025-07-17 8:33 ` gaosong
2025-08-28 8:34 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 09/11] target/loongarch: CPU enable msg interrupts Song Gao
2025-07-14 9:46 ` Bibo Mao
2025-07-11 8:59 ` [PATCH v5 10/11] target/loongarch:Implement csrrd CSR_MSGIR register Song Gao
2025-07-11 8:59 ` [PATCH v5 11/11] hw/loongarch: Implement AVEC plug/unplug interfaces 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).