On Wed, 2026-09-09 at 11:48 -0300, Daniel Henrique Barboza wrote: > From: Chao Liu <[email protected]> > > RISC-V Debug Specification: > https://github.com/riscv/riscv-debug-spec/releases/tag/1.0 > > Add DRET decode/translate and a helper to leave Debug Mode and return > to dpc. Executing DRET outside Debug Mode raises illegal instruction. > > Signed-off-by: Chao Liu <[email protected]> > Reviewed-by: Daniel Henrique Barboza > <[email protected]> > Tested-by: Tao Tang <[email protected]> > Signed-off-by: Daniel Henrique Barboza > <[email protected]>
Reviewed-by: Alistair Francis <[email protected]> Alistair > --- > target/riscv/helper.h | 1 + > target/riscv/insn32.decode | 1 + > .../tcg/insn_trans/trans_privileged.c.inc | 18 > ++++++++++++++++++ > target/riscv/tcg/op_helper.c | 16 ++++++++++++++++ > 4 files changed, 36 insertions(+) > > diff --git a/target/riscv/helper.h b/target/riscv/helper.h > index 4fc2d3a155..b4c47d0738 100644 > --- a/target/riscv/helper.h > +++ b/target/riscv/helper.h > @@ -132,6 +132,7 @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, > tl, tl) > #ifndef CONFIG_USER_ONLY > DEF_HELPER_1(sret, tl, env) > DEF_HELPER_1(mret, tl, env) > +DEF_HELPER_1(dret, tl, env) > DEF_HELPER_1(mnret, tl, env) > DEF_HELPER_1(ctr_clear, void, env) > DEF_HELPER_1(wfi, void, env) > diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode > index aa02dae3c9..46b00411ff 100644 > --- a/target/riscv/insn32.decode > +++ b/target/riscv/insn32.decode > @@ -118,6 +118,7 @@ sctrclr 000100000100 00000 000 00000 > 1110011 > uret 0000000 00010 00000 000 00000 1110011 > sret 0001000 00010 00000 000 00000 1110011 > mret 0011000 00010 00000 000 00000 1110011 > +dret 0111101 10010 00000 000 00000 1110011 > wfi 0001000 00101 00000 000 00000 1110011 > sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma > > diff --git a/target/riscv/tcg/insn_trans/trans_privileged.c.inc > b/target/riscv/tcg/insn_trans/trans_privileged.c.inc > index a8eaccef67..4e57901880 100644 > --- a/target/riscv/tcg/insn_trans/trans_privileged.c.inc > +++ b/target/riscv/tcg/insn_trans/trans_privileged.c.inc > @@ -125,6 +125,24 @@ static bool trans_mret(DisasContext *ctx, > arg_mret *a) > #endif > } > > +static bool trans_dret(DisasContext *ctx, arg_dret *a) > +{ > +#ifndef CONFIG_USER_ONLY > + if (!ctx->cfg_ptr->ext_sdext) { > + return false; > + } > + decode_save_opc(ctx, 0); > + translator_io_start(&ctx->base); > + gen_update_pc(ctx, 0); > + gen_helper_dret(cpu_pc, tcg_env); > + exit_tb(ctx); /* no chaining */ > + ctx->base.is_jmp = DISAS_NORETURN; > + return true; > +#else > + return false; > +#endif > +} > + > static bool trans_mnret(DisasContext *ctx, arg_mnret *a) > { > #ifndef CONFIG_USER_ONLY > diff --git a/target/riscv/tcg/op_helper.c > b/target/riscv/tcg/op_helper.c > index 3e94005d2b..54269efee1 100644 > --- a/target/riscv/tcg/op_helper.c > +++ b/target/riscv/tcg/op_helper.c > @@ -473,6 +473,22 @@ target_ulong helper_mret(CPURISCVState *env) > return retpc; > } > > +target_ulong helper_dret(CPURISCVState *env) > +{ > + uintptr_t ra = GETPC(); > +#ifdef CONFIG_USER_ONLY > + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra); > + return 0; > +#else > + if (!riscv_cpu_cfg(env)->ext_sdext || !env->debug_mode) { > + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, ra); > + } > + target_ulong retpc = env->dpc & get_xepc_mask(env); > + riscv_cpu_leave_debug_mode(env); > + return retpc; > +#endif > +} > + > target_ulong helper_mnret(CPURISCVState *env) > { > target_ulong retpc = env->mnepc;
