X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=debug%2Fgdbserver.py;h=162854c59939d7ac57fa789910a8c42370a9f867;hb=6f7ebb610d6bb8817a9592cc06a7d108381f1761;hp=dea9990ceca844866e345816c6c1783796099417;hpb=ea9e37ff1411a8648710b5539b0971bb5ae9571f;p=riscv-tests.git diff --git a/debug/gdbserver.py b/debug/gdbserver.py index dea9990..162854c 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -12,7 +12,7 @@ import targets import testlib from testlib import assertEqual, assertNotEqual, assertIn, assertNotIn from testlib import assertGreater, assertRegexpMatches, assertLess -from testlib import GdbTest +from testlib import GdbTest, GdbSingleHartTest, TestFailed, assertTrue MSTATUS_UIE = 0x00000001 MSTATUS_SIE = 0x00000002 @@ -65,72 +65,79 @@ def readable_binary_string(s): return "".join("%02x" % ord(c) for c in s) class SimpleRegisterTest(GdbTest): - def check_reg(self, name): - a = random.randrange(1< 1000 and \ + local > 1000: + return + + assertGreater(interrupt_count, 1000) + assertGreater(local, 1000) + + def postMortem(self): + GdbSingleHartTest.postMortem(self) + self.gdb.p("*((long long*) 0x200bff8)") + self.gdb.p("*((long long*) 0x2004000)") + self.gdb.p("interrupt_count") + self.gdb.p("local") + +class MulticoreRegTest(GdbTest): + compile_args = ("programs/infinite_loop.S", "-DMULTICORE") - for t in threads: - self.gdb.thread(t) + def early_applicable(self): + return len(self.target.harts) > 1 + + def setup(self): + self.gdb.load() + for hart in self.target.harts: + self.gdb.select_hart(hart) self.gdb.p("$pc=_start") + def test(self): # 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") + for hart in self.target.harts: + self.gdb.select_hart(hart) + self.gdb.b("main") + self.gdb.c() + assertIn("main", self.gdb.where()) + self.gdb.command("delete breakpoints") # Run through the entire loop. - self.gdb.b("main_end") - self.gdb.c() + for hart in self.target.harts: + self.gdb.select_hart(hart) + self.gdb.b("main_end") + self.gdb.c() + assertIn("main_end", self.gdb.where()) hart_ids = [] - for t in self.gdb.threads(): - assertIn("main_end", t.frame) + for hart in self.target.harts: + self.gdb.select_hart(hart) # Check register values. - self.gdb.thread(t) hart_id = self.gdb.p("$x1") assertNotIn(hart_id, hart_ids) hart_ids.append(hart_id) @@ -457,18 +515,53 @@ class MulticoreTest(GdbTest): # 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)) + for hart in self.target.harts: + self.gdb.select_hart(hart) + self.gdb.p("$x1=0x%x" % (hart.index * 0x800)) self.gdb.p("$pc=main_post_csrr") - self.gdb.c() - for t in self.gdb.threads(): - assertIn("main_end", t.frame) + self.gdb.c() + for hart in self.target.harts: + self.gdb.select_hart(hart) + assertIn("main", self.gdb.where()) # 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) + assertEqual(value, hart.index * 0x800 + n - 1) + +class MulticoreRunHaltStepiTest(GdbTest): + compile_args = ("programs/multicore.c", "-DMULTICORE") + + def early_applicable(self): + return len(self.target.harts) > 1 + + def setup(self): + self.gdb.load() + for hart in self.target.harts: + self.gdb.select_hart(hart) + self.gdb.p("$pc=_start") + + def test(self): + previous_hart_count = [0 for h in self.target.harts] + previous_interrupt_count = [0 for h in self.target.harts] + for _ in range(10): + self.gdb.c(wait=False) + time.sleep(2) + self.gdb.interrupt() + self.gdb.p("$mie") + self.gdb.p("$mip") + self.gdb.p("$mstatus") + self.gdb.p("$priv") + self.gdb.p("buf", fmt="") + hart_count = self.gdb.p("hart_count") + interrupt_count = self.gdb.p("interrupt_count") + for i, h in enumerate(self.target.harts): + assertGreater(hart_count[i], previous_hart_count[i]) + assertGreater(interrupt_count[i], previous_interrupt_count[i]) + self.gdb.select_hart(h) + pc = self.gdb.p("$pc") + self.gdb.stepi() + stepped_pc = self.gdb.p("$pc") + assertNotEqual(pc, stepped_pc) class StepTest(GdbTest): compile_args = ("programs/step.S", ) @@ -480,7 +573,7 @@ class StepTest(GdbTest): def test(self): main_address = self.gdb.p("$pc") - if self.target.extensionSupported("c"): + if self.hart.extensionSupported("c"): sequence = (4, 8, 0xc, 0xe, 0x14, 0x18, 0x22, 0x1c, 0x24, 0x24) else: sequence = (4, 8, 0xc, 0x10, 0x18, 0x1c, 0x28, 0x20, 0x2c, 0x2c) @@ -559,16 +652,16 @@ class TriggerStoreAddressInstant(TriggerTest): class TriggerDmode(TriggerTest): def early_applicable(self): - return self.target.honors_tdata1_hmode + return self.hart.honors_tdata1_hmode def check_triggers(self, tdata1_lsbs, tdata2): - dmode = 1 << (self.target.xlen-5) + dmode = 1 << (self.hart.xlen-5) triggers = [] - if self.target.xlen == 32: + if self.hart.xlen == 32: xlen_type = 'int' - elif self.target.xlen == 64: + elif self.hart.xlen == 64: xlen_type = 'long long' else: raise NotImplementedError @@ -628,7 +721,7 @@ class WriteGprs(RegsTest): self.gdb.command("info registers") for n in range(len(regs)): assertEqual(self.gdb.x("data+%d" % (8*n), 'g'), - ((0xdeadbeef<\n") @@ -678,7 +771,7 @@ class DownloadTest(GdbTest): if self.crc < 0: self.crc += 2**32 - self.binary = self.target.compile(self.download_c.name, + self.binary = self.target.compile(self.hart, self.download_c.name, "programs/checksum.c") self.gdb.command("file %s" % self.binary) @@ -689,7 +782,6 @@ class DownloadTest(GdbTest): assertEqual(self.gdb.p("status"), self.crc) os.unlink(self.download_c.name) -# FIXME: PRIV isn't implemented in the current OpenOCD #class MprvTest(GdbTest): # compile_args = ("programs/mprv.S", ) # def setup(self): @@ -702,56 +794,56 @@ class DownloadTest(GdbTest): # self.gdb.interrupt() # output = self.gdb.command("p/x *(int*)(((char*)&data)-0x80000000)") # assertIn("0xbead", output) -# -#class PrivTest(GdbTest): -# compile_args = ("programs/priv.S", ) -# def setup(self): -# # pylint: disable=attribute-defined-outside-init -# self.gdb.load() -# -# misa = self.target.misa -# self.supported = set() -# if misa & (1<<20): -# self.supported.add(0) -# if misa & (1<<18): -# self.supported.add(1) -# if misa & (1<<7): -# self.supported.add(2) -# self.supported.add(3) -# -#class PrivRw(PrivTest): -# def test(self): -# """Test reading/writing priv.""" -# for privilege in range(4): -# self.gdb.p("$priv=%d" % privilege) -# self.gdb.stepi() -# actual = self.gdb.p("$priv") -# assertIn(actual, self.supported) -# if privilege in self.supported: -# assertEqual(actual, privilege) -# -#class PrivChange(PrivTest): -# def test(self): -# """Test that the core's privilege level actually changes.""" -# -# if 0 not in self.supported: -# return 'not_applicable' -# -# self.gdb.b("main") -# self.gdb.c() -# -# # Machine mode -# self.gdb.p("$priv=3") -# main_address = self.gdb.p("$pc") -# self.gdb.stepi() -# assertEqual("%x" % self.gdb.p("$pc"), "%x" % (main_address+4)) -# -# # User mode -# self.gdb.p("$priv=0") -# self.gdb.stepi() -# # Should have taken an exception, so be nowhere near main. -# pc = self.gdb.p("$pc") -# assertTrue(pc < main_address or pc > main_address + 0x100) + +class PrivTest(GdbTest): + compile_args = ("programs/priv.S", ) + def setup(self): + # pylint: disable=attribute-defined-outside-init + self.gdb.load() + + misa = self.hart.misa + self.supported = set() + if misa & (1<<20): + self.supported.add(0) + if misa & (1<<18): + self.supported.add(1) + if misa & (1<<7): + self.supported.add(2) + self.supported.add(3) + +class PrivRw(PrivTest): + def test(self): + """Test reading/writing priv.""" + for privilege in range(4): + self.gdb.p("$priv=%d" % privilege) + self.gdb.stepi() + actual = self.gdb.p("$priv") + assertIn(actual, self.supported) + if privilege in self.supported: + assertEqual(actual, privilege) + +class PrivChange(PrivTest): + def test(self): + """Test that the core's privilege level actually changes.""" + + if 0 not in self.supported: + return 'not_applicable' + + self.gdb.b("main") + self.gdb.c() + + # Machine mode + self.gdb.p("$priv=3") + main_address = self.gdb.p("$pc") + self.gdb.stepi() + assertEqual("%x" % self.gdb.p("$pc"), "%x" % (main_address+4)) + + # User mode + self.gdb.p("$priv=0") + self.gdb.stepi() + # Should have taken an exception, so be nowhere near main. + pc = self.gdb.p("$pc") + assertTrue(pc < main_address or pc > main_address + 0x100) parsed = None def main(): @@ -771,6 +863,8 @@ def main(): parsed = parser.parse_args() target = targets.target(parsed) + testlib.print_log_names = parsed.print_log_names + if parsed.xlen: target.xlen = parsed.xlen