Browse Source

Make -H halt the core right out of reset.

Added a test, too.
pull/39/head
Tim Newsome 10 years ago
parent
commit
9b8b9b69d0
  1. 15
      riscv/execute.cc
  2. 7
      riscv/processor.cc
  3. 3
      riscv/processor.h
  4. 4
      riscv/sim.cc
  5. 36
      tests/gdbserver.py

15
riscv/execute.cc

@ -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);

7
riscv/processor.cc

@ -21,9 +21,10 @@
#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)

3
riscv/processor.h

@ -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;

4
riscv/sim.cc

@ -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));

36
tests/gdbserver.py

@ -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()

Loading…
Cancel
Save