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);
#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
void *arg);
}
}
-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);
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;
}