9 class InstantHaltTest(unittest
.TestCase
):
11 self
.binary
= testlib
.compile("debug.c")
12 self
.spike
, self
.port
= testlib
.spike(self
.binary
, halted
=True)
13 self
.gdb
= testlib
.Gdb()
14 self
.gdb
.command("file %s" % self
.binary
)
15 self
.gdb
.command("target extended-remote localhost:%d" % self
.port
)
21 def test_instant_halt(self
):
22 self
.assertEqual(0x1000, self
.gdb
.p("$pc"))
23 # For some reason instret resets to 0.
24 self
.assertLess(self
.gdb
.p("$instret"), 8)
25 self
.gdb
.command("stepi")
26 self
.assertNotEqual(0x1000, self
.gdb
.p("$pc"))
28 def test_change_pc(self
):
29 """Change the PC right as we come out of reset."""
31 self
.gdb
.command("p *((int*) 0x80000000)=0x13")
32 self
.gdb
.command("p *((int*) 0x80000004)=0x13")
33 self
.gdb
.command("p *((int*) 0x80000008)=0x13")
34 self
.gdb
.command("p $pc=0x80000000")
35 self
.gdb
.command("stepi")
36 self
.assertEqual(0x80000004, self
.gdb
.p("$pc"))
37 self
.gdb
.command("stepi")
38 self
.assertEqual(0x80000008, self
.gdb
.p("$pc"))
40 class DebugTest(unittest
.TestCase
):
42 self
.binary
= testlib
.compile("debug.c")
43 self
.spike
, self
.port
= testlib
.spike(self
.binary
, halted
=False)
44 self
.gdb
= testlib
.Gdb()
45 self
.gdb
.command("file %s" % self
.binary
)
46 self
.gdb
.command("target extended-remote localhost:%d" % self
.port
)
52 def test_turbostep(self
):
53 """Single step a bunch of times."""
54 self
.gdb
.command("p i=0");
57 self
.gdb
.command("stepi")
58 pc
= self
.gdb
.command("p $pc")
59 self
.assertNotEqual(last_pc
, pc
)
63 self
.gdb
.command("p i=0");
64 output
= self
.gdb
.command("c")
65 self
.assertIn("Continuing", output
)
66 self
.assertIn("Remote connection closed", output
)
68 def test_breakpoint(self
):
69 self
.gdb
.command("p i=0");
70 self
.gdb
.command("b print_row")
71 # The breakpoint should be hit exactly 10 times.
73 output
= self
.gdb
.command("c")
74 self
.assertIn("Continuing", output
)
75 self
.assertIn("length=%d" % i
, output
)
76 self
.assertIn("Breakpoint 1", output
)
77 output
= self
.gdb
.command("c")
78 self
.assertIn("Continuing", output
)
79 self
.assertIn("Remote connection closed", output
)
81 def test_registers(self
):
82 self
.gdb
.command("p i=0");
83 # Try both forms to test gdb.
84 for cmd
in ("info all-registers", "info registers all"):
85 output
= self
.gdb
.command(cmd
)
86 self
.assertNotIn("Could not", output
)
87 for reg
in ('zero', 'ra', 'sp', 'gp', 'tp'):
88 self
.assertIn(reg
, output
)
89 # mcpuid is one of the few registers that should have the high bit set
91 # Leave this commented out until gdb and spike agree on the encoding of
92 # mcpuid (which is going to be renamed to misa in any case).
93 #self.assertRegexpMatches(output, ".*mcpuid *0x80")
95 # The instret register should always be changing.
98 instret
= self
.gdb
.p("$instret")
99 self
.assertNotEqual(instret
, last_instret
)
100 last_instret
= instret
101 self
.gdb
.command("stepi")
103 def test_interrupt(self
):
104 """Sending gdb ^C while the program is running should cause it to halt."""
105 self
.gdb
.c(wait
=False)
108 self
.gdb
.command("p i=123");
109 self
.gdb
.c(wait
=False)
112 self
.gdb
.command("p i=0");
113 output
= self
.gdb
.c()
114 self
.assertIn("Continuing", output
)
115 self
.assertIn("Remote connection closed", output
)
117 class RegsTest(unittest
.TestCase
):
119 self
.binary
= testlib
.compile("regs.s")
120 self
.spike
, self
.port
= testlib
.spike(self
.binary
, halted
=False)
121 self
.gdb
= testlib
.Gdb()
122 self
.gdb
.command("file %s" % self
.binary
)
123 self
.gdb
.command("target extended-remote localhost:%d" % self
.port
)
129 def test_write_gprs(self
):
130 # Note a0 is missing from this list since it's used to hold the
132 regs
= ("ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "s1",
133 "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4",
134 "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5",
137 self
.gdb
.command("p $pc=write_regs")
138 for i
, r
in enumerate(regs
):
139 self
.gdb
.command("p $%s=%d" % (r
, (0xdeadbeef<<i
)+17))
140 self
.gdb
.command("p $a0=data")
141 self
.gdb
.command("b all_done")
142 output
= self
.gdb
.command("c")
143 self
.assertIn("Breakpoint 1", output
)
145 # Just to get this data in the log.
146 self
.gdb
.command("x/30gx data")
147 self
.gdb
.command("info registers")
148 for n
in range(len(regs
)):
149 self
.assertEqual(self
.gdb
.x("data+%d" % (8*n
), 'g'),
152 def test_write_csrs(self
):
153 # As much a test of gdb as of the simulator.
154 self
.gdb
.p("$mscratch=0")
156 self
.assertEqual(self
.gdb
.p("$mscratch"), 0)
157 self
.gdb
.p("$mscratch=123")
159 self
.assertEqual(self
.gdb
.p("$mscratch"), 123)
161 self
.gdb
.command("p $fflags=9")
162 self
.gdb
.command("p $pc=write_regs")
163 self
.gdb
.command("p $a0=data")
164 self
.gdb
.command("b all_done")
165 self
.gdb
.command("c")
167 self
.assertEqual(9, self
.gdb
.p("$fflags"))
168 self
.assertEqual(9, self
.gdb
.p("$x1"))
169 self
.assertEqual(9, self
.gdb
.p("$csr1"))
171 class MprvTest(unittest
.TestCase
):
173 self
.binary
= testlib
.compile("mprv.S", "-T", "standalone.lds",
175 self
.spike
, self
.port
= testlib
.spike(None, halted
=True)
176 self
.gdb
= testlib
.Gdb()
177 self
.gdb
.command("file %s" % self
.binary
)
178 self
.gdb
.command("target extended-remote localhost:%d" % self
.port
)
179 self
.gdb
.command("load")
186 """Test that the debugger can access memory when MPRV is set."""
187 self
.gdb
.c(wait
=False)
189 output
= self
.gdb
.command("p/x *(int*)(((char*)&data)-0x80000000)")
190 self
.assertIn("0xbead", output
)
192 if __name__
== '__main__':
193 # TROUBLESHOOTING TIPS
194 # If a particular test fails, run just that one test, eg.:
195 # ./tests/gdbserver.py MprvTest.test_mprv
196 # Then inspect gdb.log and spike.log to see what happened in more detail.