From 32274e0ce949d9c97647d86e82146c46e3515e90 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Wed, 15 Jan 2020 12:11:08 -0800 Subject: Force DMI busy in all tests. (#235) This catches more corner cases where this may be a problem. --- debug/gdbserver.py | 35 ++++++++++++++++++++++++++--------- debug/testlib.py | 24 ++++++++++++++++++------ 2 files changed, 44 insertions(+), 15 deletions(-) (limited to 'debug') diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 3b61529..cc8f617 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -315,13 +315,7 @@ class MemTestBlock(GdbTest): temporary_file.flush() return data - def test(self): - a = tempfile.NamedTemporaryFile(suffix=".ihex") - data = self.write(a) - - self.gdb.command("shell cat %s" % a.name) - self.gdb.command("monitor riscv reset_delays 50") - self.gdb.command("restore %s 0x%x" % (a.name, self.hart.ram)) + def spot_check_memory(self, data): increment = 19 * 4 for offset in list(range(0, self.length, increment)) + [self.length-4]: value = self.gdb.p("*((int*)0x%x)" % (self.hart.ram + offset)) @@ -331,10 +325,19 @@ class MemTestBlock(GdbTest): (ord(data[offset+3]) << 24) assertEqual(value, written) + def test_block(self, extra_delay): + a = tempfile.NamedTemporaryFile(suffix=".ihex") + data = self.write(a) + + self.gdb.command("shell cat %s" % a.name) + self.gdb.command("restore %s 0x%x" % (a.name, self.hart.ram), + reset_delays=50 + extra_delay) + self.spot_check_memory(data) + b = tempfile.NamedTemporaryFile(suffix=".srec") - self.gdb.command("monitor riscv reset_delays 100") self.gdb.command("dump srec memory %s 0x%x 0x%x" % (b.name, - self.hart.ram, self.hart.ram + self.length), ops=self.length / 32) + self.hart.ram, self.hart.ram + self.length), ops=self.length / 32, + reset_delays=100 + extra_delay) self.gdb.command("shell cat %s" % b.name) highest_seen = 0 for line in b: @@ -352,6 +355,20 @@ class MemTestBlock(GdbTest): readable_binary_string(line_data))) assertEqual(highest_seen, self.length) +# Run memory block tests with different reset delays, so hopefully we hit busy +# at every possible relevant time. +class MemTestBlock0(MemTestBlock): + def test(self): + return self.test_block(0) + +class MemTestBlock1(MemTestBlock): + def test(self): + return self.test_block(1) + +class MemTestBlock2(MemTestBlock): + def test(self): + return self.test_block(2) + class InstantHaltTest(GdbTest): def test(self): """Assert that reset is really resetting what it should.""" diff --git a/debug/testlib.py b/debug/testlib.py index fbb0472..8bdce50 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -405,6 +405,10 @@ class Gdb: # pylint: disable=too-many-public-methods # pylint: disable=too-many-instance-attributes + reset_delays = (127, 181, 17, 13, 83, 151, 31, 67, 131, 167, 23, 41, 61, + 11, 149, 107, 163, 73, 47, 43, 173, 7, 109, 101, 103, 191, 2, 139, + 97, 193, 157, 3, 29, 79, 113, 5, 89, 19, 37, 71, 179, 59, 137, 53) + def __init__(self, ports, cmd="riscv64-unknown-elf-gdb", timeout=60, binary=None): @@ -415,6 +419,7 @@ class Gdb: self.timeout = timeout self.binary = binary + self.reset_delay_index = 0 self.stack = [] self.harts = {} @@ -496,10 +501,17 @@ class Gdb: """Wait for prompt.""" self.active_child.expect(r"\(gdb\)") - def command(self, command, ops=1): + def command(self, command, ops=1, reset_delays=0): """ops is the estimated number of operations gdb will have to perform to perform this command. It is used to compute a timeout based on self.timeout.""" + if not reset_delays is None: + if reset_delays == 0: + reset_delays = self.reset_delays[self.reset_delay_index] + self.reset_delay_index = (self.reset_delay_index + 1) % \ + len(self.reset_delays) + self.command("monitor riscv reset_delays %d" % reset_delays, + reset_delays=None) timeout = ops * self.timeout self.active_child.sendline(command) self.active_child.expect("\n", timeout=timeout) @@ -962,11 +974,11 @@ class GdbTest(BaseTest): if not self.gdb: return self.gdb.interrupt() - self.gdb.command("info breakpoints") - self.gdb.command("disassemble", ops=20) - self.gdb.command("info registers all", ops=20) - self.gdb.command("flush regs") - self.gdb.command("info threads", ops=20) + self.gdb.command("info breakpoints", reset_delays=None) + self.gdb.command("disassemble", ops=20, reset_delays=None) + self.gdb.command("info registers all", ops=20, reset_delays=None) + self.gdb.command("flush regs", reset_delays=None) + self.gdb.command("info threads", ops=20, reset_delays=None) def classTeardown(self): del self.gdb -- cgit v1.1