Browse Source

Implement dcsr.v and make DRET use it

Resolves #1365
pull/1366/head
Andrew Waterman 3 years ago
parent
commit
d99efb545c
  1. 8
      riscv/csrs.cc
  2. 3
      riscv/csrs.h
  3. 1
      riscv/insns/dret.h
  4. 2
      riscv/processor.cc

8
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();
}

3
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;
};

1
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);

2
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;

Loading…
Cancel
Save