Increase delay in UserInterrupt.
[riscv-tests.git] / debug / gdbserver.py
index dbc37fc222958dd2c6331b94a0b5a0de0ffc8d6d..cbb1299ad9ecafc009df6c486a8e656f49fde011 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
@@ -124,13 +124,12 @@ class SimpleMemoryTest(GdbTest):
         assertEqual(self.gdb.p("sizeof(%s)" % data_type), size)
         a = 0x86753095555aaaa & ((1<<(size*8))-1)
         b = 0xdeadbeef12345678 & ((1<<(size*8))-1)
-        self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, self.target.ram, a))
-        self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, self.target.ram + size,
-            b))
-        assertEqual(self.gdb.p("*((%s*)0x%x)" % (data_type, self.target.ram)),
-                a)
-        assertEqual(self.gdb.p("*((%s*)0x%x)" % (
-            data_type, self.target.ram + size)), b)
+        addrA = self.target.ram
+        addrB = self.target.ram + self.target.ram_size - size
+        self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, addrA, a))
+        self.gdb.p("*((%s*)0x%x) = 0x%x" % (data_type, addrB, b))
+        assertEqual(self.gdb.p("*((%s*)0x%x)" % (data_type, addrA)), a)
+        assertEqual(self.gdb.p("*((%s*)0x%x)" % (data_type, addrB)), b)
 
 class MemTest8(SimpleMemoryTest):
     def test(self):
@@ -205,7 +204,16 @@ class MemTestBlock(GdbTest):
 
 class InstantHaltTest(GdbTest):
     def test(self):
-        assertEqual(self.target.reset_vector, self.gdb.p("$pc"))
+        """Assert that reset is really resetting what it should."""
+        self.gdb.command("monitor reset halt")
+        self.gdb.command("flushregs")
+        threads = self.gdb.threads()
+        pcs = []
+        for t in threads:
+            self.gdb.thread(t)
+            pcs.append(self.gdb.p("$pc"))
+        for pc in pcs:
+            assertEqual(self.target.reset_vector, pc)
         # mcycle and minstret have no defined reset value.
         mstatus = self.gdb.p("$mstatus")
         assertEqual(mstatus & (MSTATUS_MIE | MSTATUS_MPRV |
@@ -215,6 +223,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 +285,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 +296,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):
@@ -318,6 +328,12 @@ class Hwbp1(DebugTest):
         if self.target.instruction_hardware_breakpoint_count < 1:
             return 'not_applicable'
 
+        if not self.target.honors_tdata1_hmode:
+            # Run to main before setting the breakpoint, because startup code
+            # will otherwise clear the trigger that we set.
+            self.gdb.b("main")
+            self.gdb.c()
+
         self.gdb.hbreak("rot13")
         # The breakpoint should be hit exactly 2 times.
         for _ in range(2):
@@ -392,13 +408,67 @@ class UserInterrupt(DebugTest):
         self.gdb.c()
         self.gdb.p("i=123")
         self.gdb.c(wait=False)
-        time.sleep(0.5)
+        time.sleep(2)
         output = self.gdb.interrupt()
         assert "main" in output
         assertGreater(self.gdb.p("j"), 10)
         self.gdb.p("i=0")
         self.exit()
 
+class MulticoreTest(GdbTest):
+    compile_args = ("programs/infinite_loop.S", )
+
+    def setup(self):
+        self.gdb.load()
+
+    def test(self):
+        threads = self.gdb.threads()
+        if len(threads) < 2:
+            return 'not_applicable'
+
+        for t in threads:
+            self.gdb.thread(t)
+            self.gdb.p("$pc=_start")
+
+        # Run to main
+        self.gdb.b("main")
+        self.gdb.c()
+        for t in self.gdb.threads():
+            assertIn("main", t.frame)
+        self.gdb.command("delete breakpoints")
+
+        # Run through the entire loop.
+        self.gdb.b("main_end")
+        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.
+
+        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")
+        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", )
 
@@ -487,6 +557,9 @@ class TriggerStoreAddressInstant(TriggerTest):
         assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
 
 class TriggerDmode(TriggerTest):
+    def early_applicable(self):
+        return self.target.honors_tdata1_hmode
+
     def check_triggers(self, tdata1_lsbs, tdata2):
         dmode = 1 << (self.target.xlen-5)
 
@@ -578,7 +651,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 +768,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