LIU Zhiwei 於 2021年4月9日 週五 下午3:55寫道: > When a vectored interrupt is selected and serviced, the hardware will > automatically clear the corresponding pending bit in edge-triggered mode. > This may lead to a lower priviledge interrupt pending forever. > > Therefore when interrupts return, pull a pending interrupt to service. > > Signed-off-by: LIU Zhiwei > --- > target/riscv/op_helper.c | 25 +++++++++++++++++++++++++ > 1 file changed, 25 insertions(+) > > diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c > index 1eddcb94de..42563b22ba 100644 > --- a/target/riscv/op_helper.c > +++ b/target/riscv/op_helper.c > @@ -24,6 +24,10 @@ > #include "exec/exec-all.h" > #include "exec/helper-proto.h" > > +#if !defined(CONFIG_USER_ONLY) > +#include "hw/intc/riscv_clic.h" > +#endif > + > /* Exceptions processing helpers */ > void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env, > uint32_t exception, uintptr_t > pc) > @@ -130,6 +134,17 @@ target_ulong helper_sret(CPURISCVState *env, > target_ulong cpu_pc_deb) > mstatus = set_field(mstatus, MSTATUS_SPIE, 1); > mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U); > env->mstatus = mstatus; > + > + if (riscv_clic_is_clic_mode(env)) { > + CPUState *cs = env_cpu(env); > + target_ulong spil = get_field(env->scause, SCAUSE_SPIL); > + env->mintstatus = set_field(env->mintstatus, MINTSTATUS_SIL, > spil); > + env->scause = set_field(env->scause, SCAUSE_SPIE, 0); > Should scause.spie set to 1? > + env->scause = set_field(env->scause, SCAUSE_SPP, PRV_U); > + qemu_mutex_lock_iothread(); > + riscv_clic_get_next_interrupt(env->clic, cs->cpu_index); > + qemu_mutex_unlock_iothread(); > + } > } > > riscv_cpu_set_mode(env, prev_priv); > @@ -172,6 +187,16 @@ target_ulong helper_mret(CPURISCVState *env, > target_ulong cpu_pc_deb) > riscv_cpu_set_virt_enabled(env, prev_virt); > } > > + if (riscv_clic_is_clic_mode(env)) { > + CPUState *cs = env_cpu(env); > + target_ulong mpil = get_field(env->mcause, MCAUSE_MPIL); > + env->mintstatus = set_field(env->mintstatus, MINTSTATUS_MIL, > mpil); > + env->mcause = set_field(env->mcause, MCAUSE_MPIE, 0); > Should mcause.mpie set to 1? The xcause.xpp and xcause.xpie fields are modified following the behavior previously defined for xstatus.xpp and xstatus.xpie respectively. RISC-V Privilege spec: When executing an xRET instruction, xPIE is set to 1. Regards, Frank Chang > + env->mcause = set_field(env->mcause, MCAUSE_MPP, PRV_U); > + qemu_mutex_lock_iothread(); > + riscv_clic_get_next_interrupt(env->clic, cs->cpu_index); > + qemu_mutex_unlock_iothread(); > + } > return retpc; > } > > -- > 2.25.1 > > >