From c1d797abdc3e831ca453b017e06f70c1fff46007 Mon Sep 17 00:00:00 2001 From: Binno Date: Mon, 7 Oct 2024 19:56:40 -0700 Subject: [PATCH] Implement elp state holding mechanism for mnstatus --- riscv/csrs.cc | 1 + riscv/insns/mnret.h | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 2267f7f4..3dbac7b7 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -585,6 +585,7 @@ bool mnstatus_csr_t::unlogged_write(const reg_t val) noexcept { // NMIE can be set but not cleared const reg_t mask = (~read() & MNSTATUS_NMIE) | (proc->extension_enabled('H') ? MNSTATUS_MNPV : 0) + | (proc->extension_enabled(EXT_ZICFILP) ? MNSTATUS_MNPELP : 0) | MNSTATUS_MNPP; const reg_t requested_mnpp = proc->legalize_privilege(get_field(val, MNSTATUS_MNPP)); diff --git a/riscv/insns/mnret.h b/riscv/insns/mnret.h index 30f10818..2003cbe3 100644 --- a/riscv/insns/mnret.h +++ b/riscv/insns/mnret.h @@ -10,5 +10,11 @@ if (prev_prv != PRV_M) { STATE.mstatus->write(mstatus); } s = set_field(s, MNSTATUS_NMIE, 1); +if (ZICFILP_xLPE(prev_virt, prev_prv)) { + STATE.elp = static_cast(get_field(s, MNSTATUS_MNPELP)); +} +if (p->extension_enabled(EXT_ZICFILP)) { + s = set_field(s, MNSTATUS_MNPELP, elp_t::NO_LP_EXPECTED); +} STATE.mnstatus->write(s); p->set_privilege(prev_prv, prev_virt);