Add test case for `riscv expose_custom`.
[riscv-tests.git] / debug / gdbserver.py
index 2e7e4cf22222435457675c447ba45788d3531f4f..c362e1dc03dea441af582c093cbf490eba36101e 100755 (executable)
@@ -12,7 +12,8 @@ import targets
 import testlib
 from testlib import assertEqual, assertNotEqual, assertIn, assertNotIn
 from testlib import assertGreater, assertRegexpMatches, assertLess
 import testlib
 from testlib import assertEqual, assertNotEqual, assertIn, assertNotIn
 from testlib import assertGreater, assertRegexpMatches, assertLess
-from testlib import GdbTest, GdbSingleHartTest, TestFailed, assertTrue
+from testlib import GdbTest, GdbSingleHartTest, TestFailed
+#from testlib import assertTrue
 
 MSTATUS_UIE = 0x00000001
 MSTATUS_SIE = 0x00000002
 
 MSTATUS_UIE = 0x00000001
 MSTATUS_SIE = 0x00000002
@@ -136,6 +137,36 @@ class SimpleF18Test(SimpleRegisterTest):
     def test(self):
         self.check_reg("f18", "fs2")
 
     def test(self):
         self.check_reg("f18", "fs2")
 
+class CustomRegisterTest(SimpleRegisterTest):
+    def early_applicable(self):
+        return self.target.implements_custom_test
+
+    def check_custom(self, magic):
+        regs = self.gdb.info_registers("custom")
+        assertEqual(set(regs.keys()),
+                set(("custom1",
+                    "custom12345",
+                    "custom12346",
+                    "custom12347",
+                    "custom12348")))
+        for name, value in regs.iteritems():
+            number = int(name[6:])
+            if number % 2:
+                expect = number + magic
+                assertIn(value, (expect, expect + (1<<32)))
+            else:
+                assertIn("Could not fetch register", value)
+
+    def test(self):
+        self.check_custom(0)
+
+        # Now test writing
+        magic = 6667
+        self.gdb.p("$custom12345=%d" % (12345 + magic))
+        self.gdb.stepi()
+
+        self.check_custom(magic)
+
 class SimpleNoExistTest(GdbTest):
     def test(self):
         try:
 class SimpleNoExistTest(GdbTest):
     def test(self):
         try:
@@ -774,7 +805,19 @@ class TriggerStoreAddressInstant(TriggerTest):
         write_loop = self.gdb.p("&write_loop")
         data = self.gdb.p("&data")
         self.gdb.command("watch *0x%x" % data)
         write_loop = self.gdb.p("&write_loop")
         data = self.gdb.p("&data")
         self.gdb.command("watch *0x%x" % data)
-        self.gdb.c()
+        output = self.gdb.c()
+        if "_exit (status=0)" in output:
+            # We ran to _exit. It looks as if we didn't hit the trigger at all.
+            # However this can be "correct" behavior. gdb's definition of
+            # "watch" is to run until the value in memory changes. To do this
+            # it reads the memory value when the trigger is set, and then when
+            # the halt happens. Because our triggers can fire just before the
+            # write happens, when gdb does this check the memory hasn't
+            # changed. So it silently resumes running.
+            # https://github.com/riscv/riscv-openocd/issues/295 tracks this
+            # problem. Until it's fixed, we're going to allow running to _exit.
+            return
+
         # Accept hitting the breakpoint before or after the store instruction.
         assertIn(self.gdb.p("$pc"), [write_loop, write_loop + 4])
         assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))
         # Accept hitting the breakpoint before or after the store instruction.
         assertIn(self.gdb.p("$pc"), [write_loop, write_loop + 4])
         assertEqual(self.gdb.p("$a0"), self.gdb.p("&data"))