diff options
Diffstat (limited to 'riscv/execute.cc')
-rw-r--r-- | riscv/execute.cc | 66 |
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; } |