From 4dddbc79ada7f0a836cf538676c57c8df103ccf6 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Mon, 27 Aug 2018 13:17:51 -0700 Subject: [PATCH] Add test case for `riscv expose_custom`. Only works against spike, where I've implemented some custom debug registers to test against. --- debug/gdbserver.py | 30 ++++++++++++++++++++++++++ debug/targets.py | 4 ++++ debug/targets/RISC-V/spike-1.cfg | 1 + debug/targets/RISC-V/spike-2.cfg | 1 + debug/targets/RISC-V/spike-rtos.cfg | 1 + debug/targets/RISC-V/spike32-2-rtos.py | 1 + debug/targets/RISC-V/spike32-2.py | 1 + debug/targets/RISC-V/spike32.py | 1 + debug/targets/RISC-V/spike64-2-rtos.py | 1 + debug/targets/RISC-V/spike64-2.py | 1 + debug/targets/RISC-V/spike64.py | 1 + debug/testlib.py | 12 +++++++++++ 12 files changed, 55 insertions(+) diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 8761cf6..c362e1d 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -137,6 +137,36 @@ class SimpleF18Test(SimpleRegisterTest): 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: diff --git a/debug/targets.py b/debug/targets.py index 2cdbb33..63994db 100644 --- a/debug/targets.py +++ b/debug/targets.py @@ -75,6 +75,10 @@ class Target(object): # Supports mtime at 0x2004000 supports_clint_mtime = True + # Implements custom debug registers like spike does. It seems unlikely any + # hardware will every do that. + implements_custom_test = False + # Internal variables: directory = None temporary_files = [] diff --git a/debug/targets/RISC-V/spike-1.cfg b/debug/targets/RISC-V/spike-1.cfg index 083794f..6f7da74 100644 --- a/debug/targets/RISC-V/spike-1.cfg +++ b/debug/targets/RISC-V/spike-1.cfg @@ -16,6 +16,7 @@ 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 diff --git a/debug/targets/RISC-V/spike-2.cfg b/debug/targets/RISC-V/spike-2.cfg index ef8bab1..9dbbfe3 100644 --- a/debug/targets/RISC-V/spike-2.cfg +++ b/debug/targets/RISC-V/spike-2.cfg @@ -19,6 +19,7 @@ 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 diff --git a/debug/targets/RISC-V/spike-rtos.cfg b/debug/targets/RISC-V/spike-rtos.cfg index d8bd27e..e26ca8a 100644 --- a/debug/targets/RISC-V/spike-rtos.cfg +++ b/debug/targets/RISC-V/spike-rtos.cfg @@ -17,6 +17,7 @@ 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 diff --git a/debug/targets/RISC-V/spike32-2-rtos.py b/debug/targets/RISC-V/spike32-2-rtos.py index 79105d5..c45013f 100644 --- a/debug/targets/RISC-V/spike32-2-rtos.py +++ b/debug/targets/RISC-V/spike32-2-rtos.py @@ -7,6 +7,7 @@ class spike32_2(targets.Target): harts = [spike32.spike32_hart(), spike32.spike32_hart()] openocd_config_path = "spike-rtos.cfg" timeout_sec = 30 + implements_custom_test = True def create(self): return testlib.Spike(self, progbufsize=0) diff --git a/debug/targets/RISC-V/spike32-2.py b/debug/targets/RISC-V/spike32-2.py index 89d3c2a..6c90b7c 100644 --- a/debug/targets/RISC-V/spike32-2.py +++ b/debug/targets/RISC-V/spike32-2.py @@ -7,6 +7,7 @@ class spike32_2(targets.Target): harts = [spike32.spike32_hart(), spike32.spike32_hart()] openocd_config_path = "spike-2.cfg" timeout_sec = 30 + implements_custom_test = True def create(self): return testlib.Spike(self, isa="RV32IMAFC", progbufsize=0) diff --git a/debug/targets/RISC-V/spike32.py b/debug/targets/RISC-V/spike32.py index dfcfc01..a831ecb 100644 --- a/debug/targets/RISC-V/spike32.py +++ b/debug/targets/RISC-V/spike32.py @@ -13,6 +13,7 @@ class spike32(targets.Target): harts = [spike32_hart()] openocd_config_path = "spike-1.cfg" timeout_sec = 30 + implements_custom_test = True def create(self): # 64-bit FPRs on 32-bit target diff --git a/debug/targets/RISC-V/spike64-2-rtos.py b/debug/targets/RISC-V/spike64-2-rtos.py index 7e3fc7e..9cb3a44 100644 --- a/debug/targets/RISC-V/spike64-2-rtos.py +++ b/debug/targets/RISC-V/spike64-2-rtos.py @@ -7,6 +7,7 @@ class spike64_2_rtos(targets.Target): harts = [spike64.spike64_hart(), spike64.spike64_hart()] openocd_config_path = "spike-rtos.cfg" timeout_sec = 60 + implements_custom_test = True def create(self): return testlib.Spike(self) diff --git a/debug/targets/RISC-V/spike64-2.py b/debug/targets/RISC-V/spike64-2.py index a2082b4..23ae06b 100644 --- a/debug/targets/RISC-V/spike64-2.py +++ b/debug/targets/RISC-V/spike64-2.py @@ -7,6 +7,7 @@ class spike64_2(targets.Target): harts = [spike64.spike64_hart(), spike64.spike64_hart()] openocd_config_path = "spike-2.cfg" timeout_sec = 60 + implements_custom_test = True def create(self): return testlib.Spike(self, isa="RV64IMAFD") diff --git a/debug/targets/RISC-V/spike64.py b/debug/targets/RISC-V/spike64.py index d5802b5..d0eaf5c 100644 --- a/debug/targets/RISC-V/spike64.py +++ b/debug/targets/RISC-V/spike64.py @@ -13,6 +13,7 @@ class spike64(targets.Target): harts = [spike64_hart()] openocd_config_path = "spike-1.cfg" timeout_sec = 30 + implements_custom_test = True def create(self): # 32-bit FPRs only diff --git a/debug/testlib.py b/debug/testlib.py index 1d46b6c..6adc43a 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -552,6 +552,18 @@ class Gdb(object): value = shlex.split(output.split('=')[-1].strip())[1] return value + def info_registers(self, group): + output = self.command("info registers %s" % group) + result = {} + for line in output.splitlines(): + if "Could not fetch" in line: + name, value = line.split(None, 1) + else: + name, hex_value, _ = line.split(None, 2) + value = int(hex_value, 0) + result[name] = value + return result + def stepi(self): output = self.command("stepi", ops=10) return output -- 2.30.2