aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2019-03-11 08:43:14 -0700
committerGitHub <noreply@github.com>2019-03-11 08:43:14 -0700
commit4f784ca9b8d3536c16061518c1c2b66e3118cc5c (patch)
tree6d801e89c8836a84ab41646267b8c7170c3326eb
parent26d821d126fd0e36bf286420452f5628c946e7cb (diff)
downloadriscv-tests-4f784ca9b8d3536c16061518c1c2b66e3118cc5c.zip
riscv-tests-4f784ca9b8d3536c16061518c1c2b66e3118cc5c.tar.gz
riscv-tests-4f784ca9b8d3536c16061518c1c2b66e3118cc5c.tar.bz2
Add SmpSimultaneousRunHalt test. (#181)
This test confirms that in SMP configurations OpenOCD halts the harts near-simulatenously. (It'll also check for resume, but that's not implemented yet so commented out for now.)
-rw-r--r--debug/Makefile3
-rwxr-xr-xdebug/gdbserver.py49
-rw-r--r--debug/programs/run_halt_timing.c17
-rw-r--r--debug/testlib.py30
4 files changed, 89 insertions, 10 deletions
diff --git a/debug/Makefile b/debug/Makefile
index 75900df..41d08f5 100644
--- a/debug/Makefile
+++ b/debug/Makefile
@@ -11,6 +11,9 @@ all-tests: spike32 spike32-2 spike32-2-rtos spike32-2-hwthread \
all: pylint all-tests
+# Target to check all the multicore options.
+multi-tests: spike32-2 spike64-2-rtos spike32-2-hwthread
+
pylint:
pylint --rcfile=pylint.rc `git ls-files '*.py'`
diff --git a/debug/gdbserver.py b/debug/gdbserver.py
index adcb6b2..e7f0701 100755
--- a/debug/gdbserver.py
+++ b/debug/gdbserver.py
@@ -842,6 +842,55 @@ class MulticoreRtosSwitchActiveHartTest(GdbTest):
assertIn("set_trap_handler", output)
assertNotIn("received signal SIGTRAP", output)
+class SmpSimultaneousRunHalt(GdbTest):
+ compile_args = ("programs/run_halt_timing.c", "-DMULTICORE")
+
+ def early_applicable(self):
+ return len(self.target.harts) > 1
+
+ def setup(self):
+ self.gdb.select_hart(self.target.harts[0])
+ self.gdb.load()
+ for hart in self.target.harts:
+ self.gdb.select_hart(hart)
+ self.gdb.p("$pc=_start")
+
+ def test(self):
+ if self.gdb.one_hart_per_gdb() or not self.server.smp():
+ return 'not_applicable'
+
+ old_mtime = set()
+ for _ in range(5):
+ self.gdb.c_all(wait=False)
+ time.sleep(2)
+ self.gdb.interrupt_all()
+
+ mtime_value = []
+ counter = []
+ for hart in self.target.harts:
+ self.gdb.select_hart(hart)
+ mv = self.gdb.p("mtime_value")
+ assertNotIn(mv, old_mtime,
+ "mtime doesn't appear to be changing at all")
+ mtime_value.append(mv)
+ c = self.gdb.p("counter")
+ assertNotEqual(c, 0,
+ "counter didn't increment; code didn't run?")
+ counter.append(c)
+ self.gdb.p("counter=0")
+
+ old_mtime.update(mtime_value)
+
+ mtime_spread = max(mtime_value) - min(mtime_value)
+ print "mtime_spread:", mtime_spread
+ counter_spread = max(counter) - min(counter)
+ print "counter_spread:", counter_spread
+
+ assertLess(mtime_spread, 100 * len(self.target.harts),
+ "Harts don't halt around the same time.")
+#TODO assertLess(counter_spread, 100 * len(self.target.harts),
+#TODO "Harts don't resume around the same time.")
+
class StepTest(GdbSingleHartTest):
compile_args = ("programs/step.S", )
diff --git a/debug/programs/run_halt_timing.c b/debug/programs/run_halt_timing.c
new file mode 100644
index 0000000..1c9a8ba
--- /dev/null
+++ b/debug/programs/run_halt_timing.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "init.h"
+
+int main()
+{
+ int counter = 0;
+ volatile uint64_t mtime_value;
+
+ while (1) {
+ counter = counter + 1;
+ mtime_value = MTIME;
+ }
+}
diff --git a/debug/testlib.py b/debug/testlib.py
index 9c620b2..c4b785c 100644
--- a/debug/testlib.py
+++ b/debug/testlib.py
@@ -245,12 +245,12 @@ class Openocd(object):
]
if config:
- f = find_file(config)
- if f is None:
+ self.config_file = find_file(config)
+ if self.config_file is None:
print "Unable to read file " + config
exit(1)
- cmd += ["-f", f]
+ cmd += ["-f", self.config_file]
if debug:
cmd.append("-d")
@@ -318,6 +318,14 @@ class Openocd(object):
except (OSError, AttributeError):
pass
+ def smp(self):
+ """Return true iff OpenOCD internally sees the harts as part of an SMP
+ group."""
+ for line in file(self.config_file, "r"):
+ if "target smp" in line:
+ return True
+ return False
+
class OpenocdCli(object):
def __init__(self, port=4444):
self.child = pexpect.spawn(
@@ -967,9 +975,11 @@ class ExamineTarget(GdbTest):
print txt,
class TestFailed(Exception):
- def __init__(self, message):
+ def __init__(self, message, comment=None):
Exception.__init__(self)
self.message = message
+ if comment:
+ self.message += ": %s" % comment
class TestNotApplicable(Exception):
def __init__(self, message):
@@ -980,25 +990,25 @@ def assertEqual(a, b):
if a != b:
raise TestFailed("%r != %r" % (a, b))
-def assertNotEqual(a, b):
+def assertNotEqual(a, b, comment=None):
if a == b:
- raise TestFailed("%r == %r" % (a, b))
+ raise TestFailed("%r == %r" % (a, b), comment)
def assertIn(a, b):
if a not in b:
raise TestFailed("%r not in %r" % (a, b))
-def assertNotIn(a, b):
+def assertNotIn(a, b, comment=None):
if a in b:
- raise TestFailed("%r in %r" % (a, b))
+ raise TestFailed("%r in %r" % (a, b), comment)
def assertGreater(a, b):
if not a > b:
raise TestFailed("%r not greater than %r" % (a, b))
-def assertLess(a, b):
+def assertLess(a, b, comment=None):
if not a < b:
- raise TestFailed("%r not less than %r" % (a, b))
+ raise TestFailed("%r not less than %r" % (a, b), comment)
def assertTrue(a):
if not a: