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