From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
To: frank.chang@sifive.com, qemu-devel@nongnu.org, qemu-riscv@nongnu.org
Cc: Palmer Dabbelt <palmer@dabbelt.com>,
Alistair Francis <alistair.francis@wdc.com>,
Bin Meng <bmeng.cn@gmail.com>, Weiwei Li <liwei1518@gmail.com>,
Liu Zhiwei <zhiwei_liu@linux.alibaba.com>,
Tommy Wu <tommy.wu@sifive.com>
Subject: Re: [PATCH v10 4/7] target/riscv: Add Smrnmi mnret instruction
Date: Thu, 26 Dec 2024 09:47:30 -0300 [thread overview]
Message-ID: <24e41e24-1ca8-4a96-a727-a329acc9691a@ventanamicro.com> (raw)
In-Reply-To: <20241217062440.884261-5-frank.chang@sifive.com>
On 12/17/24 3:24 AM, frank.chang@sifive.com wrote:
> From: Tommy Wu <tommy.wu@sifive.com>
>
> This patch adds a new instruction 'mnret'. 'mnret' is an M-mode-only
> instruction that uses the values in `mnepc` and `mnstatus` to return to the
> program counter, privilege mode, and virtualization mode of the
> interrupted context.
>
> Signed-off-by: Frank Chang <frank.chang@sifive.com>
> Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
> ---
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> target/riscv/helper.h | 1 +
> target/riscv/insn32.decode | 3 ++
> .../riscv/insn_trans/trans_privileged.c.inc | 20 +++++++++
> target/riscv/op_helper.c | 45 ++++++++++++++++---
> 4 files changed, 64 insertions(+), 5 deletions(-)
>
> diff --git a/target/riscv/helper.h b/target/riscv/helper.h
> index 451261ce5a..16ea240d26 100644
> --- a/target/riscv/helper.h
> +++ b/target/riscv/helper.h
> @@ -131,6 +131,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(mnret, tl, env)
> DEF_HELPER_1(wfi, void, env)
> DEF_HELPER_1(wrs_nto, void, env)
> DEF_HELPER_1(tlb_flush, void, env)
> diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
> index e9139ec1b9..942c434c6e 100644
> --- a/target/riscv/insn32.decode
> +++ b/target/riscv/insn32.decode
> @@ -121,6 +121,9 @@ wfi 0001000 00101 00000 000 00000 1110011
> sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
> sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
>
> +# *** NMI ***
> +mnret 0111000 00010 00000 000 00000 1110011
> +
> # *** RV32I Base Instruction Set ***
> lui .................... ..... 0110111 @u
> {
> diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
> index ecd3b8b2c9..73f940d406 100644
> --- a/target/riscv/insn_trans/trans_privileged.c.inc
> +++ b/target/riscv/insn_trans/trans_privileged.c.inc
> @@ -18,6 +18,12 @@
> * this program. If not, see <http://www.gnu.org/licenses/>.
> */
>
> +#define REQUIRE_SMRNMI(ctx) do { \
> + if (!ctx->cfg_ptr->ext_smrnmi) { \
> + return false; \
> + } \
> +} while (0)
> +
> static bool trans_ecall(DisasContext *ctx, arg_ecall *a)
> {
> /* always generates U-level ECALL, fixed in do_interrupt handler */
> @@ -106,6 +112,20 @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
> #endif
> }
>
> +static bool trans_mnret(DisasContext *ctx, arg_mnret *a)
> +{
> +#ifndef CONFIG_USER_ONLY
> + REQUIRE_SMRNMI(ctx);
> + decode_save_opc(ctx, 0);
> + gen_helper_mnret(cpu_pc, tcg_env);
> + tcg_gen_exit_tb(NULL, 0); /* no chaining */
> + ctx->base.is_jmp = DISAS_NORETURN;
> + return true;
> +#else
> + return false;
> +#endif
> +}
> +
> static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
> {
> #ifndef CONFIG_USER_ONLY
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index eddedacf4b..63ec53e992 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -321,24 +321,30 @@ target_ulong helper_sret(CPURISCVState *env)
> return retpc;
> }
>
> -target_ulong helper_mret(CPURISCVState *env)
> +static void check_ret_from_m_mode(CPURISCVState *env, target_ulong retpc,
> + target_ulong prev_priv)
> {
> if (!(env->priv >= PRV_M)) {
> riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
> }
>
> - target_ulong retpc = env->mepc;
> if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
> riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
> }
>
> - uint64_t mstatus = env->mstatus;
> - target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
> -
> if (riscv_cpu_cfg(env)->pmp &&
> !pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
> riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
> }
> +}
> +
> +target_ulong helper_mret(CPURISCVState *env)
> +{
> + target_ulong retpc = env->mepc;
> + uint64_t mstatus = env->mstatus;
> + target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
> +
> + check_ret_from_m_mode(env, retpc, prev_priv);
>
> target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV) &&
> (prev_priv != PRV_M);
> @@ -370,6 +376,35 @@ target_ulong helper_mret(CPURISCVState *env)
> return retpc;
> }
>
> +target_ulong helper_mnret(CPURISCVState *env)
> +{
> + target_ulong retpc = env->mnepc;
> + target_ulong prev_priv = get_field(env->mnstatus, MNSTATUS_MNPP);
> + target_ulong prev_virt;
> +
> + check_ret_from_m_mode(env, retpc, prev_priv);
> +
> + prev_virt = get_field(env->mnstatus, MNSTATUS_MNPV) &&
> + (prev_priv != PRV_M);
> + env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, true);
> +
> + /*
> + * If MNRET changes the privilege mode to a mode
> + * less privileged than M, it also sets mstatus.MPRV to 0.
> + */
> + if (prev_priv < PRV_M) {
> + env->mstatus = set_field(env->mstatus, MSTATUS_MPRV, false);
> + }
> +
> + if (riscv_has_ext(env, RVH) && prev_virt) {
> + riscv_cpu_swap_hypervisor_regs(env);
> + }
> +
> + riscv_cpu_set_mode(env, prev_priv, prev_virt);
> +
> + return retpc;
> +}
> +
> void helper_wfi(CPURISCVState *env)
> {
> CPUState *cs = env_cpu(env);
next prev parent reply other threads:[~2024-12-26 12:48 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-17 6:24 [PATCH v10 0/7] Add Smrnmi support frank.chang
2024-12-17 6:24 ` [PATCH v10 1/7] target/riscv: Add 'ext_smrnmi' in the RISCVCPUConfig frank.chang
2024-12-17 6:24 ` [PATCH v10 2/7] target/riscv: Add Smrnmi CSRs frank.chang
2024-12-17 6:24 ` [PATCH v10 3/7] target/riscv: Handle Smrnmi interrupt and exception frank.chang
2024-12-26 12:42 ` Daniel Henrique Barboza
2024-12-31 3:11 ` Frank Chang
2024-12-31 9:19 ` Daniel Henrique Barboza
2024-12-17 6:24 ` [PATCH v10 4/7] target/riscv: Add Smrnmi mnret instruction frank.chang
2024-12-26 12:47 ` Daniel Henrique Barboza [this message]
2024-12-17 6:24 ` [PATCH v10 5/7] target/riscv: Add Smrnmi cpu extension frank.chang
2024-12-26 12:51 ` Daniel Henrique Barboza
2024-12-17 6:24 ` [PATCH v10 6/7] target/riscv: Add Zicfilp support for Smrnmi frank.chang
2024-12-26 12:53 ` Daniel Henrique Barboza
2024-12-17 6:24 ` [PATCH v10 7/7] target/riscv: Disable Smrnmi for the 'max' type CPU frank.chang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=24e41e24-1ca8-4a96-a727-a329acc9691a@ventanamicro.com \
--to=dbarboza@ventanamicro.com \
--cc=alistair.francis@wdc.com \
--cc=bmeng.cn@gmail.com \
--cc=frank.chang@sifive.com \
--cc=liwei1518@gmail.com \
--cc=palmer@dabbelt.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-riscv@nongnu.org \
--cc=tommy.wu@sifive.com \
--cc=zhiwei_liu@linux.alibaba.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.