aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <andrew@sifive.com>2023-05-24 13:51:34 -0700
committerAndrew Waterman <andrew@sifive.com>2023-05-25 14:35:42 -0700
commitd99efb545cca366a159dc1dedcbbd08fa2b3b8cf (patch)
tree56933e75e6963c14080a179315b48ac0ca6895e4
parente910707051c4e10889f58229443bf9d41652ed7b (diff)
downloadriscv-isa-sim-d99efb545cca366a159dc1dedcbbd08fa2b3b8cf.zip
riscv-isa-sim-d99efb545cca366a159dc1dedcbbd08fa2b3b8cf.tar.gz
riscv-isa-sim-d99efb545cca366a159dc1dedcbbd08fa2b3b8cf.tar.bz2
Implement dcsr.v and make DRET use it
Resolves #1365
-rw-r--r--riscv/csrs.cc8
-rw-r--r--riscv/csrs.h3
-rw-r--r--riscv/insns/dret.h1
-rw-r--r--riscv/processor.cc2
4 files changed, 11 insertions, 3 deletions
diff --git a/riscv/csrs.cc b/riscv/csrs.cc
index 9a165eb..95b5e22 100644
--- a/riscv/csrs.cc
+++ b/riscv/csrs.cc
@@ -13,6 +13,8 @@
#include "trap.h"
// For require():
#include "insn_macros.h"
+// For CSR_DCSR_V:
+#include "debug_defines.h"
// STATE macro used by require_privilege() macro:
#undef STATE
@@ -1234,6 +1236,7 @@ dcsr_csr_t::dcsr_csr_t(processor_t* const proc, const reg_t addr):
ebreaks(false),
ebreaku(false),
halt(false),
+ v(false),
cause(0) {
}
@@ -1255,6 +1258,7 @@ reg_t dcsr_csr_t::read() const noexcept {
result = set_field(result, DCSR_CAUSE, cause);
result = set_field(result, DCSR_STEP, step);
result = set_field(result, DCSR_PRV, prv);
+ result = set_field(result, CSR_DCSR_V, v);
return result;
}
@@ -1267,12 +1271,14 @@ bool dcsr_csr_t::unlogged_write(const reg_t val) noexcept {
ebreaks = get_field(val, DCSR_EBREAKS);
ebreaku = get_field(val, DCSR_EBREAKU);
halt = get_field(val, DCSR_HALT);
+ v = proc->extension_enabled('H') ? get_field(val, CSR_DCSR_V) : false;
return true;
}
-void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv) noexcept {
+void dcsr_csr_t::write_cause_and_prv(uint8_t cause, reg_t prv, bool v) noexcept {
this->cause = cause;
this->prv = prv;
+ this->v = v;
log_write();
}
diff --git a/riscv/csrs.h b/riscv/csrs.h
index 65be799..19aefca 100644
--- a/riscv/csrs.h
+++ b/riscv/csrs.h
@@ -656,7 +656,7 @@ class dcsr_csr_t: public csr_t {
dcsr_csr_t(processor_t* const proc, const reg_t addr);
virtual void verify_permissions(insn_t insn, bool write) const override;
virtual reg_t read() const noexcept override;
- void write_cause_and_prv(uint8_t cause, reg_t prv) noexcept;
+ void write_cause_and_prv(uint8_t cause, reg_t prv, bool v) noexcept;
protected:
virtual bool unlogged_write(const reg_t val) noexcept override;
public:
@@ -667,6 +667,7 @@ class dcsr_csr_t: public csr_t {
bool ebreaks;
bool ebreaku;
bool halt;
+ bool v;
uint8_t cause;
};
diff --git a/riscv/insns/dret.h b/riscv/insns/dret.h
index 56ce25b..0540c51 100644
--- a/riscv/insns/dret.h
+++ b/riscv/insns/dret.h
@@ -1,6 +1,7 @@
require(STATE.debug_mode);
set_pc_and_serialize(STATE.dpc->read());
p->set_privilege(STATE.dcsr->prv);
+p->set_virt(STATE.dcsr->v);
if (STATE.prv < PRV_M)
STATE.mstatus->write(STATE.mstatus->read() & ~MSTATUS_MPRV);
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 23284b8..3d13f4e 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -763,7 +763,7 @@ void processor_t::set_virt(bool virt)
void processor_t::enter_debug_mode(uint8_t cause)
{
state.debug_mode = true;
- state.dcsr->write_cause_and_prv(cause, state.prv);
+ state.dcsr->write_cause_and_prv(cause, state.prv, state.v);
set_privilege(PRV_M);
state.dpc->write(state.pc);
state.pc = DEBUG_ROM_ENTRY;