debug: Fixing the non-RTOS behavior for DownloadTest
[riscv-tests.git] / debug / gdbserver.py
index bf279503ecb41c921ec82695de213ebac45c9642..0c3cee4b3328fd12bb0c045482923c2c532a51d4 100755 (executable)
@@ -136,6 +136,19 @@ class SimpleF18Test(SimpleRegisterTest):
     def test(self):
         self.check_reg("f18", "fs2")
 
+class SimpleNoExistTest(GdbTest):
+    def test(self):
+        try:
+            self.gdb.p("$csr2288")
+            assert False, "Reading csr2288 should have failed"
+        except testlib.CouldNotFetch:
+            pass
+        try:
+            self.gdb.p("$csr2288=5")
+            assert False, "Writing csr2288 should have failed"
+        except testlib.CouldNotFetch:
+            pass
+
 class SimpleMemoryTest(GdbTest):
     def access_test(self, size, data_type):
         assertEqual(self.gdb.p("sizeof(%s)" % data_type), size)
@@ -338,7 +351,9 @@ class DebugSymbols(DebugTest):
 
 class DebugBreakpoint(DebugTest):
     def test(self):
+
         self.gdb.b("rot13")
+
         # The breakpoint should be hit exactly 2 times.
         for _ in range(2):
             output = self.gdb.c()
@@ -602,7 +617,7 @@ class MulticoreRunAllHaltOne(GdbTest):
         time.sleep(1)
         self.gdb.p("buf", fmt="")
 
-class StepTest(GdbTest):
+class StepTest(GdbSingleHartTest):
     compile_args = ("programs/step.S", )
 
     def setup(self):
@@ -621,7 +636,7 @@ class StepTest(GdbTest):
             pc = self.gdb.p("$pc")
             assertEqual("%x" % (pc - main_address), "%x" % expected)
 
-class TriggerTest(GdbTest):
+class TriggerTest(GdbSingleHartTest):
     compile_args = ("programs/trigger.S", )
     def setup(self):
         self.gdb.load()
@@ -660,12 +675,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):
@@ -735,7 +755,7 @@ class TriggerDmode(TriggerTest):
         assertIn("clear_triggers", output)
         self.check_triggers((1<<6) | (1<<0), 0xfeedac00)
 
-class RegsTest(GdbTest):
+class RegsTest(GdbSingleHartTest):
     compile_args = ("programs/regs.S", )
     def setup(self):
         self.gdb.load()
@@ -815,13 +835,27 @@ class DownloadTest(GdbTest):
         self.gdb.command("file %s" % self.binary)
 
     def test(self):
-        self.gdb.load()
-        self.gdb.command("b _exit")
-        self.gdb.c(timeout=60)
+        # Some hart will compete the CRC calculation first!
+        # Let them race in RTOS mode.
+        # In non-RTOS mode, only one hart will continue.
+        # This loop will fail because the others won't know 
+        # about '_start'. But if that is the case, they
+        # won't run on the `continue` either, so we don't really care.
+        try:
+            self.gdb.load()
+            for hart in self.target.harts:
+                self.gdb.select_hart(hart)
+                self.gdb.p("$pc=_start")
+        except ValueError: #invalid literal for int() with base 0: 'No symbol table is loaded.  Use the "file" command.'
+            pass
+        finally:
+            
+        self.gdb.select_hart(self.hart)
+        self.gdb.c()
         assertEqual(self.gdb.p("status"), self.crc)
         os.unlink(self.download_c.name)
 
-#class MprvTest(GdbTest):
+#class MprvTest(GdbSingleHartTest):
 #    compile_args = ("programs/mprv.S", )
 #    def setup(self):
 #        self.gdb.load()
@@ -834,7 +868,7 @@ class DownloadTest(GdbTest):
 #        output = self.gdb.command("p/x *(int*)(((char*)&data)-0x80000000)")
 #        assertIn("0xbead", output)
 
-class PrivTest(GdbTest):
+class PrivTest(GdbSingleHartTest):
     compile_args = ("programs/priv.S", )
     def setup(self):
         # pylint: disable=attribute-defined-outside-init
@@ -855,9 +889,21 @@ class PrivRw(PrivTest):
         """Test reading/writing priv."""
         # Disable physical memory protection by allowing U mode access to all
         # memory.
-        self.gdb.p("$pmpcfg0=0xf")  # TOR, R, W, X
-        self.gdb.p("$pmpaddr0=0x%x" %
-                ((self.hart.ram + self.hart.ram_size) >> 2))
+        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
+
+        # Ensure Virtual Memory is disabled if applicable (SATP register is not
+        # reset)
+        try:
+            self.gdb.p("$satp=0")
+        except testlib.CouldNotFetch:
+            # SATP only exists if you have S mode.
+            pass
 
         # Leave the PC at _start, where the first 4 instructions should be
         # legal in any mode.