From bd45f592f65a82da35780f04a1dd8be44ae37d8e Mon Sep 17 00:00:00 2001 From: YenHaoChen Date: Fri, 22 Dec 2023 10:16:22 +0800 Subject: [PATCH 1/3] Implement mstateen0[57] for hcontext and scontext --- riscv/csrs.cc | 16 ++++++++++++++++ riscv/csrs.h | 6 ++++++ riscv/processor.cc | 6 +++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 4783646991..c8526f4c7f 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1614,6 +1614,22 @@ void jvt_csr_t::verify_permissions(insn_t insn, bool write) const { } } +context_csr_t::context_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init): + masked_csr_t(proc, addr, mask, init) { +} + +void context_csr_t::verify_permissions(insn_t insn, bool write) const { + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HCONTEXT)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SCONTEXT)) + throw trap_virtual_instruction(insn.bits()); + } + + basic_csr_t::verify_permissions(insn, write); +} + virtualized_indirect_csr_t::virtualized_indirect_csr_t(processor_t* const proc, csr_t_p orig, csr_t_p virt): virtualized_csr_t(proc, orig, virt) { } diff --git a/riscv/csrs.h b/riscv/csrs.h index 887749a613..53fa5f94c3 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -808,6 +808,12 @@ class jvt_csr_t: public basic_csr_t { virtual void verify_permissions(insn_t insn, bool write) const override; }; +class context_csr_t: public masked_csr_t { + public: + context_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; + // Sscsrind registers needs permissions checked // (the original virtualized_csr_t does not call verify_permission of the underlying CSRs) class virtualized_indirect_csr_t: public virtualized_csr_t { diff --git a/riscv/processor.cc b/riscv/processor.cc index 1bb1fc9e95..0d0caf6763 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -418,9 +418,9 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_TINFO] = std::make_shared(proc, CSR_TINFO, 0); } unsigned scontext_length = (xlen == 32 ? 16 : 34); // debug spec suggests 16-bit for RV32 and 34-bit for RV64 - csrmap[CSR_SCONTEXT] = scontext = std::make_shared(proc, CSR_SCONTEXT, (reg_t(1) << scontext_length) - 1, 0); + csrmap[CSR_SCONTEXT] = scontext = std::make_shared(proc, CSR_SCONTEXT, (reg_t(1) << scontext_length) - 1, 0); unsigned hcontext_length = (xlen == 32 ? 6 : 13) + (proc->extension_enabled('H') ? 1 : 0); // debug spec suggest 7-bit (6-bit) for RV32 and 14-bit (13-bit) for RV64 with (without) H extension - csrmap[CSR_HCONTEXT] = std::make_shared(proc, CSR_HCONTEXT, (reg_t(1) << hcontext_length) - 1, 0); + csrmap[CSR_HCONTEXT] = std::make_shared(proc, CSR_HCONTEXT, (reg_t(1) << hcontext_length) - 1, 0); csrmap[CSR_MCONTEXT] = mcontext = std::make_shared(proc, CSR_MCONTEXT, csrmap[CSR_HCONTEXT]); debug_mode = false; single_step = STEP_NONE; @@ -482,7 +482,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) const reg_t sstateen0_mask = (proc->extension_enabled(EXT_ZFINX) ? SSTATEEN0_FCSR : 0) | (proc->extension_enabled(EXT_ZCMT) ? SSTATEEN0_JVT : 0) | SSTATEEN0_CS; - const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN; + const reg_t hstateen0_mask = sstateen0_mask | HSTATEEN0_SCONTEXT | HSTATEEN0_SENVCFG | HSTATEEN_SSTATEEN; const reg_t mstateen0_mask = hstateen0_mask; for (int i = 0; i < 4; i++) { const reg_t mstateen_mask = i == 0 ? mstateen0_mask : MSTATEEN_HSTATEEN; From a93755f7db87c30f89153a9645ae50b55629f273 Mon Sep 17 00:00:00 2001 From: YenHaoChen Date: Mon, 25 Dec 2023 14:20:14 +0800 Subject: [PATCH 2/3] Disallow accessing mcontext if mstateen0[57] is 0 --- riscv/csrs.cc | 16 ++++++++++++++++ riscv/csrs.h | 6 ++++++ riscv/processor.cc | 2 +- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index c8526f4c7f..3e6d1df462 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1127,6 +1127,22 @@ void counter_proxy_csr_t::verify_permissions(insn_t insn, bool write) const { } } +context_proxy_csr_t::context_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate): + proxy_csr_t(proc, addr, delegate) { +} + +void context_proxy_csr_t::verify_permissions(insn_t insn, bool write) const { + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HCONTEXT)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SCONTEXT)) + throw trap_virtual_instruction(insn.bits()); + } + + proxy_csr_t::verify_permissions(insn, write); +} + mevent_csr_t::mevent_csr_t(processor_t* const proc, const reg_t addr): basic_csr_t(proc, addr, 0) { } diff --git a/riscv/csrs.h b/riscv/csrs.h index 53fa5f94c3..27ba54a1f2 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -588,6 +588,12 @@ class counter_proxy_csr_t: public proxy_csr_t { bool myenable(csr_t_p counteren) const noexcept; }; +class context_proxy_csr_t: public proxy_csr_t { + public: + context_proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; + class mevent_csr_t: public basic_csr_t { public: mevent_csr_t(processor_t* const proc, const reg_t addr); diff --git a/riscv/processor.cc b/riscv/processor.cc index 0d0caf6763..4f3f774d81 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -421,7 +421,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_SCONTEXT] = scontext = std::make_shared(proc, CSR_SCONTEXT, (reg_t(1) << scontext_length) - 1, 0); unsigned hcontext_length = (xlen == 32 ? 6 : 13) + (proc->extension_enabled('H') ? 1 : 0); // debug spec suggest 7-bit (6-bit) for RV32 and 14-bit (13-bit) for RV64 with (without) H extension csrmap[CSR_HCONTEXT] = std::make_shared(proc, CSR_HCONTEXT, (reg_t(1) << hcontext_length) - 1, 0); - csrmap[CSR_MCONTEXT] = mcontext = std::make_shared(proc, CSR_MCONTEXT, csrmap[CSR_HCONTEXT]); + csrmap[CSR_MCONTEXT] = mcontext = std::make_shared(proc, CSR_MCONTEXT, csrmap[CSR_HCONTEXT]); debug_mode = false; single_step = STEP_NONE; From 546cc85e2b7e7c807f9d066219f695ebf53da030 Mon Sep 17 00:00:00 2001 From: YenHaoChen Date: Fri, 22 Dec 2023 10:32:45 +0800 Subject: [PATCH 3/3] Implement mscontext CSR --- riscv/csrs.cc | 25 +++++++++++++++++++++++++ riscv/csrs.h | 6 ++++++ riscv/processor.cc | 1 + 3 files changed, 32 insertions(+) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 3e6d1df462..e76b153a96 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1268,6 +1268,31 @@ void debug_mode_csr_t::verify_permissions(insn_t insn, bool write) const { throw trap_illegal_instruction(insn.bits()); } +mscontext_csr_t::mscontext_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate): + proxy_csr_t(proc, addr, delegate) { +} + +void mscontext_csr_t::verify_permissions(insn_t insn, bool write) const { + if (proc->extension_enabled(EXT_SMSTATEEN)) { + if ((state->prv < PRV_M) && !(state->mstateen[0]->read() & MSTATEEN0_HCONTEXT)) + throw trap_illegal_instruction(insn.bits()); + + if (state->v && !(state->hstateen[0]->read() & HSTATEEN0_SCONTEXT)) + throw trap_virtual_instruction(insn.bits()); + } + + // Address of mscontext does not conform to the CSR conventions, i.e., csr_priv == PRV_S + if (!proc->extension_enabled('S')) + throw trap_illegal_instruction(insn.bits()); + + unsigned priv = state->prv == PRV_S && !state->v ? PRV_HS : state->prv; + if (priv < PRV_S) { + if (state->v) + throw trap_virtual_instruction(insn.bits()); + throw trap_illegal_instruction(insn.bits()); + } +} + dpc_csr_t::dpc_csr_t(processor_t* const proc, const reg_t addr): epc_csr_t(proc, addr) { } diff --git a/riscv/csrs.h b/riscv/csrs.h index 27ba54a1f2..3715b39306 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -670,6 +670,12 @@ class debug_mode_csr_t: public basic_csr_t { virtual void verify_permissions(insn_t insn, bool write) const override; }; +class mscontext_csr_t: public proxy_csr_t { + public: + mscontext_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate); + virtual void verify_permissions(insn_t insn, bool write) const override; +}; + class dpc_csr_t: public epc_csr_t { public: dpc_csr_t(processor_t* const proc, const reg_t addr); diff --git a/riscv/processor.cc b/riscv/processor.cc index 4f3f774d81..aec6adcacf 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -422,6 +422,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) unsigned hcontext_length = (xlen == 32 ? 6 : 13) + (proc->extension_enabled('H') ? 1 : 0); // debug spec suggest 7-bit (6-bit) for RV32 and 14-bit (13-bit) for RV64 with (without) H extension csrmap[CSR_HCONTEXT] = std::make_shared(proc, CSR_HCONTEXT, (reg_t(1) << hcontext_length) - 1, 0); csrmap[CSR_MCONTEXT] = mcontext = std::make_shared(proc, CSR_MCONTEXT, csrmap[CSR_HCONTEXT]); + csrmap[CSR_MSCONTEXT] = std::make_shared(proc, CSR_MSCONTEXT, scontext); debug_mode = false; single_step = STEP_NONE;