aboutsummaryrefslogtreecommitdiff
path: root/debug
diff options
context:
space:
mode:
authorMegan Wachs <megan@sifive.com>2016-08-08 11:41:25 -0700
committerMegan Wachs <megan@sifive.com>2016-08-08 11:41:25 -0700
commit99ea2bfc87739eb62a8eb1012e6b38d123feede5 (patch)
treeb2c343493fd99868696e5f2e3ba2e14997803261 /debug
parent0cf74a5e9aaf249fad226f129198663333f95c9d (diff)
parenteb60ed426347614dfbdcbe4dcd6ed5bae8b7968a (diff)
downloadriscv-tests-99ea2bfc87739eb62a8eb1012e6b38d123feede5.zip
riscv-tests-99ea2bfc87739eb62a8eb1012e6b38d123feede5.tar.gz
riscv-tests-99ea2bfc87739eb62a8eb1012e6b38d123feede5.tar.bz2
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'debug')
-rw-r--r--debug/README.md9
-rwxr-xr-xdebug/gdbserver.py76
-rw-r--r--debug/programs/priv.S11
-rw-r--r--debug/testlib.py6
4 files changed, 88 insertions, 14 deletions
diff --git a/debug/README.md b/debug/README.md
index 09662ba..4a90c0c 100644
--- a/debug/README.md
+++ b/debug/README.md
@@ -19,10 +19,10 @@ Targets
`./gdbserver.py --spike32 --cmd $RISCV/bin/spike`
-32-bit SiFive Core on Microsemi FPGA board
-------------------------------------------
+32-bit SiFive Core on Arty FPGA board
+-------------------------------------
-`./gdbserver.py --m2gl_m2s`
+`./gdbserver.py --freedom-e300`
Debug Tips
==========
@@ -36,3 +36,6 @@ to get an idea of what might have gone wrong.
You can see what spike is doing by add `-l` to the spike command, eg.:
`./gdbserver.py --spike32 --cmd "$RISCV/bin/spike -l"
DebugTest.test_breakpoint`. (Then look at spike.log.)
+
+You can run gdb under valgrind by passing --gdb, eg.: `./gdbserver.py --spike64
+--gdb "valgrind riscv64-unknown-elf-gdb" -- -v DownloadTest`.
diff --git a/debug/gdbserver.py b/debug/gdbserver.py
index a3f8153..f20630e 100755
--- a/debug/gdbserver.py
+++ b/debug/gdbserver.py
@@ -30,6 +30,12 @@ MSTATUS_VM = 0x1F000000
MSTATUS32_SD = 0x80000000
MSTATUS64_SD = 0x8000000000000000
+def gdb():
+ if parsed.gdb:
+ return testlib.Gdb(parsed.gdb)
+ else:
+ return testlib.Gdb()
+
def ihex_line(address, record_type, data):
assert len(data) < 128
line = ":%02X%04X%02X" % (len(data), address, record_type)
@@ -62,7 +68,7 @@ class DeleteServer(unittest.TestCase):
class SimpleRegisterTest(DeleteServer):
def setUp(self):
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
# For now gdb has to be told what the architecture is when it's not
# given an ELF file.
self.gdb.command("set arch riscv:rv%d" % target.xlen)
@@ -104,7 +110,7 @@ class SimpleRegisterTest(DeleteServer):
class SimpleMemoryTest(DeleteServer):
def setUp(self):
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
self.gdb.command("set arch riscv:rv%d" % target.xlen)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
@@ -161,7 +167,7 @@ class SimpleMemoryTest(DeleteServer):
class InstantHaltTest(DeleteServer):
def setUp(self):
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
self.gdb.command("set arch riscv:rv%d" % target.xlen)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
@@ -192,7 +198,7 @@ class DebugTest(DeleteServer):
self.binary = target.compile("programs/debug.c", "programs/checksum.c",
"programs/tiny-malloc.c", "-DDEFINE_MALLOC", "-DDEFINE_FREE")
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
self.gdb.command("file %s" % self.binary)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
self.gdb.load()
@@ -345,7 +351,7 @@ class StepTest(DeleteServer):
def setUp(self):
self.binary = target.compile("programs/step.S")
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
self.gdb.command("file %s" % self.binary)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
self.gdb.load()
@@ -363,7 +369,7 @@ class RegsTest(DeleteServer):
def setUp(self):
self.binary = target.compile("programs/regs.S")
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
self.gdb.command("file %s" % self.binary)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
self.gdb.load()
@@ -433,7 +439,7 @@ class DownloadTest(DeleteServer):
self.binary = target.compile(download_c.name, "programs/checksum.c")
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
self.gdb.command("file %s" % self.binary)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
@@ -447,7 +453,7 @@ class MprvTest(DeleteServer):
def setUp(self):
self.binary = target.compile("programs/mprv.S")
self.server = target.server()
- self.gdb = testlib.Gdb()
+ self.gdb = gdb()
self.gdb.command("file %s" % self.binary)
self.gdb.command("target extended-remote localhost:%d" % self.server.port)
self.gdb.load()
@@ -460,6 +466,58 @@ class MprvTest(DeleteServer):
output = self.gdb.command("p/x *(int*)(((char*)&data)-0x80000000)")
self.assertIn("0xbead", output)
+class PrivTest(DeleteServer):
+ def setUp(self):
+ self.binary = target.compile("programs/priv.S")
+ self.server = target.server()
+ self.gdb = gdb()
+ self.gdb.command("file %s" % self.binary)
+ self.gdb.command("target extended-remote localhost:%d" % self.server.port)
+ self.gdb.load()
+
+ misa = self.gdb.p("$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)
+
+ def test_rw(self):
+ """Test reading/writing priv."""
+ for privilege in range(4):
+ self.gdb.p("$priv=%d" % privilege)
+ self.gdb.stepi()
+ actual = self.gdb.p("$priv")
+ self.assertIn(actual, self.supported)
+ if privilege in self.supported:
+ self.assertEqual(actual, privilege)
+
+ def test_change(self):
+ """Test that the core's privilege level actually changes."""
+
+ if 0 not in self.supported:
+ # TODO: return not applicable
+ return
+
+ self.gdb.b("main")
+ self.gdb.c()
+
+ # Machine mode
+ self.gdb.p("$priv=3")
+ main = self.gdb.p("$pc")
+ self.gdb.stepi()
+ self.assertEqual("%x" % self.gdb.p("$pc"), "%x" % (main+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")
+ self.assertTrue(pc < main or pc > main + 0x100)
+
class Target(object):
directory = None
@@ -535,6 +593,8 @@ def main():
dest="target")
parser.add_argument("--cmd",
help="The command to use to start the debug server.")
+ parser.add_argument("--gdb",
+ help="The command to use to start gdb.")
parser.add_argument("--isolate", action="store_true",
help="Try to run in such a way that multiple instances can run at "
"the same time. This may make it harder to debug a failure if it "
diff --git a/debug/programs/priv.S b/debug/programs/priv.S
new file mode 100644
index 0000000..2d20a65
--- /dev/null
+++ b/debug/programs/priv.S
@@ -0,0 +1,11 @@
+#include "../../env/encoding.h"
+
+ .global main
+
+ .section .text
+main:
+ # MISA is only readable from machine mode
+ csrr t0, CSR_MISA
+ csrr t0, CSR_MISA
+ csrr t0, CSR_MISA
+ csrr t0, CSR_MISA
diff --git a/debug/testlib.py b/debug/testlib.py
index 5e7f366..b3f8f66 100644
--- a/debug/testlib.py
+++ b/debug/testlib.py
@@ -102,10 +102,10 @@ class Openocd(object):
class Gdb(object):
def __init__(self,
- path=os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gdb")):
- self.child = pexpect.spawn(path)
+ cmd=os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gdb")):
+ self.child = pexpect.spawn(cmd)
self.child.logfile = file("gdb.log", "w")
- self.child.logfile.write("+ %s\n" % path)
+ self.child.logfile.write("+ %s\n" % cmd)
self.wait()
self.command("set confirm off")
self.command("set width 0")