diff options
author | Tim Newsome <tim@sifive.com> | 2019-02-14 14:53:57 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-14 14:53:57 -0800 |
commit | 26d821d126fd0e36bf286420452f5628c946e7cb (patch) | |
tree | 7492e579724144c01cdcf08998f3c753526c9bca | |
parent | 353b55bc233ef314dd27b547af0a6bdee217b3f4 (diff) | |
download | riscv-tests-26d821d126fd0e36bf286420452f5628c946e7cb.zip riscv-tests-26d821d126fd0e36bf286420452f5628c946e7cb.tar.gz riscv-tests-26d821d126fd0e36bf286420452f5628c946e7cb.tar.bz2 |
Test `-rtos hwthread` (#178)
* WIP
* Use hwthread everywhere.
* Test `-rtos hwthread`.
Also tweak timeouts a bit so that we don't have ridiculous timeouts for
simple operations.
* Tweak timeouts so tests pass on a loaded system.
-rw-r--r-- | debug/Makefile | 3 | ||||
-rwxr-xr-x | debug/gdbserver.py | 22 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike-2-hwthread.cfg | 31 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike32-2-hwthread.py | 13 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike64-2-hwthread.py | 13 | ||||
-rw-r--r-- | debug/testlib.py | 21 |
6 files changed, 81 insertions, 22 deletions
diff --git a/debug/Makefile b/debug/Makefile index 48be07c..75900df 100644 --- a/debug/Makefile +++ b/debug/Makefile @@ -6,7 +6,8 @@ GDBSERVER_PY = $(src_dir)/gdbserver.py default: spike$(XLEN) spike$(XLEN)-2 -all-tests: spike32 spike32-2 spike32-2-rtos spike64 spike64-2 spike64-2-rtos +all-tests: spike32 spike32-2 spike32-2-rtos spike32-2-hwthread \ + spike64 spike64-2 spike64-2-rtos spike64-2-hwthread all: pylint all-tests diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 0956fa8..adcb6b2 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -269,10 +269,10 @@ class MemTestBlockReadInvalid(GdbTest): self.hart.ram + 8, self.real_values) - self.gdb.p("*((int*)0x%x) = 0xdeadbeef" % (self.hart.ram + - self.hart.ram_size - 8)) - self.gdb.p("*((int*)0x%x) = 0x12345678" % (self.hart.ram + - self.hart.ram_size - 4)) + self.gdb.p("*((int*)0x%x) = 0xdeadbeef" % + (self.hart.ram + self.hart.ram_size - 8)) + self.gdb.p("*((int*)0x%x) = 0x12345678" % + (self.hart.ram + self.hart.ram_size - 4)) # read before end of memory self.memory_test(self.hart.ram + self.hart.ram_size - 8, @@ -291,8 +291,8 @@ class MemTestBlockReadInvalid(GdbTest): def memory_test(self, start_addr, end_addr, expected_values): dump = tempfile.NamedTemporaryFile(suffix=".simdata") - self.gdb.command("dump verilog memory %s 0x%x 0x%x" % (dump.name, - start_addr, end_addr)) + self.gdb.command("dump verilog memory %s 0x%x 0x%x" % + (dump.name, start_addr, end_addr)) self.gdb.command("shell cat %s" % dump.name) line = dump.readline() line = dump.readline() @@ -472,8 +472,8 @@ class DebugFunctionCall(DebugTest): def test(self): self.gdb.b("main:start") self.gdb.c() - assertEqual(self.gdb.p('fib(6)'), 8) - assertEqual(self.gdb.p('fib(7)'), 13) + assertEqual(self.gdb.p('fib(6)', ops=10), 8) + assertEqual(self.gdb.p('fib(7)', ops=10), 13) self.exit() class DebugChangeString(DebugTest): @@ -593,7 +593,7 @@ class Registers(DebugTest): self.gdb.c() # Try both forms to test gdb. for cmd in ("info all-registers", "info registers all"): - output = self.gdb.command(cmd, ops=100) + output = self.gdb.command(cmd, ops=20) for reg in ('zero', 'ra', 'sp', 'gp', 'tp'): assertIn(reg, output) for line in output.splitlines(): @@ -707,7 +707,9 @@ class MulticoreRegTest(GdbTest): for hart in self.target.harts: self.gdb.select_hart(hart) # Check register values. - hart_id = self.gdb.p("$x1") + x1 = self.gdb.p("$x1") + hart_id = self.gdb.p("$mhartid") + assertEqual(x1, hart_id) assertNotIn(hart_id, hart_ids) hart_ids.append(hart_id) for n in range(2, 32): diff --git a/debug/targets/RISC-V/spike-2-hwthread.cfg b/debug/targets/RISC-V/spike-2-hwthread.cfg new file mode 100644 index 0000000..df4a501 --- /dev/null +++ b/debug/targets/RISC-V/spike-2-hwthread.cfg @@ -0,0 +1,31 @@ +# Connect to a mult-icore RISC-V target, exposing each hart as a thread. +adapter_khz 10000 + +interface remote_bitbang +remote_bitbang_host $::env(REMOTE_BITBANG_HOST) +remote_bitbang_port $::env(REMOTE_BITBANG_PORT) + +set _CHIPNAME riscv +jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913 + +set _TARGETNAME_0 $_CHIPNAME.cpu0 +set _TARGETNAME_1 $_CHIPNAME.cpu1 +target create $_TARGETNAME_0 riscv -chain-position $_CHIPNAME.cpu -rtos hwthread +#target create $_TARGETNAME_0 riscv -chain-position $_CHIPNAME.cpu -coreid 0 -rtos hwthread +target create $_TARGETNAME_1 riscv -chain-position $_CHIPNAME.cpu -coreid 1 +target smp $_TARGETNAME_0 $_TARGETNAME_1 + +gdb_report_data_abort enable +gdb_report_register_access_error enable + +# Expose an unimplemented CSR so we can test non-existent register access +# behavior. +riscv expose_csrs 2288 +riscv expose_custom 1,12345-12348 + +init + +set challenge [ocd_riscv authdata_read] +riscv authdata_write [expr $challenge + 1] + +halt diff --git a/debug/targets/RISC-V/spike32-2-hwthread.py b/debug/targets/RISC-V/spike32-2-hwthread.py new file mode 100644 index 0000000..bec68dc --- /dev/null +++ b/debug/targets/RISC-V/spike32-2-hwthread.py @@ -0,0 +1,13 @@ +import targets +import testlib + +import spike32 # pylint: disable=import-error + +class spike32_2(targets.Target): + harts = [spike32.spike32_hart(), spike32.spike32_hart()] + openocd_config_path = "spike-2-hwthread.cfg" + timeout_sec = 5 + implements_custom_test = True + + def create(self): + return testlib.Spike(self) diff --git a/debug/targets/RISC-V/spike64-2-hwthread.py b/debug/targets/RISC-V/spike64-2-hwthread.py new file mode 100644 index 0000000..e57f490 --- /dev/null +++ b/debug/targets/RISC-V/spike64-2-hwthread.py @@ -0,0 +1,13 @@ +import targets +import testlib + +import spike64 # pylint: disable=import-error + +class spike64_2(targets.Target): + harts = [spike64.spike64_hart(), spike64.spike64_hart()] + openocd_config_path = "spike-2-hwthread.cfg" + timeout_sec = 5 + implements_custom_test = True + + def create(self): + return testlib.Spike(self) diff --git a/debug/testlib.py b/debug/testlib.py index a302cc6..9c620b2 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -310,12 +310,11 @@ class Openocd(object): try: self.process.terminate() start = time.time() - while time.time() < start + 10000: + while time.time() < start + 10: if self.process.poll(): break else: self.process.kill() - self.process.wait() except (OSError, AttributeError): pass @@ -402,7 +401,7 @@ class Gdb(object): # Force consistency. self.command("set print entry-values no") self.command("set remotetimeout %d" % self.timeout) - self.command("target extended-remote localhost:%d" % port) + self.command("target extended-remote localhost:%d" % port, ops=10) if self.binary: self.command("file %s" % self.binary) threads = self.threads() @@ -472,7 +471,7 @@ class Gdb(object): self.select_child(child) self.command(command) - def c(self, wait=True, async=False, checkOutput=True, ops=10): + def c(self, wait=True, async=False, checkOutput=True, ops=20): """ Dumb c command. In RTOS mode, gdb will resume all harts. @@ -514,9 +513,9 @@ class Gdb(object): for child in self.children: child.expect(r"\(gdb\)") - def interrupt(self): + def interrupt(self, ops=1): self.active_child.send("\003") - self.active_child.expect(r"\(gdb\)", timeout=6000) + self.active_child.expect(r"\(gdb\)", timeout=self.timeout * ops) return self.active_child.before.strip() def interrupt_all(self): @@ -546,8 +545,8 @@ class Gdb(object): else: return int(text, 0) - def p(self, obj, fmt="/x"): - output = self.command("p%s %s" % (fmt, obj)) + def p(self, obj, fmt="/x", ops=1): + output = self.command("p%s %s" % (fmt, obj), ops=ops) m = re.search("Cannot access memory at address (0x[0-9a-f]+)", output) if m: raise CannotAccess(int(m.group(1), 0)) @@ -563,7 +562,7 @@ class Gdb(object): return value def info_registers(self, group): - output = self.command("info registers %s" % group) + output = self.command("info registers %s" % group, ops=5) result = {} for line in output.splitlines(): parts = line.split() @@ -914,9 +913,9 @@ class GdbTest(BaseTest): self.gdb.interrupt() self.gdb.command("info breakpoints") self.gdb.command("disassemble", ops=20) - self.gdb.command("info registers all", ops=100) + self.gdb.command("info registers all", ops=20) self.gdb.command("flush regs") - self.gdb.command("info threads", ops=100) + self.gdb.command("info threads", ops=20) def classTeardown(self): del self.gdb |