Test resuming from a trigger.
[riscv-tests.git] / debug / gdbserver.py
index 4d8d99a2276debf89f0cf2e30868bc3c25c4cc0a..f0385d568441b3eeb8d1d73dc5f71b19b2a7d221 100755 (executable)
@@ -65,15 +65,19 @@ def readable_binary_string(s):
     return "".join("%02x" % ord(c) for c in s)
 
 class SimpleRegisterTest(GdbTest):
-    def check_reg(self, name):
+    def check_reg(self, name, alias):
         a = random.randrange(1<<self.hart.xlen)
         b = random.randrange(1<<self.hart.xlen)
         self.gdb.p("$%s=0x%x" % (name, a))
+        assertEqual(self.gdb.p("$%s" % alias), a)
         self.gdb.stepi()
         assertEqual(self.gdb.p("$%s" % name), a)
-        self.gdb.p("$%s=0x%x" % (name, b))
+        assertEqual(self.gdb.p("$%s" % alias), a)
+        self.gdb.p("$%s=0x%x" % (alias, b))
+        assertEqual(self.gdb.p("$%s" % name), b)
         self.gdb.stepi()
         assertEqual(self.gdb.p("$%s" % name), b)
+        assertEqual(self.gdb.p("$%s" % alias), b)
 
     def setup(self):
         # 0x13 is nop
@@ -86,38 +90,51 @@ class SimpleRegisterTest(GdbTest):
 
 class SimpleS0Test(SimpleRegisterTest):
     def test(self):
-        self.check_reg("s0")
+        self.check_reg("s0", "x8")
 
 class SimpleS1Test(SimpleRegisterTest):
     def test(self):
-        self.check_reg("s1")
+        self.check_reg("s1", "x9")
 
 class SimpleT0Test(SimpleRegisterTest):
     def test(self):
-        self.check_reg("t0")
+        self.check_reg("t0", "x5")
 
 class SimpleT1Test(SimpleRegisterTest):
     def test(self):
-        self.check_reg("t1")
+        self.check_reg("t1", "x6")
 
 class SimpleF18Test(SimpleRegisterTest):
-    def check_reg(self, name):
-        self.gdb.p_raw("$mstatus=$mstatus | 0x00006000")
-        self.gdb.stepi()
-        a = random.random()
-        b = random.random()
-        self.gdb.p_raw("$%s=%f" % (name, a))
-        self.gdb.stepi()
-        assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - a), .001)
-        self.gdb.p_raw("$%s=%f" % (name, b))
-        self.gdb.stepi()
-        assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - b), .001)
+    def check_reg(self, name, alias):
+        if self.hart.extensionSupported('F'):
+            self.gdb.p_raw("$mstatus=$mstatus | 0x00006000")
+            self.gdb.stepi()
+            a = random.random()
+            b = random.random()
+            self.gdb.p_raw("$%s=%f" % (name, a))
+            assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - a), .001)
+            self.gdb.stepi()
+            assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - a), .001)
+            assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - a), .001)
+            self.gdb.p_raw("$%s=%f" % (alias, b))
+            assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - b), .001)
+            self.gdb.stepi()
+            assertLess(abs(float(self.gdb.p_raw("$%s" % name)) - b), .001)
+            assertLess(abs(float(self.gdb.p_raw("$%s" % alias)) - b), .001)
 
-    def early_applicable(self):
-        return self.hart.extensionSupported('F')
+            size = self.gdb.p("sizeof($%s)" % name)
+            if self.hart.extensionSupported('D'):
+                assertEqual(size, 8)
+            else:
+                assertEqual(size, 4)
+        else:
+            output = self.gdb.p_raw("$" + name)
+            assertEqual(output, "void")
+            output = self.gdb.p_raw("$" + alias)
+            assertEqual(output, "void")
 
     def test(self):
-        self.check_reg("f18")
+        self.check_reg("f18", "fs2")
 
 class SimpleMemoryTest(GdbTest):
     def access_test(self, size, data_type):
