aboutsummaryrefslogtreecommitdiff
path: root/riscv/csrs.h
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/csrs.h')
-rw-r--r--riscv/csrs.h22
1 files changed, 21 insertions, 1 deletions
diff --git a/riscv/csrs.h b/riscv/csrs.h
index cf48673..5ca7e15 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -15,6 +15,8 @@
// For access_type:
#include "memtracer.h"
#include <cassert>
+// For std::optional
+#include <optional>
class processor_t;
struct state_t;
@@ -516,12 +518,16 @@ class virtualized_satp_csr_t: public virtualized_csr_t {
satp_csr_t_p orig_satp;
};
+// Forward declaration
+class smcntrpmf_csr_t;
+typedef std::shared_ptr<smcntrpmf_csr_t> smcntrpmf_csr_t_p;
+
// For minstret and mcycle, which are always 64 bits, but in RV32 are
// split into high and low halves. The first class always holds the
// full 64-bit value.
class wide_counter_csr_t: public csr_t {
public:
- wide_counter_csr_t(processor_t* const proc, const reg_t addr);
+ wide_counter_csr_t(processor_t* const proc, const reg_t addr, smcntrpmf_csr_t_p config_csr);
// Always returns full 64-bit value
virtual reg_t read() const noexcept override;
void bump(const reg_t howmuch) noexcept;
@@ -529,7 +535,9 @@ class wide_counter_csr_t: public csr_t {
virtual bool unlogged_write(const reg_t val) noexcept override;
virtual reg_t written_value() const noexcept override;
private:
+ bool is_counting_enabled() const noexcept;
reg_t val;
+ smcntrpmf_csr_t_p config_csr;
};
typedef std::shared_ptr<wide_counter_csr_t> wide_counter_csr_t_p;
@@ -822,4 +830,16 @@ class sscsrind_reg_csr_t : public csr_t {
csr_t_p get_reg() const noexcept;
};
+// smcntrpmf_csr_t caches the previous state of the CSR in case a CSRW instruction
+// modifies the state that should not be immediately visible to bump()
+class smcntrpmf_csr_t : public masked_csr_t {
+ public:
+ smcntrpmf_csr_t(processor_t* const proc, const reg_t addr, const reg_t mask, const reg_t init);
+ reg_t read_prev() const noexcept;
+ void reset_prev() noexcept;
+ protected:
+ virtual bool unlogged_write(const reg_t val) noexcept override;
+ private:
+ std::optional<reg_t> prev_val;
+};
#endif