Merge remote-tracking branch 'origin/master'
authorMegan Wachs <megan@sifive.com>
Mon, 8 Aug 2016 18:41:25 +0000 (11:41 -0700)
committerMegan Wachs <megan@sifive.com>
Mon, 8 Aug 2016 18:41:25 +0000 (11:41 -0700)
15 files changed:
Makefile.in
debug/README.md
debug/gdbserver.py
debug/programs/priv.S [new file with mode: 0644]
debug/testlib.py
isa/Makefile
isa/macros/scalar/test_macros.h
isa/rv32mi/Makefrag
isa/rv32mi/breakpoint.S [new file with mode: 0644]
isa/rv32uc/Makefrag [new file with mode: 0644]
isa/rv32uc/rvc.S [new file with mode: 0644]
isa/rv64mi/breakpoint.S
isa/rv64mi/ma_addr.S
isa/rv64uc/Makefrag [new file with mode: 0644]
isa/rv64uc/rvc.S [new file with mode: 0644]

index 86c2d01c8a6844a8f32f073375ba00d8baf26f08..d2b088e85efe53a5d66abb62e7b6663b84c21f64 100644 (file)
@@ -6,7 +6,7 @@ bmarkdir        := $(abs_top_src_dir)/benchmarks
 isa_src_dir     := $(abs_top_src_dir)/isa
 debug_src_dir   := $(abs_top_src_dir)/debug
 
-all: benchmarks isa
+all: benchmarks isa debug
 
 install: all
        install -d $(instbasedir)/share/riscv-tests/isa
