1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33#include <asm-offsets.h>
34#include <config.h>
35#include <version.h>
36
37
38
39
40
41
42
43
44
45.globl _start
46_start:
47 b reset
48 ldr pc, _undefined_instruction
49 ldr pc, _software_interrupt
50 ldr pc, _prefetch_abort
51 ldr pc, _data_abort
52 ldr pc, _not_used
53 ldr pc, _irq
54 ldr pc, _fiq
55
56_undefined_instruction:
57 .word undefined_instruction
58_software_interrupt:
59 .word software_interrupt
60_prefetch_abort:
61 .word prefetch_abort
62_data_abort:
63 .word data_abort
64_not_used:
65 .word not_used
66_irq:
67 .word irq
68_fiq:
69 .word fiq
70
71 .balignl 16,0xdeadbeef
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86.globl _TEXT_BASE
87_TEXT_BASE:
88
89 .word CONFIG_SPL_TEXT_BASE
90#else
91 .word CONFIG_SYS_TEXT_BASE
92#endif
93
94
95
96
97
98
99
100.globl _bss_start_ofs
101_bss_start_ofs:
102 .word __bss_start - _start
103
104.globl _image_copy_end_ofs
105_image_copy_end_ofs:
106 .word __image_copy_end - _start
107
108.globl _bss_end_ofs
109_bss_end_ofs:
110 .word __bss_end - _start
111
112.globl _end_ofs
113_end_ofs:
114 .word _end - _start
115
116#ifdef CONFIG_USE_IRQ
117
118.globl IRQ_STACK_START
119IRQ_STACK_START:
120 .word 0x0badc0de
121
122
123.globl FIQ_STACK_START
124FIQ_STACK_START:
125 .word 0x0badc0de
126#endif
127
128
129.globl IRQ_STACK_START_IN
130IRQ_STACK_START_IN:
131 .word 0x0badc0de
132
133
134
135
136
137reset:
138
139
140
141 mrs r0,cpsr
142 bic r0,r0,
143 orr r0,r0,
144 msr cpsr,r0
145
146
147
148
149
150#ifndef CONFIG_SKIP_LOWLEVEL_INIT
151 bl cpu_init_crit
152#endif
153
154 bl _main
155
156
157
158
159
160
161
162
163 .globl relocate_code
164relocate_code:
165 mov r6, r0
166
167 adr r0, _start
168 subs r9, r6, r0
169 beq relocate_done
170 mov r1, r6
171 ldr r3, _image_copy_end_ofs
172 add r2, r0, r3
173
174copy_loop:
175 ldmia r0!, {r10-r11}
176 stmia r1!, {r10-r11}
177 cmp r0, r2
178 blo copy_loop
179
180#ifndef CONFIG_SPL_BUILD
181
182
183
184 ldr r0, _TEXT_BASE
185 ldr r10, _dynsym_start_ofs
186 add r10, r10, r0
187 ldr r2, _rel_dyn_start_ofs
188 add r2, r2, r0
189 ldr r3, _rel_dyn_end_ofs
190 add r3, r3, r0
191fixloop:
192 ldr r0, [r2]
193 add r0, r0, r9
194 ldr r1, [r2,
195 and r7, r1,
196 cmp r7,
197 beq fixrel
198 cmp r7,
199 beq fixabs
200
201 b fixnext
202fixabs:
203
204 mov r1, r1, LSR
205 add r1, r10, r1
206 ldr r1, [r1,
207 add r1, r1, r9
208 b fixnext
209fixrel:
210
211 ldr r1, [r0]
212 add r1, r1, r9
213fixnext:
214 str r1, [r0]
215 add r2, r2,
216 cmp r2, r3
217 blo fixloop
218#endif
219
220relocate_done:
221
222 bx lr
223
224_rel_dyn_start_ofs:
225 .word __rel_dyn_start - _start
226_rel_dyn_end_ofs:
227 .word __rel_dyn_end - _start
228_dynsym_start_ofs:
229 .word __dynsym_start - _start
230
231 .globl c_runtime_cpu_setup
232c_runtime_cpu_setup:
233
234 mov pc, lr
235
236
237
238
239
240
241
242
243
244
245
246
247#ifndef CONFIG_SKIP_LOWLEVEL_INIT
248cpu_init_crit:
249
250
251
252 mov pc, lr
253#endif
254
255
256
257
258
259
260
261
262@
263@ IRQ stack frame.
264@
265#define S_FRAME_SIZE 72
266
267#define S_OLD_R0 68
268#define S_PSR 64
269#define S_PC 60
270#define S_LR 56
271#define S_SP 52
272
273#define S_IP 48
274#define S_FP 44
275#define S_R10 40
276#define S_R9 36
277#define S_R8 32
278#define S_R7 28
279#define S_R6 24
280#define S_R5 20
281#define S_R4 16
282#define S_R3 12
283#define S_R2 8
284#define S_R1 4
285#define S_R0 0
286
287#define MODE_SVC 0x13
288#define I_BIT 0x80
289
290
291
292
293
294
295 .macro bad_save_user_regs
296 @ carve out a frame on current user stack
297 sub sp, sp,
298 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
299
300 ldr r2, IRQ_STACK_START_IN
301 @ get values for "aborted" pc and cpsr (into parm regs)
302 ldmia r2, {r2 - r3}
303 add r0, sp,
304 add r5, sp,
305 mov r1, lr
306 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
307 mov r0, sp @ save current stack into r0 (param register)
308 .endm
309
310 .macro irq_save_user_regs
311 sub sp, sp,
312 stmia sp, {r0 - r12} @ Calling r0-r12
313 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
314 add r8, sp,
315 stmdb r8, {sp, lr}^ @ Calling SP, LR
316 str lr, [r8,
317 mrs r6, spsr
318 str r6, [r8,
319 str r0, [r8,
320 mov r0, sp
321 .endm
322
323 .macro irq_restore_user_regs
324 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
325 mov r0, r0
326 ldr lr, [sp,
327 add sp, sp,
328 subs pc, lr,
329 .endm
330
331 .macro get_bad_stack
332 ldr r13, IRQ_STACK_START_IN @ setup our mode stack
333
334 str lr, [r13] @ save caller lr in position 0 of saved stack
335 mrs lr, spsr @ get the spsr
336 str lr, [r13,
337 mov r13,
338 @ msr spsr_c, r13
339 msr spsr, r13 @ switch modes, make sure moves will execute
340 mov lr, pc @ capture return pc
341 movs pc, lr @ jump to next instruction & switch modes.
342 .endm
343
344 .macro get_irq_stack @ setup IRQ stack
345 ldr sp, IRQ_STACK_START
346 .endm
347
348 .macro get_fiq_stack @ setup FIQ stack
349 ldr sp, FIQ_STACK_START
350 .endm
351
352
353
354
355 .align 5
356.globl undefined_instruction
357undefined_instruction:
358 get_bad_stack
359 bad_save_user_regs
360 bl do_undefined_instruction
361
362 .align 5
363.globl software_interrupt
364software_interrupt:
365 get_bad_stack
366 bad_save_user_regs
367 bl do_software_interrupt
368
369 .align 5
370.globl prefetch_abort
371prefetch_abort:
372 get_bad_stack
373 bad_save_user_regs
374 bl do_prefetch_abort
375
376 .align 5
377.globl data_abort
378data_abort:
379 get_bad_stack
380 bad_save_user_regs
381 bl do_data_abort
382
383 .align 5
384.globl not_used
385not_used:
386 get_bad_stack
387 bad_save_user_regs
388 bl do_not_used
389
390#ifdef CONFIG_USE_IRQ
391 .align 5
392.globl irq
393irq:
394 get_irq_stack
395 irq_save_user_regs
396 bl do_irq
397 irq_restore_user_regs
398
399 .align 5
400.globl fiq
401fiq:
402 get_fiq_stack
403
404 irq_save_user_regs
405 bl do_fiq
406 irq_restore_user_regs
407
408#else
409
410 .align 5
411.globl irq
412irq:
413 get_bad_stack
414 bad_save_user_regs
415 bl do_irq
416
417 .align 5
418.globl fiq
419fiq:
420 get_bad_stack
421 bad_save_user_regs
422 bl do_fiq
423
424#endif
425