@@ -199,7 +216,7 @@ class MemTestBlock(GdbTest):
         self.gdb.command("dump ihex memory %s 0x%x 0x%x" % (b.name,
             self.hart.ram, self.hart.ram + self.length))
         self.gdb.command("shell cat %s" % b.name)
-        for line in b:
+        for line in b.xreadlines():
             record_type, address, line_data = ihex_parse(line)
             if record_type == 0:
                 written_data = data[address:address+len(line_data)]
@@ -388,6 +405,8 @@ class Registers(DebugTest):
             output = self.gdb.command(cmd)
             for reg in ('zero', 'ra', 'sp', 'gp', 'tp'):
                 assertIn(reg, output)
+            for line in output.splitlines():
+                assertRegexpMatches(line, r"^\S")
 
         #TODO
         # mcpuid is one of the few registers that should have the high bit set
@@ -555,6 +574,34 @@ class MulticoreRunHaltStepiTest(GdbTest):
                 stepped_pc = self.gdb.p("$pc")
                 assertNotEqual(pc, stepped_pc)
 
+class MulticoreRunAllHaltOne(GdbTest):
+    compile_args = ("programs/multicore.c", "-DMULTICORE")
+
+    def early_applicable(self):
+        return len(self.target.harts) > 1
+
+    def setup(self):
+        self.gdb.select_hart(self.target.harts[0])
+        self.gdb.load()
+        for hart in self.target.harts:
+            self.gdb.select_hart(hart)
+            self.gdb.p("$pc=_start")
+
+    def test(self):
+        if not self.gdb.one_hart_per_gdb():
+            return 'not_applicable'
+
+        # Run harts in reverse order
+        for h in reversed(self.target.harts):
+            self.gdb.select_hart(h)
+            self.gdb.c(wait=False)
+
+        self.gdb.interrupt()
+        # Give OpenOCD time to call poll() on both harts, which is what causes
+        # the bug.
+        time.sleep(1)
+        self.gdb.p("buf", fmt="")
+
 class StepTest(GdbTest):
     compile_args = ("programs/step.S", )
 
@@ -613,12 +660,17 @@ class TriggerLoadAddressInstant(TriggerTest):
         self.gdb.command("b just_before_read_loop")
         self.gdb.c()
         read_loop = self.gdb.p("&read_loop")
+        read_again = self.gdb.p("&read_again")
         self.gdb.command("rwatch data")
         self.gdb.c()
         # Accept hitting the breakpoint before or after the load instruction.
         assertIn(self.gdb.p("$pc"), [read_loop, read_loop + 4])
         assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
 
+        self.gdb.c()
+        assertIn(self.gdb.p("$pc"), [read_again, read_again + 4])
+        assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
+
 # FIXME: Triggers aren't quite working yet
 #class TriggerStoreAddress(TriggerTest):
 #    def test(self):
@@ -806,6 +858,18 @@ class PrivTest(GdbTest):
 class PrivRw(PrivTest):
     def test(self):
         """Test reading/writing priv."""
+        # Disable physical memory protection by allowing U mode access to all
+        # memory.
+        try:
+            self.gdb.p("$pmpcfg0=0xf")  # TOR, R, W, X
+            self.gdb.p("$pmpaddr0=0x%x" %
+                    ((self.hart.ram + self.hart.ram_size) >> 2))
+        except testlib.CouldNotFetch:
+            # PMP registers are optional
+            pass
+
+        # Leave the PC at _start, where the first 4 instructions should be
+        # legal in any mode.
         for privilege in range(4):
             self.gdb.p("$priv=%d" % privilege)
             self.gdb.stepi()
@@ -854,9 +918,7 @@ def main():
     global parsed   # pylint: disable=global-statement
     parsed = parser.parse_args()
     target = targets.target(parsed)
-
-    if parsed.xlen:
-        target.xlen = parsed.xlen
+    testlib.print_log_names = parsed.print_log_names
 
     module = sys.modules[__name__]