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
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_TEXT_BASE:
87 .word TEXT_BASE
88
89.globl _armboot_start
90_armboot_start:
91 .word _start
92
93
94
95
96.globl _bss_start
97_bss_start:
98 .word __bss_start
99
100.globl _bss_end
101_bss_end:
102 .word _end
103
104#ifdef CONFIG_USE_IRQ
105
106.globl IRQ_STACK_START
107IRQ_STACK_START:
108 .word 0x0badc0de
109
110
111.globl FIQ_STACK_START
112FIQ_STACK_START:
113 .word 0x0badc0de
114#endif
115
116
117
118
119
120.globl reset
121reset:
122
123
124
125 mrs r0,cpsr
126 bic r0,r0,
127 orr r0,r0,
128 msr cpsr,r0
129
130
131
132
133
134#ifndef CONFIG_SKIP_LOWLEVEL_INIT
135 bl cpu_init_crit
136#endif
137
138relocate:
139 adr r0, _start
140 ldr r1, _TEXT_BASE
141 cmp r0, r1
142 beq stack_setup
143
144 ldr r2, _armboot_start
145 ldr r3, _bss_start
146 sub r2, r3, r2
147 add r2, r0, r2
148
149copy_loop:
150 ldmia r0!, {r3-r10}
151 stmia r1!, {r3-r10}
152 cmp r0, r2
153 ble copy_loop
154
155
156stack_setup:
157 ldr r0, _TEXT_BASE
158 sub r0, r0,
159 sub r0, r0,
160#ifdef CONFIG_USE_IRQ
161 sub r0, r0,
162#endif
163 sub sp, r0,
164 bic sp, sp,
165
166clear_bss:
167 ldr r0, _bss_start
168 ldr r1, _bss_end
169 mov r2,
170
171clbss_l:str r2, [r0]
172 add r0, r0,
173 cmp r0, r1
174 ble clbss_l
175
176 ldr pc, _start_armboot
177
178_start_armboot:
179 .word start_armboot
180
181
182
183
184
185
186
187
188
189
190
191
192#ifndef CONFIG_SKIP_LOWLEVEL_INIT
193cpu_init_crit:
194
195
196
197 mov pc, lr
198#endif
199
200
201
202
203
204
205
206
207@
208@ IRQ stack frame.
209@
210#define S_FRAME_SIZE 72
211
212#define S_OLD_R0 68
213#define S_PSR 64
214#define S_PC 60
215#define S_LR 56
216#define S_SP 52
217
218#define S_IP 48
219#define S_FP 44
220#define S_R10 40
221#define S_R9 36
222#define S_R8 32
223#define S_R7 28
224#define S_R6 24
225#define S_R5 20
226#define S_R4 16
227#define S_R3 12
228#define S_R2 8
229#define S_R1 4
230#define S_R0 0
231
232#define MODE_SVC 0x13
233#define I_BIT 0x80
234
235
236
237
238
239
240 .macro bad_save_user_regs
241 @ carve out a frame on current user stack
242 sub sp, sp,
243 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
244
245 ldr r2, _armboot_start
246 sub r2, r2,
247 sub r2, r2,
248 @ get values for "aborted" pc and cpsr (into parm regs)
249 ldmia r2, {r2 - r3}
250 add r0, sp,
251 add r5, sp,
252 mov r1, lr
253 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
254 mov r0, sp @ save current stack into r0 (param register)
255 .endm
256
257 .macro irq_save_user_regs
258 sub sp, sp,
259 stmia sp, {r0 - r12} @ Calling r0-r12
260 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
261 add r8, sp,
262 stmdb r8, {sp, lr}^ @ Calling SP, LR
263 str lr, [r8,
264 mrs r6, spsr
265 str r6, [r8,
266 str r0, [r8,
267 mov r0, sp
268 .endm
269
270 .macro irq_restore_user_regs
271 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
272 mov r0, r0
273 ldr lr, [sp,
274 add sp, sp,
275 subs pc, lr,
276 .endm
277
278 .macro get_bad_stack
279 ldr r13, _armboot_start @ setup our mode stack
280 sub r13, r13,
281 sub r13, r13,
282
283 str lr, [r13] @ save caller lr in position 0 of saved stack
284 mrs lr, spsr @ get the spsr
285 str lr, [r13,
286 mov r13,
287 @ msr spsr_c, r13
288 msr spsr, r13 @ switch modes, make sure moves will execute
289 mov lr, pc @ capture return pc
290 movs pc, lr @ jump to next instruction & switch modes.
291 .endm
292
293 .macro get_irq_stack @ setup IRQ stack
294 ldr sp, IRQ_STACK_START
295 .endm
296
297 .macro get_fiq_stack @ setup FIQ stack
298 ldr sp, FIQ_STACK_START
299 .endm
300
301
302
303
304 .align 5
305.globl undefined_instruction
306undefined_instruction:
307 get_bad_stack
308 bad_save_user_regs
309 bl do_undefined_instruction
310
311 .align 5
312.globl software_interrupt
313software_interrupt:
314 get_bad_stack
315 bad_save_user_regs
316 bl do_software_interrupt
317
318 .align 5
319.globl prefetch_abort
320prefetch_abort:
321 get_bad_stack
322 bad_save_user_regs
323 bl do_prefetch_abort
324
325 .align 5
326.globl data_abort
327data_abort:
328 get_bad_stack
329 bad_save_user_regs
330 bl do_data_abort
331
332 .align 5
333.globl not_used
334not_used:
335 get_bad_stack
336 bad_save_user_regs
337 bl do_not_used
338
339#ifdef CONFIG_USE_IRQ
340 .align 5
341.globl irq
342irq:
343 get_irq_stack
344 irq_save_user_regs
345 bl do_irq
346 irq_restore_user_regs
347
348 .align 5
349.globl fiq
350fiq:
351 get_fiq_stack
352
353 irq_save_user_regs
354 bl do_fiq
355 irq_restore_user_regs
356
357#else
358
359 .align 5
360.globl irq
361irq:
362 get_bad_stack
363 bad_save_user_regs
364 bl do_irq
365
366 .align 5
367.globl fiq
368fiq:
369 get_bad_stack
370 bad_save_user_regs
371 bl do_fiq
372
373#endif
374