aboutsummaryrefslogtreecommitdiff
path: root/debug/programs
diff options
context:
space:
mode:
Diffstat (limited to 'debug/programs')
-rwxr-xr-xdebug/programs/entry.S53
-rw-r--r--debug/programs/init.c23
-rw-r--r--debug/programs/multicore.c81
-rw-r--r--debug/programs/start.S12
4 files changed, 148 insertions, 21 deletions
diff --git a/debug/programs/entry.S b/debug/programs/entry.S
index ff8ae30..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 512
+// 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
@@ -61,8 +60,15 @@ handle_reset:
la gp, __global_pointer$
.option pop
- # initialize stack pointer
- la sp, stack_top
+ # Initialize stack pointer.
+ # 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
+ mul t0, t0, t1
+ la sp, stack_bottom
+ add sp, sp, t0
# Clear all hardware triggers
li t0, ~0
@@ -73,8 +79,33 @@ handle_reset:
csrr t1, CSR_TSELECT
beq t0, t1, 1b
+#ifdef MULTICORE
+ csrr t0, CSR_MHARTID
+ bnez t0, wait_until_initialized
+#endif
+
+ la t0, __bss_start
+ la t1, __bss_end
+1:
+ bge t0, t1, 2f
+ sb zero, 0(t0)
+ addi t0, t0, 1
+ j 1b
+2:
+#ifdef MULTICORE
+ la t0, initialized
+ li t1, 1
+ sw t1, 0(t0)
+
+wait_until_initialized: # Wait for hart 0 to perform initialization.
+ la t0, initialized
+1:
+ lw t1, 0(t0)
+ beqz t1, 1b
+#endif
+
# perform the rest of initialization in C
- j _init
+ j _init
trap_entry:
@@ -157,9 +188,13 @@ trap_entry:
addi sp, sp, 32*REGBYTES
mret
+loop_forever:
+ j 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:
-#endif
+initialized:
+ .word 0
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/programs/multicore.c b/debug/programs/multicore.c
new file mode 100644
index 0000000..d7dd845
--- /dev/null
+++ b/debug/programs/multicore.c
@@ -0,0 +1,81 @@
+#include <stdint.h>
+
+typedef struct {
+ int counter;
+} atomic_t;
+
+static inline int atomic_xchg(atomic_t *v, int n)
+{
+ register int c;
+
+ __asm__ __volatile__ (
+ "amoswap.w.aqrl %0, %2, %1"
+ : "=r" (c), "+A" (v->counter)
+ : "r" (n));
+ return c;
+}
+
+#define csr_read(csr) \
+({ \
+ register unsigned long __v; \
+ __asm__ __volatile__ ("csrr %0, " #csr \
+ : "=r" (__v)); \
+ __v; \
+})
+
+static inline void mb(void)
+{
+ __asm__ __volatile__ ("fence");
+}
+
+void get_lock(atomic_t *lock)
+{
+ while (atomic_xchg(lock, 1) == 1)
+ ;
+ mb();
+}
+
+void put_lock(atomic_t *lock)
+{
+ mb();
+ atomic_xchg(lock, 0);
+}
+
+static atomic_t buf_lock = { .counter = 0 };
+static char buf[32];
+static int buf_initialized;
+static unsigned hart_count[2];
+
+static const char case_bit = 'a' - 'A';
+volatile int initialized;
+
+int main()
+{
+ uint32_t hartid = csr_read(mhartid);
+ hart_count[hartid] = 0;
+
+ while (1) {
+ get_lock(&buf_lock);
+ hart_count[hartid]++;
+
+ if (!buf_initialized) {
+ for (unsigned i = 0; i < sizeof(buf); i++) {
+ buf[i] = 'A' + (i % 26);
+ }
+ buf_initialized = 1;
+ }
+
+ char first = buf[0];
+ int offset = (first & ~0x20) - 'A';
+ for (unsigned i = 0; i < sizeof(buf); i++) {
+ while (buf[i] != (first - offset + ((offset + i) % 26)))
+ ;
+
+ if (hartid & 1)
+ buf[i] = 'A' + ((i + hartid + hart_count[hartid]) % 26);
+ else
+ buf[i] = 'a' + ((i + hartid + hart_count[hartid]) % 26);
+ }
+ put_lock(&buf_lock);
+ }
+}
diff --git a/debug/programs/start.S b/debug/programs/start.S
deleted file mode 100644
index 76c37bb..0000000
--- a/debug/programs/start.S
+++ /dev/null
@@ -1,12 +0,0 @@
- .global _start
-
-_start:
- la sp, stack_end
- jal main
-done:
- j done
-
- .data
-stack:
- .fill 4096, 1, 0
-stack_end: