Add some infrastructure for multicore tests.
authorTim Newsome <tim@sifive.com>
Fri, 1 Sep 2017 19:31:15 +0000 (12:31 -0700)
committerTim Newsome <tim@sifive.com>
Fri, 1 Sep 2017 19:31:15 +0000 (12:31 -0700)
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
debug/programs/entry.S
debug/programs/init.c
debug/targets.py
debug/testlib.py

index 78ac9aaebb5403bc3644ccc3eb0cf80c032b46a4..21eea4ed521b2da90c18e301b06838784eb4c20d 100755 (executable)
@@ -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)
 
index 866636b1b50b7e052faaf150ae62752623a9f68d..a2ea955a2707ed93d1283b066d801fc46ac2d398 100755 (executable)
@@ -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
index a2b41b02d60e2eb51af3d9322dcedb2f72460c67..9933c23a72705be76deef9a670ff053b853384a8 100644 (file)
@@ -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)
         ;
 }
index 8efa2559d8f72c2539100b2eddfa444e6cdb414f..db8d917c7b9f2a2132acd4c026f4edecf53d2500 100644 (file)
@@ -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.")
index 692afb6f70f2b0587862c4d1ac755e983e6b5799..8ac616e7dd19b24d02bb401537858cb2fdc368a1 100644 (file)
@@ -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):