aboutsummaryrefslogtreecommitdiff
path: root/riscv/csrs.h
diff options
context:
space:
mode:
authorScott Johnson <scott.johnson@arilinc.com>2022-07-13 09:33:36 -0700
committerScott Johnson <scott.johnson@arilinc.com>2022-07-13 18:57:55 -0700
commit85ab2228ddb802c33a967349d69b2d948846bd01 (patch)
treef10f767ca76db9903d0a9fb1169d9c833cd1804c /riscv/csrs.h
parent8f36f1a5f8a47282743706e7777a277b9f17ba6f (diff)
downloadspike-85ab2228ddb802c33a967349d69b2d948846bd01.zip
spike-85ab2228ddb802c33a967349d69b2d948846bd01.tar.gz
spike-85ab2228ddb802c33a967349d69b2d948846bd01.tar.bz2
Add proxy for accessing the low 32 bits of a 64-bit CSR
Use this for mstatus on RV32 so that `csrw mstatus` does not modify the bits in `mstatush`. Fixes #1044.
Diffstat (limited to 'riscv/csrs.h')
-rw-r--r--riscv/csrs.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/riscv/csrs.h b/riscv/csrs.h
index 3998d79..500bde7 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -54,7 +54,9 @@ class csr_t {
const unsigned csr_priv;
const bool csr_read_only;
+ // For access to written_value() and unlogged_write():
friend class rv32_high_csr_t;
+ friend class rv32_low_csr_t;
};
typedef std::shared_ptr<csr_t> csr_t_p;
@@ -249,6 +251,19 @@ class mstatus_csr_t final: public base_status_csr_t {
typedef std::shared_ptr<mstatus_csr_t> mstatus_csr_t_p;
+// For RV32 CSRs that are split into two, e.g. mstatus/mstatush
+// CSRW should only modify the lower half
+class rv32_low_csr_t: public csr_t {
+ public:
+ rv32_low_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig);
+ virtual reg_t read() const noexcept override;
+ virtual void verify_permissions(insn_t insn, bool write) const override;
+ protected:
+ virtual bool unlogged_write(const reg_t val) noexcept override;
+ private:
+ csr_t_p orig;
+};
+
class rv32_high_csr_t: public csr_t {
public:
rv32_high_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig);