#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