diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 058e73c1..4ab1331a 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1851,3 +1851,16 @@ void mtval2_csr_t::verify_permissions(insn_t insn, bool write) const { if (!proc->extension_enabled('H') && !proc->extension_enabled(EXT_SSDBLTRP)) throw trap_illegal_instruction(insn.bits()); } + +hstatus_csr_t::hstatus_csr_t(processor_t* const proc, const reg_t addr): + basic_csr_t(proc, addr, set_field((reg_t)0, HSTATUS_VSXL, xlen_to_uxl(proc->get_const_xlen()))) { +} + +bool hstatus_csr_t::unlogged_write(const reg_t val) noexcept { + const reg_t mask = HSTATUS_VTSR | HSTATUS_VTW + | (proc->supports_impl(IMPL_MMU) ? HSTATUS_VTVM : 0) + | HSTATUS_HU | HSTATUS_SPVP | HSTATUS_SPV | HSTATUS_GVA; + + const reg_t new_hstatus = (read() & ~mask) | (val & mask); + return basic_csr_t::unlogged_write(new_hstatus); +} diff --git a/riscv/csrs.h b/riscv/csrs.h index dc89963c..db61fba9 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -891,4 +891,11 @@ class mtval2_csr_t: public hypervisor_csr_t { mtval2_csr_t(processor_t* const proc, const reg_t addr); virtual void verify_permissions(insn_t insn, bool write) const override; }; + +class hstatus_csr_t final: public basic_csr_t { + public: + hstatus_csr_t(processor_t* const proc, const reg_t addr); + protected: + virtual bool unlogged_write(const reg_t val) noexcept override; +}; #endif diff --git a/riscv/processor.cc b/riscv/processor.cc index a3b55b46..418599b0 100644 --- a/riscv/processor.cc +++ b/riscv/processor.cc @@ -297,11 +297,7 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) csrmap[CSR_SCAUSE] = scause = std::make_shared(proc, nonvirtual_scause, vscause); csrmap[CSR_MTVAL2] = mtval2 = std::make_shared(proc, CSR_MTVAL2); csrmap[CSR_MTINST] = mtinst = std::make_shared(proc, CSR_MTINST); - const reg_t hstatus_init = set_field((reg_t)0, HSTATUS_VSXL, xlen_to_uxl(proc->get_const_xlen())); - const reg_t hstatus_mask = HSTATUS_VTSR | HSTATUS_VTW - | (proc->supports_impl(IMPL_MMU) ? HSTATUS_VTVM : 0) - | HSTATUS_HU | HSTATUS_SPVP | HSTATUS_SPV | HSTATUS_GVA; - csrmap[CSR_HSTATUS] = hstatus = std::make_shared(proc, CSR_HSTATUS, hstatus_mask, hstatus_init); + csrmap[CSR_HSTATUS] = hstatus = std::make_shared(proc, CSR_HSTATUS); csrmap[CSR_HGEIE] = std::make_shared(proc, CSR_HGEIE, 0); csrmap[CSR_HGEIP] = std::make_shared(proc, CSR_HGEIP, 0); csrmap[CSR_HIDELEG] = hideleg = std::make_shared(proc, CSR_HIDELEG, mideleg);