]> git.ipfire.org Git - thirdparty/u-boot.git/blame - arch/arm/cpu/arm1136/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[thirdparty/u-boot.git] / arch / arm / cpu / arm1136 / start.S
CommitLineData
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
102IRQ_STACK_START:
103 .word 0x0badc0de
104
105/* IRQ stack memory (calculated at run-time) */
106.globl FIQ_STACK_START
107FIQ_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
113IRQ_STACK_START_IN:
114 .word 0x0badc0de
e48b7c0a 115
e48b7c0a
HS
116/*
117 * the actual reset code
118 */
119
120reset:
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
139c_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
154cpu_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
297do_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
302undefined_instruction:
303 get_bad_stack
304 bad_save_user_regs
082acfd4 305 bl do_undefined_instruction
8ed96046
WD
306
307 .align 5
308software_interrupt:
309 get_bad_stack_swi
310 bad_save_user_regs
082acfd4 311 bl do_software_interrupt
8ed96046
WD
312
313 .align 5
314prefetch_abort:
315 get_bad_stack
316 bad_save_user_regs
082acfd4 317 bl do_prefetch_abort
8ed96046
WD
318
319 .align 5
320data_abort:
321 get_bad_stack
322 bad_save_user_regs
082acfd4 323 bl do_data_abort
8ed96046
WD
324
325 .align 5
326not_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
334irq:
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
341fiq:
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
351irq:
352 get_bad_stack
353 bad_save_user_regs
082acfd4 354 bl do_irq
8ed96046
WD
355
356 .align 5
357fiq:
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
365arm1136_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 */