866636b1b50b7e052faaf150ae62752623a9f68d
[riscv-tests.git] / debug / programs / entry.S
1 #ifndef ENTRY_S
2 #define ENTRY_S
3
4 #include "encoding.h"
5
6 #define STACK_SIZE 1024
7
8 #if XLEN == 64
9 # define LREG ld
10 # define SREG sd
11 # define REGBYTES 8
12 #else
13 # define LREG lw
14 # define SREG sw
15 # define REGBYTES 4
16 #endif
17
18 .section .text.entry
19 .globl _start
20 _start:
21 j handle_reset
22
23 nmi_vector:
24 j nmi_vector
25
26 trap_vector:
27 j trap_entry
28
29 handle_reset:
30 // If misa doesn't exist (or is following an old spec where it has a
31 // different number), skip the next block.
32 la t0, 3f
33 csrw mtvec, t0
34 csrwi mstatus, 0
35
36 // make sure these registers exist by seeing if either S or U bits
37 // are set before attempting to zero them out.
38 csrr t1, misa
39 addi t2, x0, 1
40 slli t2, t2, 20 // U_EXTENSION
41 and t2, t1, t2
42 bne x0, t2, 1f
43 addi t2, x0, 1
44 slli t2, t2, 18 // S_EXTENSION
45 and t2, t1, t2
46 bne x0, t2, 1f
47 j 2f
48 1:
49 csrwi mideleg, 0
50 csrwi medeleg, 0
51 2:
52 csrwi mie, 0
53 3:
54 la t0, trap_entry
55 csrw mtvec, t0
56 csrwi mstatus, 0
57
58 # initialize global pointer
59 .option push
60 .option norelax
61 la gp, __global_pointer$
62 .option pop
63
64 # Initialize stack pointer.
65 # Support up to 4 harts, with IDs 0--3.
66 csrr t0, CSR_MHARTID
67 addi t0, t0, 1
68 li t1, STACK_SIZE / 4
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 STACK_SIZE/4, 4, 0x22446688
198 stack_top:
199 initialized:
200 .word 0
201 #endif