From 0d690752517d82e6ce823ea20d2f4d95f535728f Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Fri, 4 Nov 2022 10:43:44 -0700 Subject: Make MulticoreRegTest work with real hardware. It would fail intermittently. We can't guarantee all harts resume simultaneously. When we let multiple harts run to a breakpoint at the end of the same loop, one is likely to get there first, and the second won't make it. To avoid this problem, run for a short amount of time instead of to a breakpoint. --- debug/gdbserver.py | 34 ++++++++++++++++++---------------- debug/programs/infinite_loop.S | 2 +- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 21a822c..d567a85 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -1062,24 +1062,21 @@ class MulticoreRegTest(GdbTest): self.gdb.p("$pc=_start") def test(self): - # Run to main - for hart in self.target.harts: - self.gdb.select_hart(hart) - self.gdb.b("main") - self.gdb.c() - assertIn("main", self.gdb.where()) - self.gdb.command("delete breakpoints") - - # Run through the entire loop. - for hart in self.target.harts: - self.gdb.select_hart(hart) - self.gdb.b("main_end") - self.gdb.c() - assertIn("main_end", self.gdb.where()) + # We use time instead of breakpoints, because otherwise we can't + # guarantee that every hart runs all the way through the loop. (The + # problem is that we can't guarantee resuming at the same time, so the + # first hart that is resumed will hit a breakpoint at the end of the + # loop before another hart has executed the whole loop.) + + # Run through the whole loop. + self.gdb.c_all(wait=False) + time.sleep(1) + self.gdb.interrupt_all() hart_ids = set() for hart in self.target.harts: self.gdb.select_hart(hart) + assertIn("main_end", self.gdb.where()) # Check register values. x1 = self.gdb.p("$x1") hart_id = self.gdb.p("$mhartid") @@ -1097,10 +1094,15 @@ class MulticoreRegTest(GdbTest): self.gdb.select_hart(hart) self.gdb.p(f"$x1=0x{hart.index * 4096:x}") self.gdb.p("$pc=main_post_csrr") - self.gdb.c() + + # Run through the whole loop. + self.gdb.c_all(wait=False) + time.sleep(1) + self.gdb.interrupt_all() + for hart in self.target.harts: self.gdb.select_hart(hart) - assertIn("main", self.gdb.where()) + assertIn("main_end", self.gdb.where()) # Check register values. for n in range(1, 32): value = self.gdb.p(f"$x{n}") diff --git a/debug/programs/infinite_loop.S b/debug/programs/infinite_loop.S index 5cc377c..d13f366 100644 --- a/debug/programs/infinite_loop.S +++ b/debug/programs/infinite_loop.S @@ -41,4 +41,4 @@ main_post_csrr: addi x30, x29, 1 addi x31, x30, 1 main_end: - j main + j main_end -- cgit v1.1