aboutsummaryrefslogtreecommitdiff
path: root/riscv/execute.cc
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/execute.cc')
-rw-r--r--riscv/execute.cc66
1 files changed, 46 insertions, 20 deletions
diff --git a/riscv/execute.cc b/riscv/execute.cc
index cc77d88..1b572a7 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -40,13 +40,12 @@ static void commit_log_print_value(FILE *log_file, int width, const void *data)
fprintf(log_file, "0x%016" PRIx64, *(const uint64_t *)data);
break;
default:
- // max lengh of vector
- if (((width - 1) & width) == 0) {
- const uint64_t *arr = (const uint64_t *)data;
+ if (width % 8 == 0) {
+ const uint8_t *arr = (const uint8_t *)data;
fprintf(log_file, "0x");
- for (int idx = width / 64 - 1; idx >= 0; --idx) {
- fprintf(log_file, "%016" PRIx64, arr[idx]);
+ for (int idx = width / 8 - 1; idx >= 0; --idx) {
+ fprintf(log_file, "%02" PRIx8, arr[idx]);
}
} else {
abort();
@@ -202,7 +201,7 @@ static inline reg_t execute_insn_logged(processor_t* p, reg_t pc, insn_fetch_t f
return npc;
}
-bool processor_t::slow_path()
+bool processor_t::slow_path() const
{
return debug || state.single_step != state.STEP_NONE || state.debug_mode ||
log_commits_enabled || histogram_enabled || in_wfi || check_triggers_icount;
@@ -211,21 +210,31 @@ bool processor_t::slow_path()
// fetch/decode/execute loop
void processor_t::step(size_t n)
{
+ mmu_t* _mmu = mmu;
+
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);
+ enter_debug_mode(DCSR_CAUSE_GROUP, 0);
+ } else if (halt_on_reset) {
+ halt_on_reset = false;
+ enter_debug_mode(DCSR_CAUSE_HALT, 0);
}
- else if (state.dcsr->halt) {
- enter_debug_mode(DCSR_CAUSE_HALT);
+ }
+
+ if (extension_enabled(EXT_ZICCID)) {
+ // Ziccid requires stores eventually become visible to instruction fetch,
+ // so periodically flush the I$
+ if (ziccid_flush_count-- == 0) {
+ ziccid_flush_count += ZICCID_FLUSH_PERIOD;
+ _mmu->flush_icache();
}
}
while (n > 0) {
size_t instret = 0;
reg_t pc = state.pc;
- mmu_t* _mmu = mmu;
state.prv_changed = false;
state.v_changed = false;
@@ -257,7 +266,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 +295,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,26 +331,32 @@ 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)
{
- if (mmu->matched_trigger) {
- delete mmu->matched_trigger;
- mmu->matched_trigger = NULL;
- }
take_trigger_action(t.action, t.address, pc, t.gva);
}
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 +370,10 @@ void processor_t::step(size_t n)
in_wfi = true;
}
- state.minstret->bump(instret);
+ state.minstret->bump((state.mcountinhibit->read() & MCOUNTINHIBIT_IR) ? 0 : instret);
// Model a hart whose CPI is 1.
- state.mcycle->bump(instret);
+ state.mcycle->bump((state.mcountinhibit->read() & MCOUNTINHIBIT_CY) ? 0 : instret);
n -= instret;
}