Add some infrastructure for multicore tests.
[riscv-tests.git] / debug / programs / entry.S
1 #include "encoding.h"
2
3 // Enough stack to store every register in case a trap handler is executed,
4 // plus 33 more values.
5 #define STACK_SIZE (64 * XLEN / 8)
6
7 #if XLEN == 64
8 # define LREG ld
9 # define SREG sd
10 # define REGBYTES 8
11 #else
12 # define LREG lw
13 # define SREG sw
14 # define REGBYTES 4
15 #endif
16
17 .section .text.entry
18 .globl _start
19 _start:
20 j handle_reset
21
22 nmi_vector:
23 j nmi_vector
24
25 trap_vector:
26 j trap_entry
27
28 handle_reset:
29 // If misa doesn't exist (or is following an old spec where it has a
30 // different number), skip the next block.
31 la t0, 3f
32 csrw mtvec, t0
33 csrwi mstatus, 0
34
35 // make sure these registers exist by seeing if either S or U bits
36 // are set before attempting to zero them out.
37 csrr t1, misa
38 addi t2, x0, 1
39 slli t2, t2, 20 // U_EXTENSION
40 and t2, t1, t2
41 bne x0, t2, 1f
42 addi t2, x0, 1
43 slli t2, t2, 18 // S_EXTENSION
44 and t2, t1, t2
45 bne x0, t2, 1f
46 j 2f
47 1:
48 csrwi mideleg, 0
49 csrwi medeleg, 0
50 2:
51 csrwi mie, 0
52 3:
53 la t0, trap_entry
54 csrw mtvec, t0
55 csrwi mstatus, 0
56
57 # initialize global pointer
58 .option push
59 .option norelax
60 la gp, __global_pointer$
61 .option pop
62
63 # Initialize stack pointer.
64 # Give each hart STACK_SIZE of stack.
65 # Assume hart IDs are contiguous and start at 0.
66 csrr t0, CSR_MHARTID
67 addi t0, t0, 1
68 li t1, STACK_SIZE
69 mul t0, t0, t1
70 la sp, stack_bottom
71 add sp, sp, t0
72
73 # Clear all hardware triggers
74 li t0, ~0
75 1:
76 addi t0, t0, 1
77 csrw CSR_TSELECT, t0
78 csrw CSR_TDATA1, zero
79 csrr t1, CSR_TSELECT
80 beq t0, t1, 1b
81
82 #ifdef MULTICORE
83 csrr t0, CSR_MHARTID
84 bnez t0, wait_until_initialized
85 #endif
86
87 la t0, __bss_start
88 la t1, __bss_end
89 1:
90 bge t0, t1, 2f
91 sb zero, 0(t0)
92 addi t0, t0, 1
93 j 1b
94 2:
95 #ifdef MULTICORE
96 la t0, initialized
97 li t1, 1
98 sw t1, 0(t0)
99
100 wait_until_initialized: # Wait for hart 0 to perform initialization.
101 la t0, initialized
102 1:
103 lw t1, 0(t0)
104 beqz t1, 1b
105 #endif
106
107 # perform the rest of initialization in C
108 j _init
109
110
111 trap_entry:
112 addi sp, sp, -32*REGBYTES
113
114 SREG x1, 1*REGBYTES(sp)
115 SREG x2, 2*REGBYTES(sp)
116 SREG x3, 3*REGBYTES(sp)
117 SREG x4, 4*REGBYTES(sp)
118 SREG x5, 5*REGBYTES(sp)
119 SREG x6, 6*REGBYTES(sp)
120 SREG x7, 7*REGBYTES(sp)
121 SREG x8, 8*REGBYTES(sp)
122 SREG x9, 9*REGBYTES(sp)
123 SREG x10, 10*REGBYTES(sp)
124 SREG x11, 11*REGBYTES(sp)
125 SREG x12, 12*REGBYTES(sp)
126 SREG x13, 13*REGBYTES(sp)
127 SREG x14, 14*REGBYTES(sp)
128 SREG x15, 15*REGBYTES(sp)
129 SREG x16, 16*REGBYTES(sp)
130 SREG x17, 17*REGBYTES(sp)
131 SREG x18, 18*REGBYTES(sp)
132 SREG x19, 19*REGBYTES(sp)
133 SREG x20, 20*REGBYTES(sp)
134 SREG x21, 21*REGBYTES(sp)
135 SREG x22, 22*REGBYTES(sp)
136 SREG x23, 23*REGBYTES(sp)
137 SREG x24, 24*REGBYTES(sp)
138 SREG x25, 25*REGBYTES(sp)
139 SREG x26, 26*REGBYTES(sp)
140 SREG x27, 27*REGBYTES(sp)
141 SREG x28, 28*REGBYTES(sp)
142 SREG x29, 29*REGBYTES(sp)
143 SREG x30, 30*REGBYTES(sp)
144 SREG x31, 31*REGBYTES(sp)
145
146 csrr a0, mcause
147 csrr a1, mepc
148 mv a2, sp
149 jal handle_trap
150 csrw mepc, a0
151
152 # Remain in M-mode after mret
153 li t0, MSTATUS_MPP
154 csrs mstatus, t0
155
156 LREG x1, 1*REGBYTES(sp)
157 LREG x2, 2*REGBYTES(sp)
158 LREG x3, 3*REGBYTES(sp)
159 LREG x4, 4*REGBYTES(sp)
160 LREG x5, 5*REGBYTES(sp)
161 LREG x6, 6*REGBYTES(sp)
162 LREG x7, 7*REGBYTES(sp)
163 LREG x8, 8*REGBYTES(sp)
164 LREG x9, 9*REGBYTES(sp)
165 LREG x10, 10*REGBYTES(sp)
166 LREG x11, 11*REGBYTES(sp)
167 LREG x12, 12*REGBYTES(sp)
168 LREG x13, 13*REGBYTES(sp)
169 LREG x14, 14*REGBYTES(sp)
170 LREG x15, 15*REGBYTES(sp)
171 LREG x16, 16*REGBYTES(sp)
172 LREG x17, 17*REGBYTES(sp)
173 LREG x18, 18*REGBYTES(sp)
174 LREG x19, 19*REGBYTES(sp)
175 LREG x20, 20*REGBYTES(sp)
176 LREG x21, 21*REGBYTES(sp)
177 LREG x22, 22*REGBYTES(sp)
178 LREG x23, 23*REGBYTES(sp)
179 LREG x24, 24*REGBYTES(sp)
180 LREG x25, 25*REGBYTES(sp)
181 LREG x26, 26*REGBYTES(sp)
182 LREG x27, 27*REGBYTES(sp)
183 LREG x28, 28*REGBYTES(sp)
184 LREG x29, 29*REGBYTES(sp)
185 LREG x30, 30*REGBYTES(sp)
186 LREG x31, 31*REGBYTES(sp)
187
188 addi sp, sp, 32*REGBYTES
189 mret
190
191 loop_forever:
192 j loop_forever
193
194 // Fill the stack with data so we can see if it was overrun.
195 .align 4
196 stack_bottom:
197 .fill NHARTS * STACK_SIZE/4, 4, 0x22446688
198 stack_top:
199 initialized:
200 .word 0