aboutsummaryrefslogtreecommitdiff
path: root/riscv/execute.cc
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/execute.cc')
-rw-r--r--riscv/execute.cc42
1 files changed, 32 insertions, 10 deletions
diff --git a/riscv/execute.cc b/riscv/execute.cc
index f263dce..e0a6e59 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -213,12 +213,11 @@ void processor_t::step(size_t n)
{
if (!state.debug_mode) {
if (halt_request == HR_REGULAR) {
- enter_debug_mode(DCSR_CAUSE_DEBUGINT);
+ enter_debug_mode(DCSR_CAUSE_DEBUGINT, 0);
} else if (halt_request == HR_GROUP) {
- enter_debug_mode(DCSR_CAUSE_GROUP);
- } // !!!The halt bit in DCSR is deprecated.
- else if (state.dcsr->halt) {
- enter_debug_mode(DCSR_CAUSE_HALT);
+ enter_debug_mode(DCSR_CAUSE_GROUP, 0);
+ } else if (state.dcsr->halt) {
+ enter_debug_mode(DCSR_CAUSE_HALT, 0);
}
}
@@ -257,7 +256,7 @@ void processor_t::step(size_t n)
if (unlikely(!state.serialized && state.single_step == state.STEP_STEPPED)) {
state.single_step = state.STEP_NONE;
if (!state.debug_mode) {
- enter_debug_mode(DCSR_CAUSE_STEP);
+ enter_debug_mode(DCSR_CAUSE_STEP, 0);
// enter_debug_mode changed state.pc, so we can't just continue.
break;
}
@@ -286,6 +285,17 @@ void processor_t::step(size_t n)
disasm(fetch.insn);
pc = execute_insn_logged(this, pc, fetch);
advance_pc();
+
+ // Resume from debug mode in critical error
+ if (state.critical_error && !state.debug_mode) {
+ if (state.dcsr->read() & DCSR_CETRIG) {
+ enter_debug_mode(DCSR_CAUSE_EXTCAUSE, DCSR_EXTCAUSE_CRITERR);
+ } else {
+ // Handling of critical error is implementation defined
+ // For now just enter debug mode
+ enter_debug_mode(DCSR_CAUSE_HALT, 0);
+ }
+ }
}
}
else while (instret < n)
@@ -311,13 +321,23 @@ void processor_t::step(size_t n)
take_trap(t, pc);
n = instret;
+ // If critical error then enter debug mode critical error trigger enabled
+ if (state.critical_error) {
+ if (state.dcsr->read() & DCSR_CETRIG) {
+ enter_debug_mode(DCSR_CAUSE_EXTCAUSE, DCSR_EXTCAUSE_CRITERR);
+ } else {
+ // Handling of critical error is implementation defined
+ // For now just enter debug mode
+ enter_debug_mode(DCSR_CAUSE_HALT, 0);
+ }
+ }
// Trigger action takes priority over single step
auto match = TM.detect_trap_match(t);
if (match.has_value())
take_trigger_action(match->action, 0, state.pc, 0);
else if (unlikely(state.single_step == state.STEP_STEPPED)) {
state.single_step = state.STEP_NONE;
- enter_debug_mode(DCSR_CAUSE_STEP);
+ enter_debug_mode(DCSR_CAUSE_STEP, 0);
}
}
catch (triggers::matched_t& t)
@@ -330,7 +350,7 @@ void processor_t::step(size_t n)
}
catch(trap_debug_mode&)
{
- enter_debug_mode(DCSR_CAUSE_SWBP);
+ enter_debug_mode(DCSR_CAUSE_SWBP, 0);
}
catch (wait_for_interrupt_t &t)
{
@@ -344,10 +364,12 @@ void processor_t::step(size_t n)
in_wfi = true;
}
- state.minstret->bump(instret);
+ if (!(state.mcountinhibit->read() & MCOUNTINHIBIT_IR))
+ state.minstret->bump(instret);
// Model a hart whose CPI is 1.
- state.mcycle->bump(instret);
+ if (!(state.mcountinhibit->read() & MCOUNTINHIBIT_CY))
+ state.mcycle->bump(instret);
n -= instret;
}