aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-09-12 18:48:44 -0700
committerTim Newsome <tim@sifive.com>2017-09-14 12:32:59 -0700
commit6c2ad1c5c27f5e19e005541f7665a32814d32e0f (patch)
treebebb1df50e44a8d0d87c235eba10e7f6332f1d36
parent706b6476a2eb320a84fef39716a7c19a83b68a39 (diff)
downloadriscv-tests-6c2ad1c5c27f5e19e005541f7665a32814d32e0f.zip
riscv-tests-6c2ad1c5c27f5e19e005541f7665a32814d32e0f.tar.gz
riscv-tests-6c2ad1c5c27f5e19e005541f7665a32814d32e0f.tar.bz2
Test debugging code with interrupts.
-rwxr-xr-xdebug/gdbserver.py43
-rwxr-xr-xdebug/programs/entry.S4
-rw-r--r--debug/programs/init.c2
-rw-r--r--debug/programs/interrupt.c32
-rw-r--r--debug/targets.py3
5 files changed, 80 insertions, 4 deletions
diff --git a/debug/gdbserver.py b/debug/gdbserver.py
index 21eea4e..9fedbca 100755
--- a/debug/gdbserver.py
+++ b/debug/gdbserver.py
@@ -419,6 +419,49 @@ class UserInterrupt(DebugTest):
self.gdb.p("i=0")
self.exit()
+class InterruptTest(GdbSingleHartTest):
+ compile_args = ("programs/interrupt.c",)
+
+ def early_applicable(self):
+ return self.target.supports_clint_mtime
+
+ def setup(self):
+ self.gdb.load()
+
+ def test(self):
+ self.gdb.b("main")
+ output = self.gdb.c()
+ assertIn(" main ", output)
+ self.gdb.b("trap_entry")
+ output = self.gdb.c()
+ assertIn(" trap_entry ", output)
+ assertEqual(self.gdb.p("$mip") & 0x80, 0x80)
+ assertEqual(self.gdb.p("interrupt_count"), 0)
+ # You'd expect local to still be 0, but it looks like spike doesn't
+ # jump to the interrupt handler immediately after the write to
+ # mtimecmp.
+ assertLess(self.gdb.p("local"), 1000)
+ self.gdb.command("delete breakpoints")
+ for _ in range(10):
+ self.gdb.c(wait=False)
+ time.sleep(2)
+ self.gdb.interrupt()
+ interrupt_count = self.gdb.p("interrupt_count")
+ local = self.gdb.p("local")
+ if interrupt_count > 1000 and \
+ local > 1000:
+ return
+
+ assertGreater(interrupt_count, 1000)
+ assertGreater(local, 1000)
+
+ def postMortem(self):
+ GdbSingleHartTest.postMortem(self)
+ self.gdb.p("*((long long*) 0x200bff8)")
+ self.gdb.p("*((long long*) 0x2004000)")
+ self.gdb.p("interrupt_count")
+ self.gdb.p("local")
+
class MulticoreRegTest(GdbTest):
compile_args = ("programs/infinite_loop.S", "-DMULTICORE")
diff --git a/debug/programs/entry.S b/debug/programs/entry.S
index a2ea955..97b62a3 100755
--- a/debug/programs/entry.S
+++ b/debug/programs/entry.S
@@ -1,8 +1,6 @@
#include "encoding.h"
-// Enough stack to store every register in case a trap handler is executed,
-// plus 33 more values.
-#define STACK_SIZE (64 * XLEN / 8)
+#define STACK_SIZE (74 * XLEN / 8)
#if XLEN == 64
# define LREG ld
diff --git a/debug/programs/init.c b/debug/programs/init.c
index 9933c23..8b047de 100644
--- a/debug/programs/init.c
+++ b/debug/programs/init.c
@@ -17,7 +17,7 @@ void enable_timer_interrupts()
set_csr(mstatus, MSTATUS_MIE);
}
-void handle_trap(unsigned int mcause, unsigned int mepc, unsigned int sp)
+void handle_trap(unsigned int mcause, void *mepc, void *sp)
{
unsigned hartid = csr_read(mhartid);
if (trap_handler[hartid]) {
diff --git a/debug/programs/interrupt.c b/debug/programs/interrupt.c
new file mode 100644
index 0000000..c2dd5ec
--- /dev/null
+++ b/debug/programs/interrupt.c
@@ -0,0 +1,32 @@
+#include "init.h"
+#include "encoding.h"
+
+static volatile unsigned interrupt_count;
+static volatile unsigned local;
+
+static unsigned delta = 0x100;
+void *increment_count(unsigned hartid, unsigned mcause, void *mepc, void *sp)
+{
+ interrupt_count++;
+ // There is no guarantee that the interrupt is cleared immediately when
+ // MTIMECMP is written, so stick around here until that happens.
+ while (csr_read(mip) & MIP_MTIP) {
+ MTIMECMP[hartid] = MTIME + delta;
+ }
+ return mepc;
+}
+
+int main()
+{
+ interrupt_count = 0;
+ local = 0;
+ unsigned hartid = csr_read(mhartid);
+
+ set_trap_handler(increment_count);
+ MTIMECMP[hartid] = MTIME - 1;
+ enable_timer_interrupts();
+
+ while (1) {
+ local++;
+ }
+}
diff --git a/debug/targets.py b/debug/targets.py
index db8d917..d661d14 100644
--- a/debug/targets.py
+++ b/debug/targets.py
@@ -67,6 +67,9 @@ class Target(object):
# before starting the test.
gdb_setup = []
+ # Supports mtime at 0x2004000
+ supports_clint_mtime = True
+
# Internal variables:
directory = None
temporary_files = []