f16a3cc623b219b3cead07ff77815d3046d58cae
11 class DeleteSpike(unittest
.TestCase
):
15 class InstantHaltTest(DeleteSpike
):
17 self
.binary
= testlib
.compile("debug.c")
18 self
.spike
= testlib
.Spike(self
.binary
, halted
=True)
19 self
.gdb
= testlib
.Gdb()
20 self
.gdb
.command("file %s" % self
.binary
)
21 self
.gdb
.command("target extended-remote localhost:%d" % self
.spike
.port
)
23 def test_instant_halt(self
):
24 self
.assertEqual(0x1000, self
.gdb
.p("$pc"))
25 # For some reason instret resets to 0.
26 self
.assertLess(self
.gdb
.p("$instret"), 8)
27 self
.gdb
.command("stepi")
28 self
.assertNotEqual(0x1000, self
.gdb
.p("$pc"))
30 def test_change_pc(self
):
31 """Change the PC right as we come out of reset."""
33 self
.gdb
.command("p *((int*) 0x80000000)=0x13")
34 self
.gdb
.command("p *((int*) 0x80000004)=0x13")
35 self
.gdb
.command("p *((int*) 0x80000008)=0x13")
36 self
.gdb
.command("p $pc=0x80000000")
37 self
.gdb
.command("stepi")
38 self
.assertEqual(0x80000004, self
.gdb
.p("$pc"))
39 self
.gdb
.command("stepi")
40 self
.assertEqual(0x80000008, self
.gdb
.p("$pc"))
42 class DebugTest(DeleteSpike
):
44 self
.binary
= testlib
.compile("debug.c")
45 self
.spike
= testlib
.Spike(self
.binary
, halted
=False)
46 self
.gdb
= testlib
.Gdb()
47 self
.gdb
.command("file %s" % self
.binary
)
48 self
.gdb
.command("target extended-remote localhost:%d" % self
.spike
.port
)
50 def test_turbostep(self
):
51 """Single step a bunch of times."""
52 self
.gdb
.command("p i=0");
55 self
.gdb
.command("stepi")
56 pc
= self
.gdb
.command("p $pc")
57 self
.assertNotEqual(last_pc
, pc
)
61 self
.gdb
.command("p i=0");
62 output
= self
.gdb
.command("c")
63 self
.assertIn("Continuing", output
)
64 self
.assertIn("Remote connection closed", output
)
66 def test_breakpoint(self
):
67 self
.gdb
.command("p i=0");
68 self
.gdb
.command("b print_row")
69 # The breakpoint should be hit exactly 10 times.
71 output
= self
.gdb
.command("c")
72 self
.assertIn("Continuing", output
)
73 self
.assertIn("length=%d" % i
, output
)
74 self
.assertIn("Breakpoint 1", output
)
75 output
= self
.gdb
.command("c")
76 self
.assertIn("Continuing", output
)
77 self
.assertIn("Remote connection closed", output
)
79 def test_registers(self
):
80 self
.gdb
.command("p i=0");
81 # Try both forms to test gdb.
82 for cmd
in ("info all-registers", "info registers all"):
83 output
= self
.gdb
.command(cmd
)
84 self
.assertNotIn("Could not", output
)
85 for reg
in ('zero', 'ra', 'sp', 'gp', 'tp'):
86 self
.assertIn(reg
, output
)
87 # mcpuid is one of the few registers that should have the high bit set
89 # Leave this commented out until gdb and spike agree on the encoding of
90 # mcpuid (which is going to be renamed to misa in any case).
91 #self.assertRegexpMatches(output, ".*mcpuid *0x80")
93 # The instret register should always be changing.
96 instret
= self
.gdb
.p("$instret")
97 self
.assertNotEqual(instret
, last_instret
)
98 last_instret
= instret
99 self
.gdb
.command("stepi")
101 def test_interrupt(self
):
102 """Sending gdb ^C while the program is running should cause it to halt."""
103 self
.gdb
.c(wait
=False)
106 self
.gdb
.command("p i=123");
107 self
.gdb
.c(wait
=False)
110 self
.gdb
.command("p i=0");
111 output
= self
.gdb
.c()
112 self
.assertIn("Continuing", output
)
113 self
.assertIn("Remote connection closed", output
)
115 class RegsTest(DeleteSpike
):
117 self
.binary
= testlib
.compile("regs.s")
118 self
.spike
= testlib
.Spike(self
.binary
, halted
=False)
119 self
.gdb
= testlib
.Gdb()
120 self
.gdb
.command("file %s" % self
.binary
)
121 self
.gdb
.command("target extended-remote localhost:%d" % self
.spike
.port
)
123 def test_write_gprs(self
):
124 # Note a0 is missing from this list since it's used to hold the
126 regs
= ("ra", "sp", "gp", "tp", "t0", "t1", "t2", "fp", "s1",
127 "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4",
128 "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5",
131 self
.gdb
.command("p $pc=write_regs")
132 for i
, r
in enumerate(regs
):
133 self
.gdb
.command("p $%s=%d" % (r
, (0xdeadbeef<<i
)+17))
134 self
.gdb
.command("p $a0=data")
135 self
.gdb
.command("b all_done")
136 output
= self
.gdb
.command("c")
137 self
.assertIn("Breakpoint 1", output
)
139 # Just to get this data in the log.
140 self
.gdb
.command("x/30gx data")
141 self
.gdb
.command("info registers")
142 for n
in range(len(regs
)):
143 self
.assertEqual(self
.gdb
.x("data+%d" % (8*n
), 'g'),
146 def test_write_csrs(self
):
147 # As much a test of gdb as of the simulator.
148 self
.gdb
.p("$mscratch=0")
150 self
.assertEqual(self
.gdb
.p("$mscratch"), 0)
151 self
.gdb
.p("$mscratch=123")
153 self
.assertEqual(self
.gdb
.p("$mscratch"), 123)
155 self
.gdb
.command("p $fflags=9")
156 self
.gdb
.command("p $pc=write_regs")
157 self
.gdb
.command("p $a0=data")
158 self
.gdb
.command("b all_done")
159 self
.gdb
.command("c")
161 self
.assertEqual(9, self
.gdb
.p("$fflags"))
162 self
.assertEqual(9, self
.gdb
.p("$x1"))
163 self
.assertEqual(9, self
.gdb
.p("$csr1"))
165 class DownloadTest(DeleteSpike
):
168 fd
= file("data.c", "w")
169 fd
.write("#include <stdint.h>\n")
170 fd
.write("uint32_t length = %d;\n" % length
)
171 fd
.write("uint8_t d[%d] = {\n" % length
)
173 for i
in range(length
/ 16):
174 fd
.write(" /* 0x%04x */ " % (i
* 16));
176 value
= random
.randrange(1<<8)
177 fd
.write("%d, " % value
)
178 self
.crc
= binascii
.crc32("%c" % value
, self
.crc
)
181 fd
.write("uint8_t *data = &d[0];\n");
184 self
.binary
= testlib
.compile("checksum.c", "data.c", "start.S",
186 "-T", "standalone.lds",
189 self
.spike
= testlib
.Spike(None, halted
=True)
190 self
.gdb
= testlib
.Gdb()
191 self
.gdb
.command("file %s" % self
.binary
)
192 self
.gdb
.command("target extended-remote localhost:%d" % self
.spike
.port
)
194 def test_download(self
):
195 output
= self
.gdb
.command("load")
196 self
.assertNotIn("failed", output
)
197 self
.assertIn("Transfer rate", output
)
198 self
.gdb
.command("b done")
200 result
= self
.gdb
.p("$a0")
201 self
.assertEqual(self
.crc
, result
)
203 class MprvTest(DeleteSpike
):
205 self
.binary
= testlib
.compile("mprv.S", "-T", "standalone.lds",
207 self
.spike
= testlib
.Spike(None, halted
=True)
208 self
.gdb
= testlib
.Gdb()
209 self
.gdb
.command("file %s" % self
.binary
)
210 self
.gdb
.command("target extended-remote localhost:%d" % self
.spike
.port
)
211 self
.gdb
.command("load")
214 """Test that the debugger can access memory when MPRV is set."""
215 self
.gdb
.c(wait
=False)
217 output
= self
.gdb
.command("p/x *(int*)(((char*)&data)-0x80000000)")
218 self
.assertIn("0xbead", output
)
220 if __name__
== '__main__':
221 # TROUBLESHOOTING TIPS
222 # If a particular test fails, run just that one test, eg.:
223 # ./tests/gdbserver.py MprvTest.test_mprv
224 # Then inspect gdb.log and spike.log to see what happened in more detail.