debug: Make the 'out of reset' tests actually apply reset
[riscv-tests.git] / debug / gdbserver.py
index dbc37fc222958dd2c6331b94a0b5a0de0ffc8d6d..5ac0153c469cf566fa3a811491475ca5dd4e9796 100755 (executable)
@@ -10,8 +10,8 @@ import os
 
 import targets
 import testlib
-from testlib import assertEqual, assertNotEqual, assertIn
-from testlib import assertGreater, assertTrue, assertRegexpMatches, assertLess
+from testlib import assertEqual, assertNotEqual, assertIn, assertNotIn
+from testlib import assertGreater, assertRegexpMatches, assertLess
 from testlib import GdbTest
 
 MSTATUS_UIE = 0x00000001
@@ -205,6 +205,9 @@ class MemTestBlock(GdbTest):
 
 class InstantHaltTest(GdbTest):
     def test(self):
+        """Assert that reset is really resetting what it should."""
+        self.gdb.command("monitor reset halt")
+        self.gdb.command("flushregs")
         assertEqual(self.target.reset_vector, self.gdb.p("$pc"))
         # mcycle and minstret have no defined reset value.
         mstatus = self.gdb.p("$mstatus")
@@ -215,6 +218,8 @@ class InstantChangePc(GdbTest):
     def test(self):
         """Change the PC right as we come out of reset."""
         # 0x13 is nop
+        self.gdb.command("monitor reset halt")
+        self.gdb.command("flushregs")
         self.gdb.command("p *((int*) 0x%x)=0x13" % self.target.ram)
         self.gdb.command("p *((int*) 0x%x)=0x13" % (self.target.ram + 4))
         self.gdb.command("p *((int*) 0x%x)=0x13" % (self.target.ram + 8))
@@ -275,7 +280,7 @@ class DebugTurbostep(DebugTest):
         last_pc = None
         advances = 0
         jumps = 0
-        for _ in range(100):
+        for _ in range(10):
             self.gdb.stepi()
             pc = self.gdb.p("$pc")
             assertNotEqual(last_pc, pc)
@@ -286,8 +291,8 @@ class DebugTurbostep(DebugTest):
             last_pc = pc
         # Some basic sanity that we're not running between breakpoints or
         # something.
-        assertGreater(jumps, 10)
-        assertGreater(advances, 50)
+        assertGreater(jumps, 1)
+        assertGreater(advances, 5)
 
 class DebugExit(DebugTest):
     def test(self):
@@ -399,6 +404,68 @@ class UserInterrupt(DebugTest):
         self.gdb.p("i=0")
         self.exit()
 
+class MulticoreTest(GdbTest):
+    compile_args = ("programs/infinite_loop.S", )
+
+    def setup(self):
+        self.gdb.load()
+        self.gdb.b("main")
+        self.gdb.b("main_end")
+        self.gdb.command("set non-stop on")
+        self.gdb.c()
+
+    def test(self):
+        threads = self.gdb.threads()
+        if len(threads) < 2:
+            return 'not_applicable'
+        # Run through the entire loop.
+        for t in threads:
+            self.gdb.thread(t)
+            self.gdb.p("$pc=_start")
+        # Run to main
+        for t in threads:
+            self.gdb.thread(t)
+            self.gdb.c()
+        for t in self.gdb.threads():
+            assertIn("main", t.frame)
+        # Run to end
+        for t in threads:
+            self.gdb.thread(t)
+            self.gdb.c()
+        hart_ids = []
+        for t in self.gdb.threads():
+            assertIn("main_end", t.frame)
+            # Check register values.
+            self.gdb.thread(t)
+            hart_id = self.gdb.p("$x1")
+            assertNotIn(hart_id, hart_ids)
+            hart_ids.append(hart_id)
+            for n in range(2, 32):
+                value = self.gdb.p("$x%d" % n)
+                assertEqual(value, hart_ids[-1] + n - 1)
+
+        # Confirmed that we read different register values for different harts.
+        # Write a new value to x1, and run through the add sequence again.
+
+        # This part isn't working right, because gdb doesn't resume Thread 2
+        # when asked. I don't know the root cause for that, but up to this
+        # point the test is still useful.
+
+#        for t in threads:
+#            self.gdb.thread(t)
+#            self.gdb.p("$x1=0x%x" % (int(t.id) + 0x800))
+#            self.gdb.p("$pc=main_post_csrr")
+#        for t in threads:
+#            self.gdb.thread(t)
+#            self.gdb.c()
+#        for t in self.gdb.threads():
+#            assertIn("main_end", t.frame)
+#            # Check register values.
+#            self.gdb.thread(t)
+#            for n in range(1, 32):
+#                value = self.gdb.p("$x%d" % n)
+#                assertEqual(value, int(t.id) + 0x800 + n - 1)
+
 class StepTest(GdbTest):
     compile_args = ("programs/step.S", )
 
@@ -578,7 +645,7 @@ class WriteCsrs(RegsTest):
 class DownloadTest(GdbTest):
     def setup(self):
         # pylint: disable=attribute-defined-outside-init
-        length = min(2**20, self.target.ram_size - 2048)
+        length = min(2**10, self.target.ram_size - 2048)
         self.download_c = tempfile.NamedTemporaryFile(prefix="download_",
                 suffix=".c", delete=False)
         self.download_c.write("#include <stdint.h>\n")
@@ -695,8 +762,8 @@ def main():
     # TODO: remove global
     global parsed   # pylint: disable=global-statement
     parsed = parser.parse_args()
+    target = targets.target(parsed)
 
-    target = parsed.target(parsed.server_cmd, parsed.sim_cmd, parsed.isolate)
     if parsed.xlen:
         target.xlen = parsed.xlen