aboutsummaryrefslogtreecommitdiff
path: root/target/riscv/cpu_helper.c
diff options
context:
space:
mode:
authorRajnesh Kanwal <rkanwal@rivosinc.com>2023-10-16 12:17:34 +0100
committerAlistair Francis <alistair.francis@wdc.com>2023-11-07 11:02:17 +1000
commit1ebad505f3d5108513bf150b901344caceb3a7c1 (patch)
tree48647564dccaa213aaf964daf90e069d285de4c6 /target/riscv/cpu_helper.c
parentb901c7eb701a8f4d512be3a70958150fc5d0cd90 (diff)
target/riscv: Split interrupt logic from riscv_cpu_update_mip.
This is to allow virtual interrupts to be inserted into S and VS modes. Given virtual interrupts will be maintained in separate mvip and hvip CSRs, riscv_cpu_update_mip will no longer be in the path and interrupts need to be triggered for these cases from rmw_hvip64 and rmw_mvip64 functions. Signed-off-by: Rajnesh Kanwal <rkanwal@rivosinc.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20231016111736.28721-5-rkanwal@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'target/riscv/cpu_helper.c')
-rw-r--r--target/riscv/cpu_helper.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index aaeb1d0d5c..581b8c6380 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -620,11 +620,12 @@ int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
}
}
-uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
- uint64_t value)
+void riscv_cpu_interrupt(CPURISCVState *env)
{
+ uint64_t gein, vsgein = 0, vstip = 0;
CPUState *cs = env_cpu(env);
- uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
+
+ QEMU_IOTHREAD_LOCK_GUARD();
if (env->virt_enabled) {
gein = get_field(env->hstatus, HSTATUS_VGEIN);
@@ -633,15 +634,25 @@ uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
vstip = env->vstime_irq ? MIP_VSTIP : 0;
- QEMU_IOTHREAD_LOCK_GUARD();
-
- env->mip = (env->mip & ~mask) | (value & mask);
-
if (env->mip | vsgein | vstip) {
cpu_interrupt(cs, CPU_INTERRUPT_HARD);
} else {
cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
}
+}
+
+uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, uint64_t value)
+{
+ uint64_t old = env->mip;
+
+ /* No need to update mip for VSTIP */
+ mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
+
+ QEMU_IOTHREAD_LOCK_GUARD();
+
+ env->mip = (env->mip & ~mask) | (value & mask);
+
+ riscv_cpu_interrupt(env);
return old;
}