5 // The maximum number of HARTs this code supports
9 #define CLINT_END_HART_IPI CLINT_CTRL_ADDR + (MAX_HARTS*4)
10 #define CLINT1_END_HART_IPI CLINT1_CTRL_ADDR + (MAX_HARTS*4)
12 // The hart that non-SMP tests should run on
17 /* If your test cannot handle multiple-threads, use this:
20 #define smp_disable(reg1, reg2) \
22 li reg2, NONSMP_HART ;\
23 beq reg1, reg2, hart0_entry ;\
29 /* If your test needs to temporarily block multiple-threads, do this:
30 * smp_pause(reg1, reg2)
31 * ... single-threaded work ...
32 * smp_resume(reg1, reg2)
33 * ... multi-threaded work ...
36 #define smp_pause(reg1, reg2) \
39 li reg1, NONSMP_HART ;\
43 #ifdef CLINT1_CTRL_ADDR
44 // If a second CLINT exists, then make sure we:
45 // 1) Trigger a software interrupt on all harts of both CLINTs.
46 // 2) Locate your own hart's software interrupt pending register and clear it.
47 // 3) Wait for all harts on both CLINTs to clear their software interrupt
49 // WARNING: This code makes these assumptions, which are only true for Fadu as
51 // 1) hart0 uses CLINT0 at offset 0
52 // 2) hart2 uses CLINT1 at offset 0
53 // 3) hart3 uses CLINT1 at offset 1
54 // 4) There are no other harts or CLINTs in the system.
55 #define smp_resume(reg1, reg2) \
56 /* Trigger software interrupt on CLINT0 */ \
57 li reg1, CLINT_CTRL_ADDR ;\
62 li reg2, CLINT_END_HART_IPI ;\
63 blt reg1, reg2, 41b ;\
64 /* Trigger software interrupt on CLINT1 */ \
65 li reg1, CLINT1_CTRL_ADDR ;\
70 li reg2, CLINT1_END_HART_IPI ;\
71 blt reg1, reg2, 41b ;\
72 /* Wait to receive software interrupt */ \
76 andi reg2, reg2, 0x8 ;\
78 /* Clear own software interrupt bit */ \
81 /* hart0 case: Use CLINT0 */ \
82 li reg1, CLINT_CTRL_ADDR ;\
84 add reg2, reg2, reg1 ;\
88 /* hart 2, 3 case: Use CLINT1 and remap hart IDs to 0 and 1 */ \
89 li reg1, CLINT1_CTRL_ADDR ;\
90 addi reg2, reg2, -2; \
92 add reg2, reg2, reg1 ;\
95 /* Wait for all software interrupt bits to be cleared on CLINT0 */ \
96 li reg1, CLINT_CTRL_ADDR ;\
100 addi reg1, reg1, 4 ;\
101 li reg2, CLINT_END_HART_IPI ;\
102 blt reg1, reg2, 41b; \
103 /* Wait for all software interrupt bits to be cleared on CLINT1 */ \
104 li reg1, CLINT1_CTRL_ADDR ;\
108 addi reg1, reg1, 4 ;\
109 li reg2, CLINT1_END_HART_IPI ;\
110 blt reg1, reg2, 41b; \
111 /* End smp_resume() */
115 #define smp_resume(reg1, reg2) \
116 li reg1, CLINT_CTRL_ADDR ;\
120 addi reg1, reg1, 4 ;\
121 li reg2, CLINT_END_HART_IPI ;\
122 blt reg1, reg2, 41b ;\
126 andi reg2, reg2, 0x8 ;\
128 li reg1, CLINT_CTRL_ADDR ;\
129 csrr reg2, mhartid ;\
130 slli reg2, reg2, 2 ;\
131 add reg2, reg2, reg1 ;\
136 addi reg1, reg1, 4 ;\
137 li reg2, CLINT_END_HART_IPI ;\
140 #endif /* ifdef CLINT1_CTRL_ADDR */