From a7238f6f683705a92a3216562d91cfc8979c75ed Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Fri, 1 Sep 2017 12:31:15 -0700 Subject: [PATCH] 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. --- debug/gdbserver.py | 2 +- debug/programs/entry.S | 15 ++++++----- debug/programs/init.c | 23 +++++++++++++++++ debug/targets.py | 57 +++++++++++++++++++++--------------------- debug/testlib.py | 4 +-- 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- 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): -- 2.30.2