diff options
-rwxr-xr-x | debug/gdbserver.py | 91 | ||||
-rw-r--r-- | debug/programs/debug.c | 2 | ||||
-rw-r--r-- | debug/targets.py | 4 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike32-2-hwthread.py | 1 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike32-2-rtos.py | 1 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike32.py | 1 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike64-2-hwthread.py | 1 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike64-2-rtos.py | 1 | ||||
-rw-r--r-- | debug/targets/RISC-V/spike64-2.py | 1 | ||||
-rw-r--r-- | debug/testlib.py | 2 |
10 files changed, 104 insertions, 1 deletions
diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 5a0c378..3ccaf2f 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -8,6 +8,7 @@ import sys import tempfile import time import os +import re import targets import testlib @@ -764,6 +765,96 @@ class UserInterrupt(DebugTest): self.gdb.p("i=0") self.exit() +class MemorySampleTest(DebugTest): + def early_applicable(self): + return self.target.support_memory_sampling + + def setup(self): + DebugTest.setup(self) + self.gdb.b("main:start") + self.gdb.c() + self.gdb.p("i=123") + + @staticmethod + def check_incrementing_samples(raw_samples, check_addr, tolerance=0x100000): + first_timestamp = None + end = None + total_samples = 0 + previous_value = None + for line in raw_samples.splitlines(): + m = re.match(r"^timestamp \w+: (\d+)", line) + if m: + timestamp = int(m.group(1)) + if not first_timestamp: + first_timestamp = timestamp + else: + end = (timestamp, total_samples) + else: + address, value = line.split(': ') + address = int(address, 16) + if address == check_addr: + value = int(value, 16) + if not previous_value is None: + # TODO: what if the counter wraps? + assertGreater(value, previous_value) + assertLess(value, previous_value + tolerance) + previous_value = value + total_samples += 1 + if end and total_samples > 0: + print("%d samples/second" % (1000 * end[1] / (end[0] - + first_timestamp))) + else: + raise Exception("No samples collected.") + + @staticmethod + def check_samples_equal(raw_samples, check_addr, check_value): + total_samples = 0 + for line in raw_samples.splitlines(): + if not line.startswith("timestamp "): + address, value = line.split(': ') + address = int(address, 16) + if address == check_addr: + value = int(value, 16) + assertEqual(value, check_value) + total_samples += 1 + assertGreater(total_samples, 0) + + def collect_samples(self): + self.gdb.c(wait=False) + time.sleep(5) + output = self.gdb.interrupt() + assert "main" in output + return self.gdb.command("monitor riscv dump_sample_buf", ops=5) + +class MemorySampleSingle(MemorySampleTest): + def test(self): + addr = self.gdb.p("&j") + sizeof_j = self.gdb.p("sizeof(j)") + self.gdb.command("monitor riscv memory_sample 0 0x%x %d" % ( + addr, sizeof_j)) + + raw_samples = self.collect_samples() + self.check_incrementing_samples(raw_samples, addr) + + # Buffer should have been emptied by dumping. + raw_samples = self.gdb.command("monitor riscv dump_sample_buf", ops=5) + assertEqual(len(raw_samples), 0) + +class MemorySampleMixed(MemorySampleTest): + def test(self): + addr = {} + for i, name in enumerate(("j", "i32", "i64")): + addr[name] = self.gdb.p("&%s" % name) + sizeof = self.gdb.p("sizeof(%s)" % name) + self.gdb.command("monitor riscv memory_sample %d 0x%x %d" % ( + i, addr[name], sizeof)) + + raw_samples = self.collect_samples() + self.check_incrementing_samples(raw_samples, addr["j"], + tolerance=0x200000) + self.check_samples_equal(raw_samples, addr["i32"], 0xdeadbeef) + self.check_samples_equal(raw_samples, addr["i64"], 0x1122334455667788) + class RepeatReadTest(DebugTest): def early_applicable(self): return self.target.supports_clint_mtime diff --git a/debug/programs/debug.c b/debug/programs/debug.c index 8a4aa73..641aa4e 100644 --- a/debug/programs/debug.c +++ b/debug/programs/debug.c @@ -55,6 +55,8 @@ int main() int j = 0; char fox[] = "The quick brown fox jumps of the lazy dog."; unsigned int checksum = 0; + volatile uint32_t i32 = 0xdeadbeef; + volatile uint64_t i64 = 0x1122334455667788; start: while (i) diff --git a/debug/targets.py b/debug/targets.py index 8b64e14..be5c9fa 100644 --- a/debug/targets.py +++ b/debug/targets.py @@ -99,6 +99,10 @@ class Target: # isn't supposed to work. support_manual_hwbp = True + # Set False if memory sampling is not supported due to OpenOCD + # limitation/hardware support. + support_memory_sampling = True + # Internal variables: directory = None temporary_files = [] diff --git a/debug/targets/RISC-V/spike32-2-hwthread.py b/debug/targets/RISC-V/spike32-2-hwthread.py index 2ad2998..e84391a 100644 --- a/debug/targets/RISC-V/spike32-2-hwthread.py +++ b/debug/targets/RISC-V/spike32-2-hwthread.py @@ -9,6 +9,7 @@ class spike32_2(targets.Target): openocd_config_path = "spike-2-hwthread.cfg" timeout_sec = 5 implements_custom_test = True + support_memory_sampling = False # not supported without sba def create(self): return testlib.Spike(self, isa="RV32IMAV", support_hasel=True, diff --git a/debug/targets/RISC-V/spike32-2-rtos.py b/debug/targets/RISC-V/spike32-2-rtos.py index ce0d56d..81029e8 100644 --- a/debug/targets/RISC-V/spike32-2-rtos.py +++ b/debug/targets/RISC-V/spike32-2-rtos.py @@ -12,6 +12,7 @@ class spike32_2(targets.Target): support_hasel = False test_semihosting = False support_manual_hwbp = False # not supported with `-rtos riscv` + support_memory_sampling = False # not supported with `-rtos riscv` def create(self): return testlib.Spike(self, progbufsize=0, dmi_rti=4, diff --git a/debug/targets/RISC-V/spike32.py b/debug/targets/RISC-V/spike32.py index b261f6c..913dccf 100644 --- a/debug/targets/RISC-V/spike32.py +++ b/debug/targets/RISC-V/spike32.py @@ -17,6 +17,7 @@ class spike32(targets.Target): openocd_config_path = "spike-1.cfg" timeout_sec = 30 implements_custom_test = True + support_memory_sampling = False # Needs SBA def create(self): # 64-bit FPRs on 32-bit target diff --git a/debug/targets/RISC-V/spike64-2-hwthread.py b/debug/targets/RISC-V/spike64-2-hwthread.py index 5d8d6e6..ee1a46b 100644 --- a/debug/targets/RISC-V/spike64-2-hwthread.py +++ b/debug/targets/RISC-V/spike64-2-hwthread.py @@ -9,6 +9,7 @@ class spike64_2(targets.Target): openocd_config_path = "spike-2-hwthread.cfg" timeout_sec = 5 implements_custom_test = True + support_memory_sampling = False # Needs SBA def create(self): return testlib.Spike(self) diff --git a/debug/targets/RISC-V/spike64-2-rtos.py b/debug/targets/RISC-V/spike64-2-rtos.py index 2062f6d..acb217f 100644 --- a/debug/targets/RISC-V/spike64-2-rtos.py +++ b/debug/targets/RISC-V/spike64-2-rtos.py @@ -12,6 +12,7 @@ class spike64_2_rtos(targets.Target): support_hasel = False test_semihosting = False support_manual_hwbp = False # not supported with `-rtos riscv` + support_memory_sampling = False # not supported with `-rtos riscv` def create(self): return testlib.Spike(self, abstract_rti=30, support_hasel=False, diff --git a/debug/targets/RISC-V/spike64-2.py b/debug/targets/RISC-V/spike64-2.py index 5dc0e7b..ceb2227 100644 --- a/debug/targets/RISC-V/spike64-2.py +++ b/debug/targets/RISC-V/spike64-2.py @@ -12,6 +12,7 @@ class spike64_2(targets.Target): timeout_sec = 20 implements_custom_test = True support_hasel = False + support_memory_sampling = False # Needs SBA def create(self): # TODO: It would be nice to test with slen=128, but spike currently diff --git a/debug/testlib.py b/debug/testlib.py index 1b90caa..d8fc891 100644 --- a/debug/testlib.py +++ b/debug/testlib.py @@ -138,7 +138,7 @@ class Spike: if not self.progbufsize is None: cmd += ["--dm-progsize", str(self.progbufsize)] - cmd += ["--dm-sba", "32"] + cmd += ["--dm-sba", "64"] if not self.dmi_rti is None: cmd += ["--dmi-rti", str(self.dmi_rti)] |