diff options
Diffstat (limited to 'bsp/include/sifive')
-rw-r--r-- | bsp/include/sifive/bits.h | 3 | ||||
-rw-r--r-- | bsp/include/sifive/const.h | 1 | ||||
-rw-r--r-- | bsp/include/sifive/sections.h | 1 | ||||
-rw-r--r-- | bsp/include/sifive/smp.h | 65 |
4 files changed, 69 insertions, 1 deletions
diff --git a/bsp/include/sifive/bits.h b/bsp/include/sifive/bits.h index e550f80..bfe656f 100644 --- a/bsp/include/sifive/bits.h +++ b/bsp/include/sifive/bits.h @@ -1,3 +1,4 @@ +// See LICENSE for license details. #ifndef _RISCV_BITS_H #define _RISCV_BITS_H @@ -17,7 +18,7 @@ #define STR(x) XSTR(x) #define XSTR(x) #x -#ifdef __riscv64 +#if __riscv_xlen == 64 # define SLL32 sllw # define STORE sd # define LOAD ld diff --git a/bsp/include/sifive/const.h b/bsp/include/sifive/const.h index 3e0a681..8dcffbb 100644 --- a/bsp/include/sifive/const.h +++ b/bsp/include/sifive/const.h @@ -1,3 +1,4 @@ +// See LICENSE for license details. /* Derived from <linux/const.h> */ #ifndef _SIFIVE_CONST_H diff --git a/bsp/include/sifive/sections.h b/bsp/include/sifive/sections.h index 848c237..6e1f051 100644 --- a/bsp/include/sifive/sections.h +++ b/bsp/include/sifive/sections.h @@ -1,3 +1,4 @@ +// See LICENSE for license details. #ifndef _SECTIONS_H #define _SECTIONS_H diff --git a/bsp/include/sifive/smp.h b/bsp/include/sifive/smp.h new file mode 100644 index 0000000..8e34388 --- /dev/null +++ b/bsp/include/sifive/smp.h @@ -0,0 +1,65 @@ +#ifndef SIFIVE_SMP +#define SIFIVE_SMP + +// The maximum number of HARTs this code supports +#ifndef MAX_HARTS +#define MAX_HARTS 32 +#endif +#define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS*4) + +// The hart that non-SMP tests should run on +#ifndef NONSMP_HART +#define NONSMP_HART 0 +#endif + +/* If your test cannot handle multiple-threads, use this: + * smp_disable(reg1) + */ +#define smp_disable(reg1, reg2) \ + csrr reg1, mhartid ;\ + li reg2, NONSMP_HART ;\ + beq reg1, reg2, hart0_entry ;\ +42: ;\ + wfi ;\ + j 42b ;\ +hart0_entry: + +/* If your test needs to temporarily block multiple-threads, do this: + * smp_pause(reg1, reg2) + * ... single-threaded work ... + * smp_resume(reg1, reg2) + * ... multi-threaded work ... + */ + +#define smp_pause(reg1, reg2) \ + li reg2, 0x8 ;\ + csrw mie, reg2 ;\ + csrr reg2, mhartid ;\ + bnez reg2, 42f + +#define smp_resume(reg1, reg2) \ + li reg1, CLINT_CTRL_ADDR ;\ +41: ;\ + li reg2, 1 ;\ + sw reg2, 0(reg1) ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b ;\ +42: ;\ + wfi ;\ + csrr reg2, mip ;\ + andi reg2, reg2, 0x8 ;\ + beqz reg2, 42b ;\ + li reg1, CLINT_CTRL_ADDR ;\ + csrr reg2, mhartid ;\ + slli reg2, reg2, 2 ;\ + add reg2, reg2, reg1 ;\ + sw zero, 0(reg2) ;\ +41: ;\ + lw reg2, 0(reg1) ;\ + bnez reg2, 41b ;\ + addi reg1, reg1, 4 ;\ + li reg2, CLINT_END_HART_IPI ;\ + blt reg1, reg2, 41b + +#endif |