diff options
Diffstat (limited to 'target/riscv/cpu_helper.c')
-rw-r--r-- | target/riscv/cpu_helper.c | 28 |
1 files changed, 8 insertions, 20 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 662228c..5076580 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -135,36 +135,24 @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc, #ifndef CONFIG_USER_ONLY static int riscv_cpu_local_irq_pending(CPURISCVState *env) { - target_ulong irqs; + target_ulong virt_enabled = riscv_cpu_virt_enabled(env); target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE); target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE); - target_ulong hs_mstatus_sie = get_field(env->mstatus_hs, MSTATUS_SIE); - target_ulong pending = env->mip & env->mie & - ~(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP); - target_ulong vspending = (env->mip & env->mie & - (MIP_VSSIP | MIP_VSTIP | MIP_VSEIP)); + target_ulong pending = env->mip & env->mie; target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && mstatus_mie); target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && mstatus_sie); - target_ulong hs_sie = env->priv < PRV_S || - (env->priv == PRV_S && hs_mstatus_sie); + target_ulong hsie = virt_enabled || sie; + target_ulong vsie = virt_enabled && sie; - if (riscv_cpu_virt_enabled(env)) { - target_ulong pending_hs_irq = pending & -hs_sie; - - if (pending_hs_irq) { - riscv_cpu_set_force_hs_excep(env, FORCE_HS_EXCEP); - return ctz64(pending_hs_irq); - } - - pending = vspending; - } - - irqs = (pending & ~env->mideleg & -mie) | (pending & env->mideleg & -sie); + target_ulong irqs = + (pending & ~env->mideleg & -mie) | + (pending & env->mideleg & ~env->hideleg & -hsie) | + (pending & env->mideleg & env->hideleg & -vsie); if (irqs) { return ctz64(irqs); /* since non-zero */ |