aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWeiwei Li <liweiwei@iscas.ac.cn>2022-07-08 18:34:13 +0800
committerWeiwei Li <liweiwei@iscas.ac.cn>2022-07-21 08:50:23 +0800
commit28ee0c4d6a1ed221f1a05ba48f54023ac7d455cc (patch)
treed7bcb889ac5757ee84eb2a09a86cbad96c4db18e
parentd02b285c8858e33c7f9a79207127c8374c4ddc62 (diff)
downloadspike-28ee0c4d6a1ed221f1a05ba48f54023ac7d455cc.zip
spike-28ee0c4d6a1ed221f1a05ba48f54023ac7d455cc.tar.gz
spike-28ee0c4d6a1ed221f1a05ba48f54023ac7d455cc.tar.bz2
modify minstret/mcycle/minstreth/mcycleh to reuse rv32_low/high_csr_t
-rw-r--r--riscv/csrs.cc34
-rw-r--r--riscv/csrs.h16
-rw-r--r--riscv/processor.cc15
3 files changed, 21 insertions, 44 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 6f8f260..9721f87 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -515,6 +515,10 @@ bool rv32_low_csr_t::unlogged_write(const reg_t val) noexcept {
return orig->unlogged_write((orig->written_value() >> 32 << 32) | (val & 0xffffffffU));
}
+reg_t rv32_low_csr_t::written_value() const noexcept {
+ return orig->written_value() & 0xffffffffU;
+}
+
// implement class rv32_high_csr_t
rv32_high_csr_t::rv32_high_csr_t(processor_t* const proc, const reg_t addr, csr_t_p orig):
csr_t(proc, addr),
@@ -533,6 +537,10 @@ bool rv32_high_csr_t::unlogged_write(const reg_t val) noexcept {
return orig->unlogged_write((orig->written_value() << 32 >> 32) | ((val & 0xffffffffU) << 32));
}
+reg_t rv32_high_csr_t::written_value() const noexcept {
+ return (orig->written_value() >> 32) & 0xffffffffU;
+}
+
// implement class sstatus_csr_t
sstatus_csr_t::sstatus_csr_t(processor_t* const proc, sstatus_proxy_csr_t_p orig, vsstatus_csr_t_p virt):
virtualized_csr_t(proc, orig, virt),
@@ -924,10 +932,7 @@ void wide_counter_csr_t::bump(const reg_t howmuch) noexcept {
}
bool wide_counter_csr_t::unlogged_write(const reg_t val) noexcept {
- if (proc->get_xlen() == 32)
- this->val = (this->val >> 32 << 32) | (val & 0xffffffffU);
- else
- this->val = val;
+ this->val = val;
// The ISA mandates that if an instruction writes instret, the write
// takes precedence over the increment to instret. However, Spike
// unconditionally increments instret after executing an instruction.
@@ -941,27 +946,6 @@ reg_t wide_counter_csr_t::written_value() const noexcept {
return this->val + 1;
}
-void wide_counter_csr_t::write_upper_half(const reg_t val) noexcept {
- this->val = (val << 32) | (this->val << 32 >> 32);
- this->val--; // See comment above.
- // Log upper half only.
- log_special_write(address + (CSR_MINSTRETH - CSR_MINSTRET), written_value() >> 32);
-}
-
-counter_top_csr_t::counter_top_csr_t(processor_t* const proc, const reg_t addr, wide_counter_csr_t_p parent):
- csr_t(proc, addr),
- parent(parent) {
-}
-
-reg_t counter_top_csr_t::read() const noexcept {
- return parent->read() >> 32;
-}
-
-bool counter_top_csr_t::unlogged_write(const reg_t val) noexcept {
- parent->write_upper_half(val);
- return true;
-}
-
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 500bde7..8108d1e 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -260,6 +260,7 @@ class rv32_low_csr_t: public csr_t {
virtual void verify_permissions(insn_t insn, bool write) const override;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
+ virtual reg_t written_value() const noexcept override;
private:
csr_t_p orig;
};
@@ -271,6 +272,7 @@ class rv32_high_csr_t: public csr_t {
virtual void verify_permissions(insn_t insn, bool write) const override;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
+ virtual reg_t written_value() const noexcept override;
private:
csr_t_p orig;
};
@@ -498,7 +500,6 @@ class wide_counter_csr_t: public csr_t {
// Always returns full 64-bit value
virtual reg_t read() const noexcept override;
void bump(const reg_t howmuch) noexcept;
- void write_upper_half(const reg_t val) noexcept;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
virtual reg_t written_value() const noexcept override;
@@ -508,19 +509,6 @@ class wide_counter_csr_t: public csr_t {
typedef std::shared_ptr<wide_counter_csr_t> wide_counter_csr_t_p;
-// A simple proxy to read/write the upper half of minstret/mcycle
-class counter_top_csr_t: public csr_t {
- public:
- counter_top_csr_t(processor_t* const proc, const reg_t addr, wide_counter_csr_t_p parent);
- virtual reg_t read() const noexcept override;
- protected:
- virtual bool unlogged_write(const reg_t val) noexcept override;
- private:
- wide_counter_csr_t_p parent;
-};
-
-typedef std::shared_ptr<counter_top_csr_t> counter_top_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 8f77b47..c351d1d 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -202,20 +202,25 @@ void state_t::reset(processor_t* const proc, reg_t max_isa)
csrmap[CSR_MSCRATCH] = std::make_shared<basic_csr_t>(proc, CSR_MSCRATCH, 0);
csrmap[CSR_MTVEC] = mtvec = std::make_shared<tvec_csr_t>(proc, CSR_MTVEC);
csrmap[CSR_MCAUSE] = mcause = std::make_shared<cause_csr_t>(proc, CSR_MCAUSE);
- csrmap[CSR_MINSTRET] = minstret = std::make_shared<wide_counter_csr_t>(proc, CSR_MINSTRET);
- csrmap[CSR_MCYCLE] = mcycle = std::make_shared<wide_counter_csr_t>(proc, CSR_MCYCLE);
+ minstret = std::make_shared<wide_counter_csr_t>(proc, CSR_MINSTRET);
+ mcycle = std::make_shared<wide_counter_csr_t>(proc, CSR_MCYCLE);
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);
}
if (xlen == 32) {
- counter_top_csr_t_p minstreth, mcycleh;
- csrmap[CSR_MINSTRETH] = minstreth = std::make_shared<counter_top_csr_t>(proc, CSR_MINSTRETH, minstret);
- csrmap[CSR_MCYCLEH] = mcycleh = std::make_shared<counter_top_csr_t>(proc, CSR_MCYCLEH, mcycle);
+ csr_t_p minstreth, mcycleh;
+ csrmap[CSR_MINSTRET] = std::make_shared<rv32_low_csr_t>(proc, CSR_MINSTRET, minstret);
+ csrmap[CSR_MINSTRETH] = minstreth = std::make_shared<rv32_high_csr_t>(proc, CSR_MINSTRETH, minstret);
+ 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)) {
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);
}
+ } else {
+ csrmap[CSR_MINSTRET] = minstret;
+ csrmap[CSR_MCYCLE] = mcycle;
}
for (reg_t i = 3; i <= 31; ++i) {
const reg_t which_mevent = CSR_MHPMEVENT3 + i - 3;