Make -H halt the core right out of reset.
authorTim Newsome <tim@sifive.com>
Fri, 6 May 2016 19:14:22 +0000 (12:14 -0700)
committerTim Newsome <tim@sifive.com>
Mon, 23 May 2016 19:12:12 +0000 (12:12 -0700)
Added a test, too.

riscv/execute.cc
riscv/processor.cc
riscv/processor.h
riscv/sim.cc
tests/gdbserver.py

index 03588f3e557d00927db40d092d08b8c44ebc1922..a0848d7a4143120d962c1e7415edb76c894f56cd 100644 (file)
@@ -54,13 +54,14 @@ 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)
 {
-  // TODO: get_interrupt() isn't super fast. Does that matter?
-  if (state.dcsr.cause == DCSR_CAUSE_NONE &&
-      sim->debug_module.get_interrupt(id)) {
-    enter_debug_mode(DCSR_CAUSE_DEBUGINT);
-  }
-
-  if (state.dcsr.cause != DCSR_CAUSE_NONE) {
+  if (state.dcsr.cause == DCSR_CAUSE_NONE) {
+    // TODO: get_interrupt() isn't super fast. Does that matter?
+    if (sim->debug_module.get_interrupt(id)) {
+      enter_debug_mode(DCSR_CAUSE_DEBUGINT);
+    } else if (state.dcsr.halt) {
+      enter_debug_mode(DCSR_CAUSE_HALT);
+    }
+  } else {
     // In Debug Mode, just do 11 steps at a time. Otherwise we're going to be
     // spinning the rest of the time anyway.
     n = std::min(n, (size_t) 11);
index d43defc81c48d468303085f5ce118ab206880160..7f7547141277d00f5795f0693560413c6673c2f9 100644 (file)
 #undef STATE
 #define STATE state
 
-processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id)
+processor_t::processor_t(const char* isa, sim_t* sim, uint32_t id,
+        bool halt_on_reset)
   : debug(false), sim(sim), ext(NULL), disassembler(new disassembler_t),
-    id(id), run(false)
+    id(id), run(false), halt_on_reset(halt_on_reset)
 {
   parse_isa_string(isa);
 
@@ -145,6 +146,8 @@ void processor_t::reset(bool value)
   run = !value;
 
   state.reset();
+  state.dcsr.halt = halt_on_reset;
+  halt_on_reset = false;
   set_csr(CSR_MSTATUS, state.mstatus);
 
   if (ext)
index 721da2cb54fdb53f0611e6e6b97097bbefdb38f4..730ae787c60c99a2805c314fc9e64ea2ddf8bb10 100644 (file)
@@ -101,7 +101,7 @@ struct state_t
 class processor_t : public abstract_device_t
 {
 public:
-  processor_t(const char* isa, sim_t* sim, uint32_t id);
+  processor_t(const char* isa, sim_t* sim, uint32_t id, bool halt_on_reset=false);
   ~processor_t();
 
   void set_debug(bool value);
@@ -146,6 +146,7 @@ private:
   std::string isa_string;
   bool run; // !reset
   bool histogram_enabled;
+  bool halt_on_reset;
 
   std::vector<insn_desc_t> instructions;
   std::map<reg_t,uint64_t> pc_histogram;
index 4b4eed4ddc2369c2cfcf9aee6df6b10e2d4b41d3..d17289d5afc676b4ed8c7a6a5406b05f0407495a 100644 (file)
@@ -47,9 +47,7 @@ sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, bool halted,
   debug_mmu = new mmu_t(this, NULL);
 
   for (size_t i = 0; i < procs.size(); i++) {
-    procs[i] = new processor_t(isa, this, i);
-    if (halted)
-      procs[i]->enter_debug_mode(DCSR_CAUSE_HALT);
+    procs[i] = new processor_t(isa, this, i, halted);
   }
 
   rtc.reset(new rtc_t(procs));
index 297960604e0d9578f06d3265ca771e9db36044d6..0f9ee1dd624083192b1e8e84ab7c24ccdad2d5c6 100755 (executable)
@@ -6,6 +6,25 @@ import unittest
 import tempfile
 import time
 
+class InstantHaltTest(unittest.TestCase):
+    def setUp(self):
+        self.binary = testlib.compile("debug.c")
+        self.spike, self.port = testlib.spike(self.binary, halted=True)
+        self.gdb = testlib.Gdb()
+        self.gdb.command("file %s" % self.binary)
+        self.gdb.command("target extended-remote localhost:%d" % self.port)
+
+    def tearDown(self):
+        self.spike.kill()
+        self.spike.wait()
+
+    def test_instant_halt(self):
+        self.assertEqual(0x1000, self.gdb.p("$pc"))
+        # For some reason instret resets to 0.
+        self.assertLess(self.gdb.p("$instret"), 8)
+        self.gdb.command("stepi")
+        self.assertNotEqual(0x1000, self.gdb.p("$pc"))
+
 class DebugTest(unittest.TestCase):
     def setUp(self):
         self.binary = testlib.compile("debug.c")
@@ -137,5 +156,22 @@ class RegsTest(unittest.TestCase):
         self.assertEqual(9, self.gdb.p("$x1"))
         self.assertEqual(9, self.gdb.p("$csr1"))
 
+#class MprvTest(unittest.TestCase):
+#    def setUp(self):
+#        self.binary = testlib.compile("mprv.S")
+#        self.spike, self.port = testlib.spike(self.binary, halted=False)
+#        self.gdb = testlib.Gdb()
+#        self.gdb.command("file %s" % self.binary)
+#        self.gdb.command("target extended-remote localhost:%d" % self.port)
+#
+#    def tearDown(self):
+#        self.spike.kill()
+#        self.spike.wait()
+#
+#    def test_mprv(self):
+#        """Test that the debugger can access memory when MPRV is set."""
+#        output = self.gdb.command("p/x data");
+#        self.assertIn("0xbead", output)
+
 if __name__ == '__main__':
     unittest.main()