diff --git a/incl/iss/arch/riscv_hart_m_p.h b/incl/iss/arch/riscv_hart_m_p.h
index 181dd18..b266bae 100644
--- a/incl/iss/arch/riscv_hart_m_p.h
+++ b/incl/iss/arch/riscv_hart_m_p.h
@@ -284,6 +284,7 @@ private:
iss::status read_time(unsigned addr, reg_t &val);
iss::status read_status(unsigned addr, reg_t &val);
iss::status write_status(unsigned addr, reg_t val);
+ iss::status write_cause(unsigned addr, reg_t val);
iss::status read_ie(unsigned addr, reg_t &val);
iss::status write_ie(unsigned addr, reg_t val);
iss::status read_ip(unsigned addr, reg_t &val);
@@ -353,6 +354,7 @@ riscv_hart_m_p::riscv_hart_m_p()
csr_wr_cb[minstreth] = &this_class::write_instret;
csr_rd_cb[mstatus] = &this_class::read_status;
csr_wr_cb[mstatus] = &this_class::write_status;
+ csr_wr_cb[mcause] = &this_class::write_cause;
csr_rd_cb[mip] = &this_class::read_ip;
csr_wr_cb[mip] = &this_class::write_ip;
csr_rd_cb[mie] = &this_class::read_ie;
@@ -716,6 +718,11 @@ template iss::status riscv_hart_m_p::write_status(unsigned
return iss::Ok;
}
+template iss::status riscv_hart_m_p::write_cause(unsigned addr, reg_t val) {
+ csr[mcause] = val & ((1UL<<(traits::XLEN-1))|0xf); //TODO: make exception code size configurable
+ return iss::Ok;
+}
+
template iss::status riscv_hart_m_p::read_ie(unsigned addr, reg_t &val) {
val = csr[mie];
return iss::Ok;
diff --git a/incl/iss/arch/riscv_hart_msu_vp.h b/incl/iss/arch/riscv_hart_msu_vp.h
index f43d0e0..853a519 100644
--- a/incl/iss/arch/riscv_hart_msu_vp.h
+++ b/incl/iss/arch/riscv_hart_msu_vp.h
@@ -392,6 +392,7 @@ private:
iss::status read_time(unsigned addr, reg_t &val);
iss::status read_status(unsigned addr, reg_t &val);
iss::status write_status(unsigned addr, reg_t val);
+ iss::status write_cause(unsigned addr, reg_t val);
iss::status read_ie(unsigned addr, reg_t &val);
iss::status write_ie(unsigned addr, reg_t val);
iss::status read_ip(unsigned addr, reg_t &val);
@@ -442,7 +443,12 @@ riscv_hart_msu_vp::riscv_hart_msu_vp()
//csr_wr_cb[addr] = &this_class::write_reg;
}
// common regs
- const std::array addrs{{misa, mvendorid, marchid, mimpid, mepc, mtvec, mscratch, mcause, mtval, mscratch}};
+ const std::array addrs{{
+ misa, mvendorid, marchid, mimpid,
+ mepc, mtvec, mscratch, mcause, mtval, mscratch,
+ sepc, stvec, sscratch, scause, stval, sscratch,
+ uepc, utvec, uscratch, ucause, utval, uscratch
+ }};
for(auto addr: addrs) {
csr_rd_cb[addr] = &this_class::read_reg;
csr_wr_cb[addr] = &this_class::write_reg;
@@ -465,10 +471,13 @@ riscv_hart_msu_vp::riscv_hart_msu_vp()
csr_wr_cb[minstreth] = &this_class::write_instret;
csr_rd_cb[mstatus] = &this_class::read_status;
csr_wr_cb[mstatus] = &this_class::write_status;
+ csr_wr_cb[mcause] = &this_class::write_cause;
csr_rd_cb[sstatus] = &this_class::read_status;
csr_wr_cb[sstatus] = &this_class::write_status;
+ csr_wr_cb[scause] = &this_class::write_cause;
csr_rd_cb[ustatus] = &this_class::read_status;
csr_wr_cb[ustatus] = &this_class::write_status;
+ csr_wr_cb[ucause] = &this_class::write_cause;
csr_rd_cb[mip] = &this_class::read_ip;
csr_wr_cb[mip] = &this_class::write_ip;
csr_rd_cb[sip] = &this_class::read_ip;
@@ -878,6 +887,11 @@ template iss::status riscv_hart_msu_vp::write_status(unsig
return iss::Ok;
}
+template iss::status riscv_hart_msu_vp::write_cause(unsigned addr, reg_t val) {
+ csr[addr] = val & ((1UL<<(traits::XLEN-1))|0xf); //TODO: make exception code size configurable
+ return iss::Ok;
+}
+
template iss::status riscv_hart_msu_vp::read_ie(unsigned addr, reg_t &val) {
val = csr[mie];
if (addr < mie) val &= csr[mideleg];
diff --git a/incl/iss/arch/riscv_hart_mu_p.h b/incl/iss/arch/riscv_hart_mu_p.h
index 2215eeb..b388afe 100644
--- a/incl/iss/arch/riscv_hart_mu_p.h
+++ b/incl/iss/arch/riscv_hart_mu_p.h
@@ -301,6 +301,7 @@ private:
iss::status read_time(unsigned addr, reg_t &val);
iss::status read_status(unsigned addr, reg_t &val);
iss::status write_status(unsigned addr, reg_t val);
+ iss::status write_cause(unsigned addr, reg_t val);
iss::status read_ie(unsigned addr, reg_t &val);
iss::status write_ie(unsigned addr, reg_t val);
iss::status read_ip(unsigned addr, reg_t &val);
@@ -370,8 +371,10 @@ riscv_hart_mu_p::riscv_hart_mu_p()
csr_wr_cb[minstreth] = &this_class::write_instret;
csr_rd_cb[mstatus] = &this_class::read_status;
csr_wr_cb[mstatus] = &this_class::write_status;
+ csr_wr_cb[mcause] = &this_class::write_cause;
csr_rd_cb[ustatus] = &this_class::read_status;
csr_wr_cb[ustatus] = &this_class::write_status;
+ csr_wr_cb[ucause] = &this_class::write_cause;
csr_rd_cb[mip] = &this_class::read_ip;
csr_wr_cb[mip] = &this_class::write_ip;
csr_rd_cb[uip] = &this_class::read_ip;
@@ -773,6 +776,11 @@ template iss::status riscv_hart_mu_p iss::status riscv_hart_mu_p::write_cause(unsigned addr, reg_t val) {
+ csr[addr] = val & ((1UL<<(traits::XLEN-1))|0xf); //TODO: make exception code size configurable
+ return iss::Ok;
+}
+
template iss::status riscv_hart_mu_p::read_ie(unsigned addr, reg_t &val) {
val = csr[mie];
val &= csr[mideleg];