litex: reorganize things, first work working version
[litex.git] / litex / soc / software / libbase / crt0-or1k.S
1 /*
2 * (C) Copyright 2012, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
17 * MA 02111-1307 USA
18 */
19
20 #include <spr-defs.h>
21
22 #define EXCEPTION_STACK_SIZE (4*32)
23
24 #define HANDLE_EXCEPTION ; \
25 l.addi r1, r1, -EXCEPTION_STACK_SIZE ; \
26 l.sw 0x1c(r1), r9 ; \
27 l.jal _exception_handler ; \
28 l.nop ; \
29 l.lwz r9, 0x1c(r1) ; \
30 l.addi r1, r1, EXCEPTION_STACK_SIZE ; \
31 l.rfe ; \
32 l.nop
33
34
35 .section .text, "ax", @progbits
36 .global _start
37 _start:
38 _reset_handler:
39 l.movhi r0, 0
40 l.movhi r1, 0
41 l.movhi r2, 0
42 l.movhi r3, 0
43 l.movhi r4, 0
44 l.movhi r5, 0
45 l.movhi r6, 0
46 l.movhi r7, 0
47 l.movhi r8, 0
48 l.movhi r9, 0
49 l.movhi r10, 0
50 l.movhi r11, 0
51 l.movhi r12, 0
52 l.movhi r13, 0
53 l.movhi r14, 0
54 l.movhi r15, 0
55 l.movhi r16, 0
56 l.movhi r17, 0
57 l.movhi r18, 0
58 l.movhi r19, 0
59 l.movhi r20, 0
60 l.movhi r21, 0
61 l.movhi r22, 0
62 l.movhi r23, 0
63 l.movhi r24, 0
64 l.movhi r25, 0
65 l.movhi r26, 0
66 l.movhi r27, 0
67 l.movhi r28, 0
68 l.movhi r29, 0
69 l.movhi r30, 0
70 l.movhi r31, 0
71
72 l.ori r21, r0, SPR_SR_SM
73 l.mtspr r0, r21, SPR_SR
74 l.movhi r21, hi(_reset_handler)
75 l.ori r21, r21, lo(_reset_handler)
76 l.mtspr r0, r21, SPR_EVBAR
77 /* enable caches */
78 l.jal _cache_init
79 l.nop
80 l.j _crt0
81 l.nop
82
83 /* bus error */
84 .org 0x200
85 HANDLE_EXCEPTION
86
87 /* data page fault */
88 .org 0x300
89 HANDLE_EXCEPTION
90
91 /* instruction page fault */
92 .org 0x400
93 HANDLE_EXCEPTION
94
95 /* tick timer */
96 .org 0x500
97 HANDLE_EXCEPTION
98
99 /* alignment */
100 .org 0x600
101 HANDLE_EXCEPTION
102
103 /* illegal instruction */
104 .org 0x700
105 HANDLE_EXCEPTION
106
107 /* external interrupt */
108 .org 0x800
109 HANDLE_EXCEPTION
110
111 /* D-TLB miss */
112 .org 0x900
113 HANDLE_EXCEPTION
114
115 /* I-TLB miss */
116 .org 0xa00
117 HANDLE_EXCEPTION
118
119 /* range */
120 .org 0xb00
121 HANDLE_EXCEPTION
122
123 /* system call */
124 .org 0xc00
125 HANDLE_EXCEPTION
126
127 /* floating point */
128 .org 0xd00
129 HANDLE_EXCEPTION
130
131 /* trap */
132 .org 0xe00
133 HANDLE_EXCEPTION
134
135 /* reserved */
136 .org 0xf00
137 HANDLE_EXCEPTION
138
139 .org 0x1000
140 _crt0:
141 /* Setup stack and global pointer */
142 l.movhi r1, hi(_fstack)
143 l.ori r1, r1, lo(_fstack)
144
145 /* Clear BSS */
146 l.movhi r21, hi(_fbss)
147 l.ori r21, r21, lo(_fbss)
148 l.movhi r3, hi(_ebss)
149 l.ori r3, r3, lo(_ebss)
150 .clearBSS:
151 l.sfeq r21, r3
152 l.bf .callMain
153 l.nop
154 l.sw 0(r21), r0
155 l.addi r21, r21, 4
156 l.j .clearBSS
157 l.nop
158
159 .callMain:
160 l.j main
161 l.nop
162
163 _exception_handler:
164 l.sw 0x00(r1), r2
165 l.sw 0x04(r1), r3
166 l.sw 0x08(r1), r4
167 l.sw 0x0c(r1), r5
168 l.sw 0x10(r1), r6
169 l.sw 0x14(r1), r7
170 l.sw 0x18(r1), r8
171 l.sw 0x20(r1), r10
172 l.sw 0x24(r1), r11
173 l.sw 0x28(r1), r12
174 l.sw 0x2c(r1), r13
175 l.sw 0x30(r1), r14
176 l.sw 0x34(r1), r15
177 l.sw 0x38(r1), r16
178 l.sw 0x3c(r1), r17
179 l.sw 0x40(r1), r18
180 l.sw 0x44(r1), r19
181 l.sw 0x48(r1), r20
182 l.sw 0x4c(r1), r21
183 l.sw 0x50(r1), r22
184 l.sw 0x54(r1), r23
185 l.sw 0x58(r1), r24
186 l.sw 0x5c(r1), r25
187 l.sw 0x60(r1), r26
188 l.sw 0x64(r1), r27
189 l.sw 0x68(r1), r28
190 l.sw 0x6c(r1), r29
191 l.sw 0x70(r1), r30
192 l.sw 0x74(r1), r31
193
194 /* Save return address */
195 l.or r14, r0, r9
196 /* Calculate exception vector from handler address */
197 l.andi r3, r9, 0xf00
198 l.srli r3, r3, 8
199 /* Pass saved register state */
200 l.or r4, r0, r1
201 /* Extract exception PC */
202 l.mfspr r5, r0, SPR_EPCR_BASE
203 /* Extract exception effective address */
204 l.mfspr r6, r0, SPR_EEAR_BASE
205 /* Call exception handler with the link address as argument */
206 l.jal exception_handler
207 l.nop
208
209 /* Load return address */
210 l.or r9, r0, r14
211 /* Restore state */
212 l.lwz r2, 0x00(r1)
213 l.lwz r3, 0x04(r1)
214 l.lwz r4, 0x08(r1)
215 l.lwz r5, 0x0c(r1)
216 l.lwz r6, 0x10(r1)
217 l.lwz r7, 0x14(r1)
218 l.lwz r8, 0x18(r1)
219 l.lwz r10, 0x20(r1)
220 l.lwz r11, 0x24(r1)
221 l.lwz r12, 0x28(r1)
222 l.lwz r13, 0x2c(r1)
223 l.lwz r14, 0x30(r1)
224 l.lwz r15, 0x34(r1)
225 l.lwz r16, 0x38(r1)
226 l.lwz r17, 0x3c(r1)
227 l.lwz r18, 0x40(r1)
228 l.lwz r19, 0x44(r1)
229 l.lwz r20, 0x48(r1)
230 l.lwz r21, 0x4c(r1)
231 l.lwz r22, 0x50(r1)
232 l.lwz r23, 0x54(r1)
233 l.lwz r24, 0x58(r1)
234 l.lwz r25, 0x5c(r1)
235 l.lwz r26, 0x60(r1)
236 l.lwz r27, 0x64(r1)
237 l.lwz r28, 0x68(r1)
238 l.lwz r29, 0x6c(r1)
239 l.lwz r30, 0x70(r1)
240 l.lwz r31, 0x74(r1)
241 l.jr r9
242 l.nop
243
244 .global _cache_init
245 _cache_init:
246 /*
247 This function is to be used ONLY during reset, before main() is called.
248 TODO: Perhaps break into individual enable instruction/data cache
249 sections functions, and provide disable functions, also, all
250 callable from C
251 */
252
253 /* Instruction cache enable */
254 /* Check if IC present and skip enabling otherwise */
255 #if 1
256 .L6:
257 l.mfspr r3,r0,SPR_UPR
258 l.andi r7,r3,SPR_UPR_ICP
259 l.sfeq r7,r0
260 l.bf .L8
261 l.nop
262
263 /* Disable IC */
264 l.mfspr r6,r0,SPR_SR
265 l.addi r5,r0,-1
266 l.xori r5,r5,SPR_SR_ICE
267 l.and r5,r6,r5
268 l.mtspr r0,r5,SPR_SR
269
270 /* Establish cache block size
271 If BS=0, 16;
272 If BS=1, 32;
273 r14 contain block size
274 */
275 l.mfspr r3,r0,SPR_ICCFGR
276 l.andi r7,r3,SPR_ICCFGR_CBS
277 l.srli r8,r7,7
278 l.ori r4,r0,16
279 l.sll r14,r4,r8
280
281 /* Establish number of cache sets
282 r10 contains number of cache sets
283 r8 contains log(# of cache sets)
284 */
285 l.andi r7,r3,SPR_ICCFGR_NCS
286 l.srli r8,r7,3
287 l.ori r4,r0,1
288 l.sll r10,r4,r8
289
290 /* Invalidate IC */
291 l.addi r6,r0,0
292 l.sll r5,r14,r8
293
294 .L7: l.mtspr r0,r6,SPR_ICBIR
295 l.sfne r6,r5
296 l.bf .L7
297 l.add r6,r6,r14
298
299 /* Enable IC */
300 l.mfspr r6,r0,SPR_SR
301 l.ori r6,r6,SPR_SR_ICE
302 l.mtspr r0,r6,SPR_SR
303 l.nop
304 l.nop
305 l.nop
306 l.nop
307 l.nop
308 l.nop
309 l.nop
310 l.nop
311 /* Data cache enable */
312 /* Check if DC present and skip enabling otherwise */
313 #endif
314 .L8:
315 #if 1
316 l.mfspr r3,r0,SPR_UPR
317 l.andi r7,r3,SPR_UPR_DCP
318 l.sfeq r7,r0
319 l.bf .L10
320 l.nop
321 /* Disable DC */
322 l.mfspr r6,r0,SPR_SR
323 l.addi r5,r0,-1
324 l.xori r5,r5,SPR_SR_DCE
325 l.and r5,r6,r5
326 l.mtspr r0,r5,SPR_SR
327 /* Establish cache block size
328 If BS=0, 16;
329 If BS=1, 32;
330 r14 contain block size
331 */
332 l.mfspr r3,r0,SPR_DCCFGR
333 l.andi r7,r3,SPR_DCCFGR_CBS
334 l.srli r8,r7,7
335 l.ori r4,r0,16
336 l.sll r14,r4,r8
337 /* Establish number of cache sets
338 r10 contains number of cache sets
339 r8 contains log(# of cache sets)
340 */
341 l.andi r7,r3,SPR_DCCFGR_NCS
342 l.srli r8,r7,3
343 l.ori r4,r0,1
344 l.sll r10,r4,r8
345 /* Invalidate DC */
346 l.addi r6,r0,0
347 l.sll r5,r14,r8
348
349 .L9:
350 l.mtspr r0,r6,SPR_DCBIR
351 l.sfne r6,r5
352 l.bf .L9
353 l.add r6,r6,r14
354 /* Enable DC */
355 l.mfspr r6,r0,SPR_SR
356 l.ori r6,r6,SPR_SR_DCE
357 l.mtspr r0,r6,SPR_SR
358 #endif
359 .L10:
360 /* Return */
361 l.jr r9
362 l.nop