Implement avec set irq and update CSR_MSIS.
Signed-off-by: Song Gao <[email protected]>
---
hw/intc/loongarch_avec.c | 58 ++++++++++++++++++++++++++++++--
include/hw/intc/loongarch_avec.h | 3 ++
2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/hw/intc/loongarch_avec.c b/hw/intc/loongarch_avec.c
index 1f9f376898..03a20a7b60 100644
--- a/hw/intc/loongarch_avec.c
+++ b/hw/intc/loongarch_avec.c
@@ -16,6 +16,13 @@
#include "migration/vmstate.h"
#include "trace.h"
#include "hw/qdev-properties.h"
+#include "target/loongarch/cpu.h"
+#include "qemu/error-report.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,13 +30,60 @@ static uint64_t loongarch_avec_mem_read(void *opaque,
return 0;
}
+static void do_set_vcpu_avec_irq(CPUState *cs, run_on_cpu_data data)
+{
+ AVECCore *core = data.host_ptr;
+ CPULoongArchState *env;
+
+ assert(cs->cpu_index == core->dest_cpu);
+ env = &LOONGARCH_CPU(cs)->env;
+ if (core->level) {
+ set_bit(core->pending, &env->CSR_MSGIS[core->pending / 64]);
+ }
+ g_free(core);
+}
+
+
+static void avec_update_csr(AVECCore *core, int cpu_num,
+ int irq_num, int level)
+{
+ CPUState *cs = qemu_get_cpu(cpu_num);
+
+ core->pending = irq_num;
+ core->dest_cpu = cpu_num;
+ core->level = level;
+ async_run_on_cpu(cs, do_set_vcpu_avec_irq,
+ RUN_ON_CPU_HOST_PTR(core));
+}
+
+static void avec_set_irq(LoongArchAVECState *s, int cpu_num,
+ int irq_num, int level)
+{
+ AVECCore *core;
+
+ core = g_new(AVECCore, 1);
+
+ if (level) {
+ avec_update_csr(core, cpu_num, irq_num, level);
+ }
+ qemu_set_irq(s->cpu[cpu_num].parent_irq, level);