From e77c918ff3a5aa63ad459eff6b10a6ee0647451f Mon Sep 17 00:00:00 2001 From: YenHaoChen Date: Tue, 23 Apr 2024 09:21:16 +0800 Subject: Smstateen: Ignore writes to read-only hstateen*[n] bits when mstateen*[n]=0 The specification states that writes to read-only bits in a RW CSR are ignored. The hstateen*[n] bits are read-only when mstateen*[n]=0. This PR proposes ignoring writes to read-only hstateen*[n] bits when mstateen*[n]=0 instead of writing the bits to 0. --- riscv/csrs.cc | 12 +++++++----- riscv/csrs.h | 4 +++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/riscv/csrs.cc b/riscv/csrs.cc index 4a612e5..053f9b4 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -1465,26 +1465,28 @@ bool vxsat_csr_t::unlogged_write(const reg_t val) noexcept { // implement class hstateen_csr_t hstateen_csr_t::hstateen_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init, uint8_t index): - masked_csr_t(proc, addr, mask, init), - index(index) { + basic_csr_t(proc, addr, init), + index(index), + mask(mask) { } reg_t hstateen_csr_t::read() const noexcept { // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), // the same bit appears as read-only zero in the matching hstateen and sstateen CSRs - return masked_csr_t::read() & state->mstateen[index]->read(); + return basic_csr_t::read() & state->mstateen[index]->read(); } bool hstateen_csr_t::unlogged_write(const reg_t val) noexcept { // For every bit in an mstateen CSR that is zero (whether read-only zero or set to zero), // the same bit appears as read-only zero in the matching hstateen and sstateen CSRs - return masked_csr_t::unlogged_write(val & state->mstateen[index]->read()); + const reg_t mask = this->mask & state->mstateen[index]->read(); + return basic_csr_t::unlogged_write((basic_csr_t::read() & ~mask) | (val & mask)); } void hstateen_csr_t::verify_permissions(insn_t insn, bool write) const { if ((state->prv < PRV_M) && !(state->mstateen[index]->read() & MSTATEEN_HSTATEEN)) throw trap_illegal_instruction(insn.bits()); - masked_csr_t::verify_permissions(insn, write); + basic_csr_t::verify_permissions(insn, write); } // implement class sstateen_csr_t diff --git a/riscv/csrs.h b/riscv/csrs.h index 2595243..1d1aabf 100644 --- a/riscv/csrs.h +++ b/riscv/csrs.h @@ -762,7 +762,7 @@ class vxsat_csr_t: public masked_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; }; -class hstateen_csr_t: public masked_csr_t { +class hstateen_csr_t: public basic_csr_t { public: hstateen_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init, uint8_t index); virtual reg_t read() const noexcept override; @@ -771,6 +771,8 @@ class hstateen_csr_t: public masked_csr_t { virtual bool unlogged_write(const reg_t val) noexcept override; protected: uint8_t index; + private: + const reg_t mask; }; class sstateen_csr_t: public hstateen_csr_t { -- cgit v1.1