aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeiwei Li <liweiwei@iscas.ac.cn>2022-07-08 20:30:02 +0800
committerWeiwei Li <liweiwei@iscas.ac.cn>2022-07-21 08:50:26 +0800
commit3ff1b5f1c6c6e13777be1c677abc2340f3dabd1a (patch)
treeb5c4481531b8da56e2aa4ef5473c148ef0b9f177
parent28ee0c4d6a1ed221f1a05ba48f54023ac7d455cc (diff)
downloadriscv-isa-sim-3ff1b5f1c6c6e13777be1c677abc2340f3dabd1a.zip
riscv-isa-sim-3ff1b5f1c6c6e13777be1c677abc2340f3dabd1a.tar.gz
riscv-isa-sim-3ff1b5f1c6c6e13777be1c677abc2340f3dabd1a.tar.bz2
add support for time/timeh/htimedelta/htimedeltah csrs
-rw-r--r--riscv/clint.cc1
-rw-r--r--riscv/csrs.cc19
-rw-r--r--riscv/csrs.h15
-rw-r--r--riscv/processor.cc11
-rw-r--r--riscv/processor.h3
5 files changed, 49 insertions, 0 deletions
diff --git a/riscv/clint.cc b/riscv/clint.cc
index 72d1bbe..3f2d4d7 100644
--- a/riscv/clint.cc
+++ b/riscv/clint.cc
@@ -82,6 +82,7 @@ void clint_t::increment(reg_t inc)
mtime += inc;
}
for (size_t i = 0; i < procs.size(); i++) {
+ procs[i]->state.time->sync(mtime);
procs[i]->state.mip->backdoor_write_with_mask(MIP_MTIP, 0);
if (mtime >= mtimecmp[i])
procs[i]->state.mip->backdoor_write_with_mask(MIP_MTIP, MIP_MTIP);
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 9721f87..8cb9953 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -946,6 +946,25 @@ reg_t wide_counter_csr_t::written_value() const noexcept {
return this->val + 1;
}
+// implement class time_counter_csr_t
+time_counter_csr_t::time_counter_csr_t(processor_t* const proc, const reg_t addr):
+ csr_t(proc, addr),
+ shadow_val(0) {
+}
+
+reg_t time_counter_csr_t::read() const noexcept {
+ // reading the time CSR in VS or VU mode returns the sum of the contents of
+ // htimedelta and the actual value of time.
+ if (state->v)
+ return shadow_val + state->htimedelta->read();
+ else
+ return shadow_val;
+}
+
+void time_counter_csr_t::sync(const reg_t val) noexcept {
+ shadow_val = val;
+}
+
proxy_csr_t::proxy_csr_t(processor_t* const proc, const reg_t addr, csr_t_p delegate):
csr_t(proc, addr),
delegate(delegate) {
diff --git a/riscv/csrs.h b/riscv/csrs.h
index 8108d1e..34bc9d0 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -509,6 +509,21 @@ class wide_counter_csr_t: public csr_t {
typedef std::shared_ptr<wide_counter_csr_t> wide_counter_csr_t_p;
+class time_counter_csr_t: public csr_t {
+ public:
+ time_counter_csr_t(processor_t* const proc, const reg_t addr);
+ virtual reg_t read() const noexcept override;
+
+ void sync(const reg_t val) noexcept;
+
+ protected:
+ virtual bool unlogged_write(const reg_t val) noexcept override { return false; };
+ private:
+ reg_t shadow_val;
+};
+
+typedef std::shared_ptr<time_counter_csr_t> time_counter_csr_t_p;
+
// For a CSR that is an alias of another
class proxy_csr_t: public csr_t {
public:
diff --git a/riscv/processor.cc b/riscv/processor.cc
index c351d1d..642f1fb 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -204,9 +204,11 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
csrmap[CSR_MCAUSE] = mcause = std::make_shared<cause_csr_t>(proc, CSR_MCAUSE);
minstret = std::make_shared<wide_counter_csr_t>(proc, CSR_MINSTRET);
mcycle = std::make_shared<wide_counter_csr_t>(proc, CSR_MCYCLE);
+ time = std::make_shared<time_counter_csr_t>(proc, CSR_TIME);
if (proc->extension_enabled_const(EXT_ZICNTR)) {
csrmap[CSR_INSTRET] = std::make_shared<counter_proxy_csr_t>(proc, CSR_INSTRET, minstret);
csrmap[CSR_CYCLE] = std::make_shared<counter_proxy_csr_t>(proc, CSR_CYCLE, mcycle);
+ csrmap[CSR_TIME] = std::make_shared<counter_proxy_csr_t>(proc, CSR_TIME, time);
}
if (xlen == 32) {
csr_t_p minstreth, mcycleh;
@@ -215,8 +217,10 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
csrmap[CSR_MCYCLE] = std::make_shared<rv32_low_csr_t>(proc, CSR_MCYCLE, mcycle);
csrmap[CSR_MCYCLEH] = mcycleh = std::make_shared<rv32_high_csr_t>(proc, CSR_MCYCLEH, mcycle);
if (proc->extension_enabled_const(EXT_ZICNTR)) {
+ auto timeh = std::make_shared<rv32_high_csr_t>(proc, CSR_TIMEH, time);
csrmap[CSR_INSTRETH] = std::make_shared<counter_proxy_csr_t>(proc, CSR_INSTRETH, minstreth);
csrmap[CSR_CYCLEH] = std::make_shared<counter_proxy_csr_t>(proc, CSR_CYCLEH, mcycleh);
+ csrmap[CSR_TIMEH] = std::make_shared<counter_proxy_csr_t>(proc, CSR_TIMEH, timeh);
}
} else {
csrmap[CSR_MINSTRET] = minstret;
@@ -349,6 +353,13 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
(1 << CAUSE_STORE_PAGE_FAULT);
csrmap[CSR_HEDELEG] = hedeleg = std::make_shared<masked_csr_t>(proc, CSR_HEDELEG, hedeleg_mask, 0);
csrmap[CSR_HCOUNTEREN] = hcounteren = std::make_shared<masked_csr_t>(proc, CSR_HCOUNTEREN, counteren_mask, 0);
+ htimedelta = std::make_shared<basic_csr_t>(proc, CSR_HTIMEDELTA, 0);
+ if (xlen == 32) {
+ csrmap[CSR_HTIMEDELTA] = std::make_shared<rv32_low_csr_t>(proc, CSR_HTIMEDELTA, htimedelta);
+ csrmap[CSR_HTIMEDELTAH] = std::make_shared<rv32_high_csr_t>(proc, CSR_HTIMEDELTAH, htimedelta);
+ } else {
+ csrmap[CSR_HTIMEDELTA] = htimedelta;
+ }
csrmap[CSR_HTVAL] = htval = std::make_shared<basic_csr_t>(proc, CSR_HTVAL, 0);
csrmap[CSR_HTINST] = htinst = std::make_shared<basic_csr_t>(proc, CSR_HTINST, 0);
csrmap[CSR_HGATP] = hgatp = std::make_shared<hgatp_csr_t>(proc, CSR_HGATP);
diff --git a/riscv/processor.h b/riscv/processor.h
index 347ae16..b415402 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -191,6 +191,9 @@ struct state_t
csr_t_p sstateen[4];
csr_t_p hstateen[4];
+ csr_t_p htimedelta;
+ time_counter_csr_t_p time;
+
bool serialized; // whether timer CSRs are in a well-defined state
// When true, execute a single instruction and then enter debug mode. This