aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Newsome <tim@sifive.com>2017-09-01 12:31:15 -0700
committerTim Newsome <tim@sifive.com>2017-09-01 12:31:15 -0700
commita7238f6f683705a92a3216562d91cfc8979c75ed (patch)
treeb05fb4b85558c595517fb23e08193baa8623c415
parent5acbf6414ddaa6552ead5099868897a161bd945f (diff)
downloadriscv-tests-a7238f6f683705a92a3216562d91cfc8979c75ed.zip
riscv-tests-a7238f6f683705a92a3216562d91cfc8979c75ed.tar.gz
riscv-tests-a7238f6f683705a92a3216562d91cfc8979c75ed.tar.bz2
Add some infrastructure for multicore tests.
When compiling, define the number of harts. This means we only need to allocate a lot of stack if there are a lot of harts.
-rwxr-xr-xdebug/gdbserver.py2
-rwxr-xr-xdebug/programs/entry.S15
-rw-r--r--debug/programs/init.c23
-rw-r--r--debug/targets.py57
-rw-r--r--debug/testlib.py4
5 files changed, 61 insertions, 40 deletions
diff --git a/debug/gdbserver.py b/debug/gdbserver.py
index 78ac9aa..21eea4e 100755
--- a/debug/gdbserver.py
+++ b/debug/gdbserver.py
@@ -708,7 +708,7 @@ class DownloadTest(GdbTest):
if self.crc < 0:
self.crc += 2**32
- self.binary = self.hart.compile(self.download_c.name,
+ self.binary = self.target.compile(self.hart, self.download_c.name,
"programs/checksum.c")
self.gdb.command("file %s" % self.binary)
diff --git a/debug/programs/entry.S b/debug/programs/entry.S
index 866636b..a2ea955 100755
--- a/debug/programs/entry.S
+++ b/debug/programs/entry.S
@@ -1,9 +1,8 @@
-#ifndef ENTRY_S
-#define ENTRY_S
-
#include "encoding.h"
-#define STACK_SIZE 1024
+// Enough stack to store every register in case a trap handler is executed,
+// plus 33 more values.
+#define STACK_SIZE (64 * XLEN / 8)
#if XLEN == 64
# define LREG ld
@@ -62,10 +61,11 @@ handle_reset:
.option pop
# Initialize stack pointer.
- # Support up to 4 harts, with IDs 0--3.
+ # Give each hart STACK_SIZE of stack.
+ # Assume hart IDs are contiguous and start at 0.
csrr t0, CSR_MHARTID
addi t0, t0, 1
- li t1, STACK_SIZE / 4
+ li t1, STACK_SIZE
mul t0, t0, t1
la sp, stack_bottom
add sp, sp, t0
@@ -194,8 +194,7 @@ loop_forever:
// Fill the stack with data so we can see if it was overrun.
.align 4
stack_bottom:
- .fill STACK_SIZE/4, 4, 0x22446688
+ .fill NHARTS * STACK_SIZE/4, 4, 0x22446688
stack_top:
initialized:
.word 0
-#endif
diff --git a/debug/programs/init.c b/debug/programs/init.c
index a2b41b0..9933c23 100644
--- a/debug/programs/init.c
+++ b/debug/programs/init.c
@@ -1,7 +1,30 @@
+#include "init.h"
+#include "encoding.h"
+
int main(void);
+trap_handler_t trap_handler[NHARTS] = {0};
+
+void set_trap_handler(trap_handler_t handler)
+{
+ unsigned hartid = csr_read(mhartid);
+ trap_handler[hartid] = handler;
+}
+
+void enable_timer_interrupts()
+{
+ set_csr(mie, MIP_MTIP);
+ set_csr(mstatus, MSTATUS_MIE);
+}
+
void handle_trap(unsigned int mcause, unsigned int mepc, unsigned int sp)
{
+ unsigned hartid = csr_read(mhartid);
+ if (trap_handler[hartid]) {
+ trap_handler[hartid](hartid, mcause, mepc, sp);
+ return;
+ }
+
while (1)
;
}
diff --git a/debug/targets.py b/debug/targets.py
index 8efa255..db8d917 100644
--- a/debug/targets.py
+++ b/debug/targets.py
@@ -34,35 +34,6 @@ class Hart(object):
# Defaults to target-<index>
name = None
- def __init__(self):
- self.temporary_binary = None
-
- def compile(self, *sources):
- binary_name = "%s_%s-%d" % (
- self.name,
- os.path.basename(os.path.splitext(sources[0])[0]),
- self.xlen)
- if Target.isolate:
- self.temporary_binary = tempfile.NamedTemporaryFile(
- prefix=binary_name + "_")
- binary_name = self.temporary_binary.name
- Target.temporary_files.append(self.temporary_binary)
- march = "rv%dima" % self.xlen
- for letter in "fdc":
- if self.extensionSupported(letter):
- march += letter
- testlib.compile(sources +
- ("programs/entry.S", "programs/init.c",
- "-I", "../env",
- "-march=%s" % march,
- "-T", self.link_script_path,
- "-nostartfiles",
- "-mcmodel=medany",
- "-DXLEN=%d" % self.xlen,
- "-o", binary_name),
- xlen=self.xlen)
- return binary_name
-
def extensionSupported(self, letter):
# target.misa is set by testlib.ExamineTarget
if self.misa:
@@ -106,6 +77,7 @@ class Target(object):
self.directory = os.path.dirname(path)
self.server_cmd = parsed.server_cmd
self.sim_cmd = parsed.sim_cmd
+ self.temporary_binary = None
Target.isolate = parsed.isolate
if not self.name:
self.name = type(self).__name__
@@ -133,6 +105,33 @@ class Target(object):
return testlib.Openocd(server_cmd=self.server_cmd,
config=self.openocd_config_path)
+ def compile(self, hart, *sources):
+ binary_name = "%s_%s-%d" % (
+ self.name,
+ os.path.basename(os.path.splitext(sources[0])[0]),
+ hart.xlen)
+ if Target.isolate:
+ self.temporary_binary = tempfile.NamedTemporaryFile(
+ prefix=binary_name + "_")
+ binary_name = self.temporary_binary.name
+ Target.temporary_files.append(self.temporary_binary)
+ march = "rv%dima" % hart.xlen
+ for letter in "fdc":
+ if hart.extensionSupported(letter):
+ march += letter
+ testlib.compile(sources +
+ ("programs/entry.S", "programs/init.c",
+ "-DNHARTS=%d" % len(self.harts),
+ "-I", "../env",
+ "-march=%s" % march,
+ "-T", hart.link_script_path,
+ "-nostartfiles",
+ "-mcmodel=medany",
+ "-DXLEN=%d" % hart.xlen,
+ "-o", binary_name),
+ xlen=hart.xlen)
+ return binary_name
+
def add_target_options(parser):
parser.add_argument("target", help=".py file that contains definition for "
"the target to test with.")
diff --git a/debug/testlib.py b/debug/testlib.py
index 692afb6..8ac616e 100644
--- a/debug/testlib.py
+++ b/debug/testlib.py
@@ -102,7 +102,7 @@ class Spike(object):
if with_jtag_gdb:
cmd += ['--rbb-port', '0']
os.environ['REMOTE_BITBANG_HOST'] = 'localhost'
- self.infinite_loop = harts[0].compile(
+ self.infinite_loop = target.compile(harts[0],
"programs/checksum.c", "programs/tiny-malloc.c",
"programs/infinite_loop.S", "-DDEFINE_MALLOC", "-DDEFINE_FREE")
cmd.append(self.infinite_loop)
@@ -567,7 +567,7 @@ class BaseTest(object):
if compile_args not in BaseTest.compiled:
# pylint: disable=star-args
BaseTest.compiled[compile_args] = \
- self.hart.compile(*compile_args)
+ self.target.compile(self.hart, *compile_args)
self.binary = BaseTest.compiled.get(compile_args)
def classSetup(self):