index 09662ba0be57809193b3bc675b8a791ef587fcf5..4a90c0c770aad9157da31f720ef60d689d141639 100644 (file)
@@ -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`.
index a3f8153b68a740f1a1a5e82b0852a40a696f202a..f20630e65e7d591e9dd6a9b4226825454224911f 100755 (executable)
@@ -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 (file)
index 0000000..2d20a65
--- /dev/null
@@ -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
index 5e7f36690f5d57e1779949b1d2ff8f3bdeb3fac6..b3f8f66a822f8529973fa5a46b89f4beba2da52c 100644 (file)
@@ -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")
index 95092e81049ec21a5e76ed468a9d3c4b963394f0..f4dab3fdd23760d38f2f1bb40d38190e13d8a630 100644 (file)
@@ -7,6 +7,7 @@ XLEN ?= 64
 src_dir := .
 
 include $(src_dir)/rv64ui/Makefrag
+include $(src_dir)/rv64uc/Makefrag
 include $(src_dir)/rv64um/Makefrag
 include $(src_dir)/rv64ua/Makefrag
 include $(src_dir)/rv64uf/Makefrag
@@ -14,6 +15,7 @@ include $(src_dir)/rv64ud/Makefrag
 include $(src_dir)/rv64si/Makefrag
 include $(src_dir)/rv64mi/Makefrag
 include $(src_dir)/rv32ui/Makefrag
+include $(src_dir)/rv32uc/Makefrag
 include $(src_dir)/rv32um/Makefrag
 include $(src_dir)/rv32ua/Makefrag
 include $(src_dir)/rv32si/Makefrag
@@ -67,12 +69,14 @@ tests += $$($(1)_tests)
 endef
 
 $(eval $(call compile_template,rv32ui,-m32))
+$(eval $(call compile_template,rv32uc,-m32))
 $(eval $(call compile_template,rv32um,-m32))
 $(eval $(call compile_template,rv32ua,-m32))
 $(eval $(call compile_template,rv32si,-m32))
 $(eval $(call compile_template,rv32mi,-m32))
 ifeq ($(XLEN),64)
 $(eval $(call compile_template,rv64ui))
+$(eval $(call compile_template,rv64uc))
 $(eval $(call compile_template,rv64um))
 $(eval $(call compile_template,rv64ua))
 $(eval $(call compile_template,rv64uf))
index 4b1e1f58aa479f0cb9f64d8ca8255bdd22ffba0a..721b80b2d79593c93b6189331570c0f19bfdcf15 100644 (file)
@@ -314,42 +314,6 @@ test_ ## testnum: \
     li  x5, 2; \
     bne x4, x5, 1b \
 
-#-----------------------------------------------------------------------
-# Test branch instructions
-#-----------------------------------------------------------------------
-
-#define TEST_BR1_OP_TAKEN( testnum, inst, val1 ) \
-test_ ## testnum: \
-    li  TESTNUM, testnum; \
-    li  x1, val1; \
-    inst x1, 2f; \
-    bne x0, TESTNUM, fail; \
-1:  bne x0, TESTNUM, 3f; \
-2:  inst x1, 1b; \
-    bne x0, TESTNUM, fail; \
-3:
-
-#define TEST_BR1_OP_NOTTAKEN( testnum, inst, val1 ) \
-test_ ## testnum: \
-    li  TESTNUM, testnum; \
-    li  x1, val1; \
-    inst x1, 1f; \
-    bne x0, TESTNUM, 2f; \
-1:  bne x0, TESTNUM, fail; \
-2:  inst x1, 1b; \
-3:
-
-#define TEST_BR1_SRC1_BYPASS( testnum, nop_cycles, inst, val1 ) \
-test_ ## testnum: \
-    li  TESTNUM, testnum; \
-    li  x4, 0; \
-1:  li  x1, val1; \
-    TEST_INSERT_NOPS_ ## nop_cycles \
-    inst x1, fail; \
-    addi  x4, x4, 1; \
-    li  x5, 2; \
-    bne x4, x5, 1b \
-
 #define TEST_BR2_OP_TAKEN( testnum, inst, val1, val2 ) \
 test_ ## testnum: \
     li  TESTNUM, testnum; \
index 636e0972fb62cb2565fb88018c61bb6e1fa3712f..a72624478fb93d2fb5c6108eb3334db0a2cc3d7f 100644 (file)
@@ -3,11 +3,12 @@
 #-----------------------------------------------------------------------
 
 rv32mi_sc_tests = \
+       breakpoint \
        csr \
+       mcsr \
        illegal \
        ma_fetch \
        ma_addr \
-       mcsr \
        scall \
        sbreak \
        shamt \
diff --git a/isa/rv32mi/breakpoint.S b/isa/rv32mi/breakpoint.S
new file mode 100644 (file)
index 0000000..ecbec6a
--- /dev/null
@@ -0,0 +1,8 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64M
+#define RVTEST_RV64M RVTEST_RV32M
+#define __MACHINE_MODE
+
+#include "../rv64mi/breakpoint.S"
diff --git a/isa/rv32uc/Makefrag b/isa/rv32uc/Makefrag
new file mode 100644 (file)
index 0000000..0586843
--- /dev/null
@@ -0,0 +1,11 @@
+#=======================================================================
+# Makefrag for rv32uc tests
+#-----------------------------------------------------------------------
+
+rv32uc_sc_tests = \
+       rvc \
+
+rv32uc_p_tests = $(addprefix rv32uc-p-, $(rv32uc_sc_tests))
+rv32uc_v_tests = $(addprefix rv32uc-v-, $(rv32uc_sc_tests))
+
+spike32_tests += $(rv32uc_p_tests) $(rv32uc_v_tests)
diff --git a/isa/rv32uc/rvc.S b/isa/rv32uc/rvc.S
new file mode 100644 (file)
index 0000000..debbbd8
--- /dev/null
@@ -0,0 +1,7 @@
+# See LICENSE for license details.
+
+#include "riscv_test.h"
+#undef RVTEST_RV64U
+#define RVTEST_RV64U RVTEST_RV32U
+
+#include "../rv64uc/rvc.S"
index 77c9509c4e5f0d8ceb95c683271b5054dde27905..b975331d58ff6e6ccb3c99ed42d3c4b3d534e5f0 100644 (file)
@@ -36,9 +36,10 @@ RVTEST_CODE_BEGIN
   csrr a1, tdrdata1
   andi a1, a1, 0x7ff
   bne a0, a1, 2f
+  .align 2
 1:
   # Trap handler should skip this instruction.
-  j fail
+  beqz x0, fail
 
   # Make sure reads don't trap.
   li TESTNUM, 3
index c84242a99c4d9d817305f50bde104375e59d154e..6e7be9480b47e8d530e6615d7ba06cf8ac55b802 100644 (file)
@@ -13,9 +13,9 @@
 RVTEST_RV64M
 RVTEST_CODE_BEGIN
 
-  .align 3
   .option norvc
-  auipc s0, 0
+
+  la s0, data
 
   # indicate it's a load test
   li s1, CAUSE_MISALIGNED_LOAD
@@ -80,6 +80,9 @@ RVTEST_CODE_END
   .data
 RVTEST_DATA_BEGIN
 
+data:
+  .dword 0
+
   TEST_DATA
 
 RVTEST_DATA_END
diff --git a/isa/rv64uc/Makefrag b/isa/rv64uc/Makefrag
new file mode 100644 (file)
index 0000000..f5e49b7
--- /dev/null
@@ -0,0 +1,11 @@
+#=======================================================================
+# Makefrag for rv64uc tests
+#-----------------------------------------------------------------------
+
+rv64uc_sc_tests = \
+       rvc \
+
+rv64uc_p_tests = $(addprefix rv64uc-p-, $(rv64uc_sc_tests))
+rv64uc_v_tests = $(addprefix rv64uc-v-, $(rv64uc_sc_tests))
+
+spike_tests += $(rv64uc_p_tests) $(rv64uc_v_tests)
diff --git a/isa/rv64uc/rvc.S b/isa/rv64uc/rvc.S
new file mode 100644 (file)
index 0000000..6e3cf33
--- /dev/null
@@ -0,0 +1,154 @@
+# See LICENSE for license details.
+
+#*****************************************************************************
+# rvc.S
+#-----------------------------------------------------------------------------
+#
+# Test RVC corner cases.
+#
+
+#include "riscv_test.h"
+#include "test_macros.h"
+
+RVTEST_RV64U
+RVTEST_CODE_BEGIN
+
+  .option push
+  .option norvc
+
+  #define RVC_TEST_CASE(n, r, v, code...) \
+    TEST_CASE (n, r, v, .option push; .option rvc; code; .option pop)
+
+  // Make sure fetching a 4-byte instruction across a page boundary works.
+  li TESTNUM, 2
+  li a1, 666
+  li a2, 1
+  RVC_TEST_CASE (2, a1, 2, \
+        j 1f; \
+        .align 12; \
+        .skip 4094; \
+      1: addi a1, a2, 1)
+
+  li sp, 0x1234
+  RVC_TEST_CASE (3, a0, 0x1234 + 1020, c.addi4spn a0, sp, 1020)
+  RVC_TEST_CASE (4, sp, 0x1234 + 496, c.addi16sp sp, 496)
+  RVC_TEST_CASE (5, sp, 0x1234 + 496 - 512, c.addi16sp sp, -512)
+
+  la a1, data
+  RVC_TEST_CASE (6, a2, 0xfffffffffedcba99, c.lw a0, 4(a1); addi a0, a0, 1; c.sw a0, 4(a1); c.lw a2, 4(a1))
+#ifdef __riscv64
+  RVC_TEST_CASE (7, a2, 0xfedcba9976543211, c.ld a0, 0(a1); addi a0, a0, 1; c.sd a0, 0(a1); c.ld a2, 0(a1))
+#endif
+
+  RVC_TEST_CASE (8, a0, -15, ori a0, x0, 1; c.addi a0, -16)
+  RVC_TEST_CASE (9, a5, -16, ori a5, x0, 1; c.li a5, -16)
+#ifdef __riscv64
+  RVC_TEST_CASE (10, a0, 0x76543210, ld a0, (a1); c.addiw a0, -1)
+#endif
+
+  RVC_TEST_CASE (11, s0, 0xffffffffffffffe1, c.lui s0, 0xfffe1; c.srai s0, 12)
+#ifdef __riscv64
+  RVC_TEST_CASE (12, s0, 0x000fffffffffffe1, c.lui s0, 0xfffe1; c.srli s0, 12)
+#else
+  RVC_TEST_CASE (12, s0, 0x000fffe1, c.lui s0, 0xfffe1; c.srli s0, 12)
+#endif
+  RVC_TEST_CASE (14, s0, ~0x11, c.li s0, -2; c.andi s0, ~0x10)
+  RVC_TEST_CASE (15, s1, 14, li s1, 20; li a0, 6; c.sub s1, a0)
+  RVC_TEST_CASE (16, s1, 18, li s1, 20; li a0, 6; c.xor s1, a0)
+  RVC_TEST_CASE (17, s1, 22, li s1, 20; li a0, 6; c.or s1, a0)
+  RVC_TEST_CASE (18, s1,  4, li s1, 20; li a0, 6; c.and s1, a0)
+#ifdef __riscv64
+  RVC_TEST_CASE (19, s1, 0xffffffff80000000, li s1, 0x7fffffff; li a0, -1; c.subw s1, a0)
+  RVC_TEST_CASE (20, s1, 0xffffffff80000000, li s1, 0x7fffffff; li a0, 1; c.addw s1, a0)
+#endif
+  RVC_TEST_CASE (21, s0, 0x12340, li s0, 0x1234; c.slli s0, 4)
+
+  RVC_TEST_CASE (30, ra, 0, \
+        li ra, 0; \
+        c.j 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (31, x0, 0, \
+        li a0, 0; \
+        c.beqz a0, 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (32, x0, 0, \
+        li a0, 1; \
+        c.bnez a0, 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (33, x0, 0, \
+        li a0, 1; \
+        c.beqz a0, 1f; \
+        c.j 2f; \
+      1:c.j fail; \
+      2:)
+
+  RVC_TEST_CASE (34, x0, 0, \
+        li a0, 0; \
+        c.bnez a0, 1f; \
+        c.j 2f; \
+      1:c.j fail; \
+      2:)
+
+  RVC_TEST_CASE (35, ra, 0, \
+        la t0, 1f; \
+        li ra, 0; \
+        c.jr t0; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:)
+
+  RVC_TEST_CASE (36, ra, -2, \
+        la t0, 1f; \
+        li ra, 0; \
+        c.jalr t0; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:sub ra, ra, t0)
+
+#ifdef __riscv32
+  RVC_TEST_CASE (37, ra, -2, \
+        la t0, 1f; \
+        li ra, 0; \
+        c.jal 1f; \
+        c.j 2f; \
+      1:c.j 1f; \
+      2:j fail; \
+      1:sub ra, ra, t0)
+#endif
+
+  la sp, data
+  RVC_TEST_CASE (40, a2, 0xfffffffffedcba99, c.lwsp a0, 12(sp); addi a0, a0, 1; c.swsp a0, 12(sp); c.lwsp a2, 12(sp))
+#ifdef __riscv64
+  RVC_TEST_CASE (41, a2, 0xfedcba9976543211, c.ldsp a0, 8(sp); addi a0, a0, 1; c.sdsp a0, 8(sp); c.ldsp a2, 8(sp))
+#endif
+
+  RVC_TEST_CASE (42, t0, 0x246, li a0, 0x123; c.mv t0, a0; c.add t0, a0)
+
+  .option pop
+
+  TEST_PASSFAIL
+
+RVTEST_CODE_END
+
+  .data
+RVTEST_DATA_BEGIN
+
+data:
+  .dword 0xfedcba9876543210
+  .dword 0xfedcba9876543210
+
+RVTEST_DATA_END