]>
Commit | Line | Data |
---|---|---|
6f21347d WD |
1 | /* |
2 | * armboot - Startup Code for ARM926EJS CPU-core | |
3 | * | |
4 | * Copyright (c) 2003 Texas Instruments | |
5 | * | |
a56bd922 | 6 | * ----- Adapted for OMAP1610 OMAP730 from ARM925t code ------ |
6f21347d | 7 | * |
fa82f871 AA |
8 | * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> |
9 | * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> | |
792a09eb | 10 | * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> |
6f21347d WD |
11 | * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> |
12 | * Copyright (c) 2003 Kshitij <kshitij@ti.com> | |
57b4bce9 | 13 | * Copyright (c) 2010 Albert Aribaud <albert.u.boot@aribaud.net> |
6f21347d | 14 | * |
1a459660 | 15 | * SPDX-License-Identifier: GPL-2.0+ |
6f21347d WD |
16 | */ |
17 | ||
25ddd1fb | 18 | #include <asm-offsets.h> |
6f21347d | 19 | #include <config.h> |
fcd3c87e | 20 | #include <common.h> |
6f21347d WD |
21 | #include <version.h> |
22 | ||
6f21347d WD |
23 | /* |
24 | ************************************************************************* | |
25 | * | |
26 | * Jump vector table as in table 3.1 in [1] | |
27 | * | |
28 | ************************************************************************* | |
29 | */ | |
30 | ||
31 | ||
337c4333 | 32 | #ifdef CONFIG_SYS_DV_NOR_BOOT_CFG |
6f21347d WD |
33 | .globl _start |
34 | _start: | |
337c4333 HS |
35 | .globl _NOR_BOOT_CFG |
36 | _NOR_BOOT_CFG: | |
37 | .word CONFIG_SYS_DV_NOR_BOOT_CFG | |
6f21347d | 38 | b reset |
337c4333 HS |
39 | #else |
40 | .globl _start | |
41 | _start: | |
42 | b reset | |
43 | #endif | |
401bb30b | 44 | #ifdef CONFIG_SPL_BUILD |
ef22b503 JR |
45 | /* No exception handlers in preloader */ |
46 | ldr pc, _hang | |
47 | ldr pc, _hang | |
48 | ldr pc, _hang | |
49 | ldr pc, _hang | |
50 | ldr pc, _hang | |
51 | ldr pc, _hang | |
52 | ldr pc, _hang | |
53 | ||
54 | _hang: | |
55 | .word do_hang | |
56 | /* pad to 64 byte boundary */ | |
57 | .word 0x12345678 | |
58 | .word 0x12345678 | |
59 | .word 0x12345678 | |
60 | .word 0x12345678 | |
61 | .word 0x12345678 | |
62 | .word 0x12345678 | |
63 | .word 0x12345678 | |
64 | #else | |
6f21347d WD |
65 | ldr pc, _undefined_instruction |
66 | ldr pc, _software_interrupt | |
67 | ldr pc, _prefetch_abort | |
68 | ldr pc, _data_abort | |
69 | ldr pc, _not_used | |
70 | ldr pc, _irq | |
71 | ldr pc, _fiq | |
72 | ||
73 | _undefined_instruction: | |
74 | .word undefined_instruction | |
75 | _software_interrupt: | |
76 | .word software_interrupt | |
77 | _prefetch_abort: | |
78 | .word prefetch_abort | |
79 | _data_abort: | |
80 | .word data_abort | |
81 | _not_used: | |
82 | .word not_used | |
83 | _irq: | |
84 | .word irq | |
85 | _fiq: | |
86 | .word fiq | |
87 | ||
401bb30b | 88 | #endif /* CONFIG_SPL_BUILD */ |
6f21347d WD |
89 | .balignl 16,0xdeadbeef |
90 | ||
91 | ||
92 | /* | |
93 | ************************************************************************* | |
94 | * | |
95 | * Startup Code (reset vector) | |
96 | * | |
97 | * do important init only if we don't start from memory! | |
98 | * setup Memory and board specific bits prior to relocation. | |
99 | * relocate armboot to ram | |
100 | * setup stack | |
101 | * | |
102 | ************************************************************************* | |
103 | */ | |
104 | ||
ab86f72c | 105 | .globl _TEXT_BASE |
6f21347d | 106 | _TEXT_BASE: |
508611bc | 107 | #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE) |
435199f3 HS |
108 | .word CONFIG_SPL_TEXT_BASE |
109 | #else | |
110 | .word CONFIG_SYS_TEXT_BASE | |
111 | #endif | |
6f21347d | 112 | |
6f21347d | 113 | /* |
f6e20fc6 | 114 | * These are defined in the board-specific linker script. |
92d5ecba AA |
115 | * Subtracting _start from them lets the linker put their |
116 | * relative position in the executable instead of leaving | |
117 | * them null. | |
6f21347d | 118 | */ |
92d5ecba AA |
119 | .globl _bss_start_ofs |
120 | _bss_start_ofs: | |
121 | .word __bss_start - _start | |
f6e20fc6 | 122 | |
92d5ecba AA |
123 | .globl _bss_end_ofs |
124 | _bss_end_ofs: | |
3929fb0a | 125 | .word __bss_end - _start |
6f21347d | 126 | |
f326cbba PYC |
127 | .globl _end_ofs |
128 | _end_ofs: | |
129 | .word _end - _start | |
130 | ||
6f21347d WD |
131 | #ifdef CONFIG_USE_IRQ |
132 | /* IRQ stack memory (calculated at run-time) */ | |
133 | .globl IRQ_STACK_START | |
134 | IRQ_STACK_START: | |
135 | .word 0x0badc0de | |
136 | ||
137 | /* IRQ stack memory (calculated at run-time) */ | |
138 | .globl FIQ_STACK_START | |
139 | FIQ_STACK_START: | |
140 | .word 0x0badc0de | |
141 | #endif | |
142 | ||
ab86f72c HS |
143 | /* IRQ stack memory (calculated at run-time) + 8 bytes */ |
144 | .globl IRQ_STACK_START_IN | |
145 | IRQ_STACK_START_IN: | |
146 | .word 0x0badc0de | |
147 | ||
6f21347d WD |
148 | /* |
149 | * the actual reset code | |
150 | */ | |
151 | ||
152 | reset: | |
153 | /* | |
154 | * set the cpu to SVC32 mode | |
155 | */ | |
156 | mrs r0,cpsr | |
157 | bic r0,r0,#0x1f | |
158 | orr r0,r0,#0xd3 | |
159 | msr cpsr,r0 | |
160 | ||
6f21347d | 161 | /* |
a8c7c708 WD |
162 | * we do sys-critical inits only at reboot, |
163 | * not when booting from ram! | |
6f21347d | 164 | */ |
27b66622 | 165 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT |
a8c7c708 | 166 | bl cpu_init_crit |
27b66622 | 167 | #endif |
a8c7c708 | 168 | |
e05e5de7 | 169 | bl _main |
ab86f72c HS |
170 | |
171 | /*------------------------------------------------------------------------------*/ | |
172 | ||
e05e5de7 AA |
173 | .globl c_runtime_cpu_setup |
174 | c_runtime_cpu_setup: | |
175 | ||
176 | bx lr | |
177 | ||
6f21347d WD |
178 | /* |
179 | ************************************************************************* | |
180 | * | |
181 | * CPU_init_critical registers | |
182 | * | |
183 | * setup important registers | |
184 | * setup memory timing | |
185 | * | |
186 | ************************************************************************* | |
187 | */ | |
27b66622 | 188 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT |
6f21347d WD |
189 | cpu_init_crit: |
190 | /* | |
da104e04 | 191 | * flush D cache before disabling it |
6f21347d WD |
192 | */ |
193 | mov r0, #0 | |
da104e04 SG |
194 | flush_dcache: |
195 | mrc p15, 0, r15, c7, c10, 3 | |
196 | bne flush_dcache | |
197 | ||
198 | mcr p15, 0, r0, c8, c7, 0 /* invalidate TLB */ | |
199 | mcr p15, 0, r0, c7, c5, 0 /* invalidate I Cache */ | |
6f21347d WD |
200 | |
201 | /* | |
d735a99d CR |
202 | * disable MMU and D cache |
203 | * enable I cache if CONFIG_SYS_ICACHE_OFF is not defined | |
6f21347d WD |
204 | */ |
205 | mrc p15, 0, r0, c1, c0, 0 | |
b67d8816 | 206 | bic r0, r0, #0x00000300 /* clear bits 9:8 (---- --RS) */ |
6f21347d | 207 | bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ |
b67d8816 CR |
208 | #ifdef CONFIG_SYS_EXCEPTION_VECTORS_HIGH |
209 | orr r0, r0, #0x00002000 /* set bit 13 (--V- ----) */ | |
210 | #else | |
211 | bic r0, r0, #0x00002000 /* clear bit 13 (--V- ----) */ | |
212 | #endif | |
6f21347d | 213 | orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ |
d735a99d | 214 | #ifndef CONFIG_SYS_ICACHE_OFF |
6f21347d | 215 | orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ |
d735a99d | 216 | #endif |
6f21347d WD |
217 | mcr p15, 0, r0, c1, c0, 0 |
218 | ||
219 | /* | |
220 | * Go setup Memory and board specific bits prior to relocation. | |
221 | */ | |
222 | mov ip, lr /* perserve link reg across call */ | |
87cb6862 | 223 | bl lowlevel_init /* go setup pll,mux,memory */ |
6f21347d | 224 | mov lr, ip /* restore link */ |
ca4b5580 | 225 | mov pc, lr /* back to my caller */ |
27b66622 | 226 | #endif /* CONFIG_SKIP_LOWLEVEL_INIT */ |
a6cdd21b | 227 | |
401bb30b | 228 | #ifndef CONFIG_SPL_BUILD |
6f21347d WD |
229 | /* |
230 | ************************************************************************* | |
231 | * | |
232 | * Interrupt handling | |
233 | * | |
234 | ************************************************************************* | |
235 | */ | |
236 | ||
237 | @ | |
238 | @ IRQ stack frame. | |
239 | @ | |
240 | #define S_FRAME_SIZE 72 | |
241 | ||
242 | #define S_OLD_R0 68 | |
243 | #define S_PSR 64 | |
244 | #define S_PC 60 | |
245 | #define S_LR 56 | |
246 | #define S_SP 52 | |
247 | ||
248 | #define S_IP 48 | |
249 | #define S_FP 44 | |
250 | #define S_R10 40 | |
251 | #define S_R9 36 | |
252 | #define S_R8 32 | |
253 | #define S_R7 28 | |
254 | #define S_R6 24 | |
255 | #define S_R5 20 | |
256 | #define S_R4 16 | |
257 | #define S_R3 12 | |
258 | #define S_R2 8 | |
259 | #define S_R1 4 | |
260 | #define S_R0 0 | |
261 | ||
262 | #define MODE_SVC 0x13 | |
263 | #define I_BIT 0x80 | |
264 | ||
265 | /* | |
266 | * use bad_save_user_regs for abort/prefetch/undef/swi ... | |
267 | * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling | |
268 | */ | |
269 | ||
270 | .macro bad_save_user_regs | |
271 | @ carve out a frame on current user stack | |
272 | sub sp, sp, #S_FRAME_SIZE | |
273 | stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 | |
ab86f72c | 274 | ldr r2, IRQ_STACK_START_IN |
6f21347d WD |
275 | @ get values for "aborted" pc and cpsr (into parm regs) |
276 | ldmia r2, {r2 - r3} | |
277 | add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack | |
278 | add r5, sp, #S_SP | |
279 | mov r1, lr | |
280 | stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr | |
281 | mov r0, sp @ save current stack into r0 (param register) | |
282 | .endm | |
283 | ||
284 | .macro irq_save_user_regs | |
285 | sub sp, sp, #S_FRAME_SIZE | |
286 | stmia sp, {r0 - r12} @ Calling r0-r12 | |
287 | @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. | |
288 | add r8, sp, #S_PC | |
289 | stmdb r8, {sp, lr}^ @ Calling SP, LR | |
290 | str lr, [r8, #0] @ Save calling PC | |
291 | mrs r6, spsr | |
292 | str r6, [r8, #4] @ Save CPSR | |
293 | str r0, [r8, #8] @ Save OLD_R0 | |
294 | mov r0, sp | |
295 | .endm | |
296 | ||
297 | .macro irq_restore_user_regs | |
298 | ldmia sp, {r0 - lr}^ @ Calling r0 - lr | |
299 | mov r0, r0 | |
300 | ldr lr, [sp, #S_PC] @ Get PC | |
301 | add sp, sp, #S_FRAME_SIZE | |
302 | subs pc, lr, #4 @ return & move spsr_svc into cpsr | |
303 | .endm | |
304 | ||
305 | .macro get_bad_stack | |
ab86f72c | 306 | ldr r13, IRQ_STACK_START_IN @ setup our mode stack |
6f21347d WD |
307 | |
308 | str lr, [r13] @ save caller lr in position 0 of saved stack | |
309 | mrs lr, spsr @ get the spsr | |
310 | str lr, [r13, #4] @ save spsr in position 1 of saved stack | |
311 | mov r13, #MODE_SVC @ prepare SVC-Mode | |
312 | @ msr spsr_c, r13 | |
313 | msr spsr, r13 @ switch modes, make sure moves will execute | |
314 | mov lr, pc @ capture return pc | |
315 | movs pc, lr @ jump to next instruction & switch modes. | |
316 | .endm | |
317 | ||
318 | .macro get_irq_stack @ setup IRQ stack | |
319 | ldr sp, IRQ_STACK_START | |
320 | .endm | |
321 | ||
322 | .macro get_fiq_stack @ setup FIQ stack | |
323 | ldr sp, FIQ_STACK_START | |
324 | .endm | |
401bb30b | 325 | #endif /* CONFIG_SPL_BUILD */ |
6f21347d WD |
326 | |
327 | /* | |
328 | * exception handlers | |
329 | */ | |
401bb30b | 330 | #ifdef CONFIG_SPL_BUILD |
ef22b503 JR |
331 | .align 5 |
332 | do_hang: | |
333 | ldr sp, _TEXT_BASE /* switch to abort stack */ | |
334 | 1: | |
335 | bl 1b /* hang and never return */ | |
401bb30b | 336 | #else /* !CONFIG_SPL_BUILD */ |
6f21347d WD |
337 | .align 5 |
338 | undefined_instruction: | |
339 | get_bad_stack | |
340 | bad_save_user_regs | |
341 | bl do_undefined_instruction | |
342 | ||
343 | .align 5 | |
344 | software_interrupt: | |
345 | get_bad_stack | |
346 | bad_save_user_regs | |
347 | bl do_software_interrupt | |
348 | ||
349 | .align 5 | |
350 | prefetch_abort: | |
351 | get_bad_stack | |
352 | bad_save_user_regs | |
353 | bl do_prefetch_abort | |
354 | ||
355 | .align 5 | |
356 | data_abort: | |
357 | get_bad_stack | |
358 | bad_save_user_regs | |
359 | bl do_data_abort | |
360 | ||
361 | .align 5 | |
362 | not_used: | |
363 | get_bad_stack | |
364 | bad_save_user_regs | |
365 | bl do_not_used | |
366 | ||
367 | #ifdef CONFIG_USE_IRQ | |
368 | ||
369 | .align 5 | |
370 | irq: | |
371 | get_irq_stack | |
372 | irq_save_user_regs | |
53677ef1 | 373 | bl do_irq |
6f21347d WD |
374 | irq_restore_user_regs |
375 | ||
376 | .align 5 | |
377 | fiq: | |
378 | get_fiq_stack | |
379 | /* someone ought to write a more effiction fiq_save_user_regs */ | |
380 | irq_save_user_regs | |
53677ef1 | 381 | bl do_fiq |
6f21347d WD |
382 | irq_restore_user_regs |
383 | ||
384 | #else | |
385 | ||
386 | .align 5 | |
387 | irq: | |
388 | get_bad_stack | |
389 | bad_save_user_regs | |
390 | bl do_irq | |
391 | ||
392 | .align 5 | |
393 | fiq: | |
394 | get_bad_stack | |
395 | bad_save_user_regs | |
396 | bl do_fiq | |
397 | ||
398 | #endif | |
401bb30b | 399 | #endif /* CONFIG_SPL_BUILD */ |