aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYenHaoChen <howard25336284@gmail.com>2024-04-23 09:21:16 +0800
committerYenHaoChen <howard25336284@gmail.com>2024-04-23 09:55:45 +0800
commite77c918ff3a5aa63ad459eff6b10a6ee0647451f (patch)
tree2a668535cb56818d98822a698c044bc393ea9a84
parent4196bc8fafadb643671a0d92a7b32ac84457dc8d (diff)
downloadriscv-isa-sim-e77c918ff3a5aa63ad459eff6b10a6ee0647451f.zip
riscv-isa-sim-e77c918ff3a5aa63ad459eff6b10a6ee0647451f.tar.gz
riscv-isa-sim-e77c918ff3a5aa63ad459eff6b10a6ee0647451f.tar.bz2
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.
-rw-r--r--riscv/csrs.cc12
-rw-r--r--riscv/csrs.h4
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 {