diff options
author | Palmer Dabbelt <palmer@dabbelt.com> | 2017-06-13 15:14:38 -0700 |
---|---|---|
committer | Palmer Dabbelt <palmer@dabbelt.com> | 2017-06-14 08:53:39 -0700 |
commit | b22853b2f4bdd1ed31d601ebd331083d67d40f11 (patch) | |
tree | b93f00a0566675d6c38152d5097acf30381a3e04 /software/smp | |
parent | c08ce47e3829d8070ba7b4813cfc7a9a48c35a3c (diff) |
Add a SMP example
This just prints "hello world" on two cores. It contains an example of
how to initialize a multi-core system using IPIs, and a simple spin
lock.
Diffstat (limited to 'software/smp')
-rw-r--r-- | software/smp/Makefile | 6 | ||||
-rw-r--r-- | software/smp/atomic.h | 29 | ||||
-rw-r--r-- | software/smp/smp.c | 40 |
3 files changed, 75 insertions, 0 deletions
diff --git a/software/smp/Makefile b/software/smp/Makefile new file mode 100644 index 0000000..4131ffc --- /dev/null +++ b/software/smp/Makefile @@ -0,0 +1,6 @@ +TARGET = smp +C_SRCS += smp.c +CFLAGS += -O2 -fno-builtin-printf -DENABLE_SMP + +BSP_BASE = ../../bsp +include $(BSP_BASE)/env/common.mk diff --git a/software/smp/atomic.h b/software/smp/atomic.h new file mode 100644 index 0000000..074c6a2 --- /dev/null +++ b/software/smp/atomic.h @@ -0,0 +1,29 @@ +#ifndef SIFIVE_ATOMIC_H +#define SIFIVE_ATOMIC_H + +#define ATOMIC_INIT(x) \ + { \ + .counter = (x), \ + } + +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; +} + +static inline void mb(void) +{ + __asm__ __volatile__ ("fence"); +} + +#endif diff --git a/software/smp/smp.c b/software/smp/smp.c new file mode 100644 index 0000000..36c9db9 --- /dev/null +++ b/software/smp/smp.c @@ -0,0 +1,40 @@ +#include <stdio.h> +#include <unistd.h> +#include "atomic.h" +void write_hex(int, unsigned long); + +atomic_t tty_lock = ATOMIC_INIT(0); + +void get_lock(atomic_t *lock) +{ + while (atomic_xchg(lock, 1) == 1); + mb(); +} + +void put_lock(atomic_t *lock) +{ + mb(); + atomic_xchg(lock, 0); +} + +int secondary_main(int hartid) +{ + volatile int counter; + + while (1) { + get_lock(&tty_lock); + write(1, "hello world from hart ", 22); + char s[] = {'0', '\n', '\0'}; + s[0] += hartid; + write(1, s, 2); + put_lock(&tty_lock); + + for (counter = 0; counter < 10000 + 100*hartid; ++counter) + mb(); + } +} + +int main() +{ + return secondary_main(0); +} |