aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2016-05-07 11:15:59 -0700
committerTim Newsome <tim@sifive.com>2016-05-23 12:12:12 -0700
commitc7643c32e07e4b5d82bdb98b91998f9c12f24434 (patch)
tree784016e2d90f084eb44e28bea4576d5f6499e326 /tests
parent45fb0a0f0ecccf6fe84e54557655ddd7e7560aaf (diff)
downloadspike-c7643c32e07e4b5d82bdb98b91998f9c12f24434.zip
spike-c7643c32e07e4b5d82bdb98b91998f9c12f24434.tar.gz
spike-c7643c32e07e4b5d82bdb98b91998f9c12f24434.tar.bz2
mprv test now breaks like it's supposed to.
Diffstat (limited to 'tests')
-rwxr-xr-xtests/gdbserver.py52
-rw-r--r--tests/mprv.S38
-rw-r--r--tests/standalone.lds90
-rw-r--r--tests/testlib.py20
4 files changed, 178 insertions, 22 deletions
diff --git a/tests/gdbserver.py b/tests/gdbserver.py
index 0f9ee1d..6ca9af6 100755
--- a/tests/gdbserver.py
+++ b/tests/gdbserver.py
@@ -25,6 +25,18 @@ class InstantHaltTest(unittest.TestCase):
self.gdb.command("stepi")
self.assertNotEqual(0x1000, self.gdb.p("$pc"))
+ def test_change_pc(self):
+ """Change the PC right as we come out of reset."""
+ # 0x13 is nop
+ self.gdb.command("p *((int*) 0x80000000)=0x13")
+ self.gdb.command("p *((int*) 0x80000004)=0x13")
+ self.gdb.command("p *((int*) 0x80000008)=0x13")
+ self.gdb.command("p $pc=0x80000000")
+ self.gdb.command("stepi")
+ self.assertEqual(0x80000004, self.gdb.p("$pc"))
+ self.gdb.command("stepi")
+ self.assertEqual(0x80000008, self.gdb.p("$pc"))
+
class DebugTest(unittest.TestCase):
def setUp(self):
self.binary = testlib.compile("debug.c")
@@ -156,22 +168,30 @@ class RegsTest(unittest.TestCase):
self.assertEqual(9, self.gdb.p("$x1"))
self.assertEqual(9, self.gdb.p("$csr1"))
-#class MprvTest(unittest.TestCase):
-# def setUp(self):
-# self.binary = testlib.compile("mprv.S")
-# self.spike, self.port = testlib.spike(self.binary, halted=False)
-# self.gdb = testlib.Gdb()
-# self.gdb.command("file %s" % self.binary)
-# self.gdb.command("target extended-remote localhost:%d" % self.port)
-#
-# def tearDown(self):
-# self.spike.kill()
-# self.spike.wait()
-#
-# def test_mprv(self):
-# """Test that the debugger can access memory when MPRV is set."""
-# output = self.gdb.command("p/x data");
-# self.assertIn("0xbead", output)
+class MprvTest(unittest.TestCase):
+ def setUp(self):
+ self.binary = testlib.compile("mprv.S", "-T", "standalone.lds",
+ "-nostartfiles")
+ self.spike, self.port = testlib.spike(None, halted=True)
+ self.gdb = testlib.Gdb()
+ self.gdb.command("file %s" % self.binary)
+ self.gdb.command("target extended-remote localhost:%d" % self.port)
+ self.gdb.command("load")
+
+ def tearDown(self):
+ self.spike.kill()
+ self.spike.wait()
+
+ def test_mprv(self):
+ """Test that the debugger can access memory when MPRV is set."""
+ self.gdb.c(wait=False)
+ self.gdb.interrupt()
+ output = self.gdb.command("p/x *(int*)(((char*)&data)-0x80000000)")
+ self.assertIn("0xbead", output)
if __name__ == '__main__':
+ # TROUBLESHOOTING TIPS
+ # If a particular test fails, run just that one test, eg.:
+ # ./tests/gdbserver.py MprvTest.test_mprv
+ # Then inspect gdb.log and spike.log to see what happened in more detail.
unittest.main()
diff --git a/tests/mprv.S b/tests/mprv.S
new file mode 100644
index 0000000..114918a
--- /dev/null
+++ b/tests/mprv.S
@@ -0,0 +1,38 @@
+#include "../riscv/encoding.h"
+#define PGSHIFT 12
+
+ .global main
+
+ .section .text
+main:
+ # Set up a page table entry that maps 0x0... to 0x8...
+ la t0, page_table
+ srli t0, t0, PGSHIFT
+ csrw CSR_SPTBR, t0
+
+ # update mstatus
+ csrr t1, CSR_MSTATUS
+ li t0, (MSTATUS_MPRV | (VM_SV39 << 24))
+ #li t0, ((VM_SV39 << 24))
+ or t1, t0, t1
+ csrw CSR_MSTATUS, t1
+
+ la t0, (loop - 0x80000000)
+ csrw CSR_MEPC, t0
+
+ # Exit supervisor mode, entering user mode at loop.
+ mret
+
+loop:
+ la t0, data
+ lw t1, 0(t0)
+ j loop
+
+ .section .data
+data:
+ .word 0xbead
+
+ .balign 0x1000
+page_table:
+ .word ((0x80000000 >> 2) | PTE_V | PTE_TYPE_URWX_SRWX)
+ .word 0
diff --git a/tests/standalone.lds b/tests/standalone.lds
new file mode 100644
index 0000000..6705cfd
--- /dev/null
+++ b/tests/standalone.lds
@@ -0,0 +1,90 @@
+OUTPUT_ARCH( "riscv" )
+
+ENTRY( main )
+
+SECTIONS
+{
+
+ /*--------------------------------------------------------------------*/
+ /* Code and read-only segment */
+ /*--------------------------------------------------------------------*/
+
+ /* Begining of code and text segment */
+ . = 0x80000000;
+ _ftext = .;
+ PROVIDE( eprol = . );
+
+ .text :
+ {
+ *(.text.init)
+ }
+
+ /* text: Program code section */
+ .text :
+ {
+ *(.text)
+ *(.text.*)
+ *(.gnu.linkonce.t.*)
+ }
+
+ /* rodata: Read-only data */
+ .rodata :
+ {
+ *(.rdata)
+ *(.rodata)
+ *(.rodata.*)
+ *(.gnu.linkonce.r.*)
+ }
+
+ /* End of code and read-only segment */
+ PROVIDE( etext = . );
+ _etext = .;
+
+ /*--------------------------------------------------------------------*/
+ /* Initialized data segment */
+ /*--------------------------------------------------------------------*/
+
+ /* Start of initialized data segment */
+ . = ALIGN(16);
+ _fdata = .;
+
+ /* data: Writable data */
+ .data :
+ {
+ *(.data)
+ *(.data.*)
+ *(.srodata*)
+ *(.gnu.linkonce.d.*)
+ *(.comment)
+ }
+
+ /* End of initialized data segment */
+ . = ALIGN(4);
+ PROVIDE( edata = . );
+ _edata = .;
+
+ /*--------------------------------------------------------------------*/
+ /* Uninitialized data segment */
+ /*--------------------------------------------------------------------*/
+
+ /* Start of uninitialized data segment */
+ . = .;
+ _fbss = .;
+
+ /* sbss: Uninitialized writeable small data section */
+ . = .;
+
+ /* bss: Uninitialized writeable data section */
+ . = .;
+ _bss_start = .;
+ .bss :
+ {
+ *(.bss)
+ *(.bss.*)
+ *(.sbss*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ }
+
+ _end = .;
+}
diff --git a/tests/testlib.py b/tests/testlib.py
index 6233901..3b439b1 100644
--- a/tests/testlib.py
+++ b/tests/testlib.py
@@ -13,14 +13,20 @@ def find_file(path):
fullpath = os.path.join(directory, path)
if os.path.exists(fullpath):
return fullpath
- raise ValueError("Couldn't find %r." % path)
+ return None
-def compile(src):
+def compile(*args):
"""Compile a single .c file into a binary."""
- src = find_file(src)
- dst = os.path.splitext(src)[0]
+ dst = os.path.splitext(args[0])[0]
cc = os.path.expandvars("$RISCV/bin/riscv64-unknown-elf-gcc")
- cmd = "%s -g -o %s %s" % (cc, dst, src)
+ cmd = [cc, "-g", "-O", "-o", dst]
+ for arg in args:
+ found = find_file(arg)
+ if found:
+ cmd.append(found)
+ else:
+ cmd.append(arg)
+ cmd = " ".join(cmd)
result = os.system(cmd)
assert result == 0, "%r failed" % cmd
return dst
@@ -46,7 +52,9 @@ def spike(binary, halted=False, with_gdb=True, timeout=None):
if with_gdb:
port = unused_port()
cmd += ['--gdb-port', str(port)]
- cmd += ['pk', binary]
+ cmd.append('pk')
+ if binary:
+ cmd.append(binary)
logfile = open("spike.log", "w")
process = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=logfile,
stderr=logfile)