When gdb connects, jump to Debug ROM and segfault.
[riscv-isa-sim.git] / riscv / execute.cc
index 42d59cb4ce5295fe3248efda2562e322298b3c0a..1796c3884ba2a2d2761ddd7512dada25c7cd4b92 100644 (file)
@@ -4,10 +4,18 @@
 #include "mmu.h"
 #include <cassert>
 
-static void commit_log(state_t* state, reg_t pc, insn_t insn)
+
+static void commit_log_stash_privilege(state_t* state)
+{
+#ifdef RISCV_ENABLE_COMMITLOG
+  state->last_inst_priv = state->prv;
+#endif
+}
+
+static void commit_log_print_insn(state_t* state, reg_t pc, insn_t insn)
 {
 #ifdef RISCV_ENABLE_COMMITLOG
-  int32_t priv = get_field(state->mstatus, MSTATUS_PRV);
+  int32_t priv = state->last_inst_priv;
   uint64_t mask = (insn.length() == 8 ? uint64_t(0) : (uint64_t(1) << (insn.length() * 8))) - 1;
   if (state->log_reg_write.addr) {
     fprintf(stderr, "%1d 0x%016" PRIx64 " (0x%08" PRIx64 ") %c%2" PRIu64 " 0x%016" PRIx64 "\n",
@@ -24,19 +32,19 @@ static void commit_log(state_t* state, reg_t pc, insn_t insn)
 #endif
 }
 
-inline void processor_t::update_histogram(size_t pc)
+inline void processor_t::update_histogram(reg_t pc)
 {
 #ifdef RISCV_ENABLE_HISTOGRAM
-  size_t idx = pc >> 2;
-  pc_histogram[idx]++;
+  pc_histogram[pc]++;
 #endif
 }
 
 static reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch)
 {
+  commit_log_stash_privilege(p->get_state());
   reg_t npc = fetch.func(p, fetch.insn, pc);
-  if (npc != PC_SERIALIZE) {
-    commit_log(p->get_state(), pc, fetch.insn);
+  if (!invalid_pc(npc)) {
+    commit_log_print_insn(p->get_state(), pc, fetch.insn);
     p->update_histogram(pc);
   }
   return npc;
@@ -45,15 +53,23 @@ static reg_t execute_insn(processor_t* p, reg_t pc, insn_fetch_t fetch)
 // fetch/decode/execute loop
 void processor_t::step(size_t n)
 {
-  while (run && n > 0) {
+  if (state.dcsr.debugint && state.dcsr.cause == DCSR_CAUSE_NONE) {
+    enter_debug_mode(DCSR_CAUSE_DEBUGINT);
+  }
+
+  while (n > 0) {
     size_t instret = 0;
     reg_t pc = state.pc;
     mmu_t* _mmu = mmu;
 
     #define advance_pc() \
-     if (unlikely(pc == PC_SERIALIZE)) { \
+     if (unlikely(invalid_pc(pc))) { \
+       switch (pc) { \
+         case PC_SERIALIZE_BEFORE: state.serialized = true; break; \
+         case PC_SERIALIZE_AFTER: instret++; break; \
+         default: abort(); \
+       } \
        pc = state.pc; \
-       state.serialized = true; \
        break; \
      } else { \
        state.pc = pc; \
@@ -62,7 +78,6 @@ void processor_t::step(size_t n)
 
     try
     {
-      check_timer();
       take_interrupt();
 
       if (unlikely(debug))
@@ -109,6 +124,7 @@ miss:
     catch(trap_t& t)
     {
       take_trap(t, pc);
+      n = instret;
     }
 
     state.minstret += instret;