diff options
Diffstat (limited to 'debug/programs')
-rwxr-xr-x | debug/programs/entry.S | 53 | ||||
-rw-r--r-- | debug/programs/init.c | 23 | ||||
-rw-r--r-- | debug/programs/multicore.c | 81 | ||||
-rw-r--r-- | debug/programs/start.S | 12 |
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: |