]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/arm/cpu/arm925t/start.S
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / arch / arm / cpu / arm925t / start.S
CommitLineData
2e5983d2
WD
1/*
2 * armboot - Startup Code for ARM925 CPU-core
3 *
4 * Copyright (c) 2003 Texas Instruments
5 *
6 * ----- Adapted for OMAP1510 from ARM920 code ------
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>
2e5983d2 11 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com>
53677ef1 12 * Copyright (c) 2003 Kshitij <kshitij@ti.com>
2e5983d2 13 *
1a459660 14 * SPDX-License-Identifier: GPL-2.0+
2e5983d2
WD
15 */
16
25ddd1fb 17#include <asm-offsets.h>
2e5983d2
WD
18#include <config.h>
19#include <version.h>
20
2e5983d2
WD
21/*
22 *************************************************************************
23 *
24 * Jump vector table as in table 3.1 in [1]
25 *
26 *************************************************************************
27 */
28
29
30.globl _start
31_start: b reset
32 ldr pc, _undefined_instruction
33 ldr pc, _software_interrupt
34 ldr pc, _prefetch_abort
35 ldr pc, _data_abort
36 ldr pc, _not_used
37 ldr pc, _irq
38 ldr pc, _fiq
39
40_undefined_instruction: .word undefined_instruction
41_software_interrupt: .word software_interrupt
42_prefetch_abort: .word prefetch_abort
43_data_abort: .word data_abort
44_not_used: .word not_used
45_irq: .word irq
46_fiq: .word fiq
47
48 .balignl 16,0xdeadbeef
49
50
51/*
52 *************************************************************************
53 *
54 * Startup Code (reset vector)
55 *
56 * do important init only if we don't start from memory!
57 * setup Memory and board specific bits prior to relocation.
58 * relocate armboot to ram
59 * setup stack
60 *
61 *************************************************************************
62 */
63
405d023b 64.globl _TEXT_BASE
2e5983d2 65_TEXT_BASE:
508611bc
BT
66#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
67 .word CONFIG_SPL_TEXT_BASE
68#else
14d0a02a 69 .word CONFIG_SYS_TEXT_BASE
508611bc 70#endif
2e5983d2 71
2e5983d2 72/*
f6e20fc6 73 * These are defined in the board-specific linker script.
3336ca60
AA
74 * Subtracting _start from them lets the linker put their
75 * relative position in the executable instead of leaving
76 * them null.
2e5983d2 77 */
3336ca60
AA
78.globl _bss_start_ofs
79_bss_start_ofs:
80 .word __bss_start - _start
f6e20fc6 81
3336ca60
AA
82.globl _bss_end_ofs
83_bss_end_ofs:
3929fb0a 84 .word __bss_end - _start
2e5983d2 85
f326cbba
PYC
86.globl _end_ofs
87_end_ofs:
88 .word _end - _start
89
2e5983d2
WD
90#ifdef CONFIG_USE_IRQ
91/* IRQ stack memory (calculated at run-time) */
92.globl IRQ_STACK_START
93IRQ_STACK_START:
94 .word 0x0badc0de
95
96/* IRQ stack memory (calculated at run-time) */
97.globl FIQ_STACK_START
98FIQ_STACK_START:
99 .word 0x0badc0de
100#endif
101
405d023b
HS
102/* IRQ stack memory (calculated at run-time) + 8 bytes */
103.globl IRQ_STACK_START_IN
104IRQ_STACK_START_IN:
105 .word 0x0badc0de
106
405d023b
HS
107/*
108 * the actual reset code
109 */
110
111reset:
112 /*
113 * set the cpu to SVC32 mode
114 */
115 mrs r0,cpsr
116 bic r0,r0,#0x1f
117 orr r0,r0,#0xd3
118 msr cpsr,r0
119
120 /*
121 * Set up 925T mode
122 */
123 mov r1, #0x81 /* Set ARM925T configuration. */
124 mcr p15, 0, r1, c15, c1, 0 /* Write ARM925T configuration register. */
125
126 /*
127 * turn off the watchdog, unlock/diable sequence
128 */
129 mov r1, #0xF5
130 ldr r0, =WDTIM_MODE
131 strh r1, [r0]
132 mov r1, #0xA0
133 strh r1, [r0]
134
135 /*
136 * mask all IRQs by setting all bits in the INTMR - default
137 */
138 mov r1, #0xffffffff
139 ldr r0, =REG_IHL1_MIR
140 str r1, [r0]
141 ldr r0, =REG_IHL2_MIR
142 str r1, [r0]
143
144 /*
145 * wait for dpll to lock
146 */
147 ldr r0, =CK_DPLL1
148 mov r1, #0x10
149 strh r1, [r0]
150poll1:
151 ldrh r1, [r0]
152 ands r1, r1, #0x01
153 beq poll1
154
155 /*
156 * we do sys-critical inits only at reboot,
157 * not when booting from ram!
158 */
159#ifndef CONFIG_SKIP_LOWLEVEL_INIT
160 bl cpu_init_crit
161#endif
162
e05e5de7 163 bl _main
405d023b
HS
164
165/*------------------------------------------------------------------------------*/
166
e05e5de7
AA
167 .globl c_runtime_cpu_setup
168c_runtime_cpu_setup:
169
170 mov pc, lr
171
2e5983d2
WD
172/*
173 *************************************************************************
174 *
175 * CPU_init_critical registers
176 *
177 * setup important registers
178 * setup memory timing
179 *
180 *************************************************************************
181 */
182
183
184cpu_init_crit:
185 /*
186 * flush v4 I/D caches
187 */
188 mov r0, #0
189 mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
190 mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
191
192 /*
193 * disable MMU stuff and caches
194 */
195 mrc p15, 0, r0, c1, c0, 0
196 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
197 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
198 orr r0, r0, #0x00000002 @ set bit 2 (A) Align
199 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
200 mcr p15, 0, r0, c1, c0, 0
201
202 /*
203 * Go setup Memory and board specific bits prior to relocation.
204 */
205 mov ip, lr /* perserve link reg across call */
87cb6862 206 bl lowlevel_init /* go setup pll,mux,memory */
2e5983d2
WD
207 mov lr, ip /* restore link */
208 mov pc, lr /* back to my caller */
209/*
210 *************************************************************************
211 *
212 * Interrupt handling
213 *
214 *************************************************************************
215 */
216
217@
218@ IRQ stack frame.
219@
220#define S_FRAME_SIZE 72
221
222#define S_OLD_R0 68
223#define S_PSR 64
224#define S_PC 60
225#define S_LR 56
226#define S_SP 52
227
228#define S_IP 48
229#define S_FP 44
230#define S_R10 40
231#define S_R9 36
232#define S_R8 32
233#define S_R7 28
234#define S_R6 24
235#define S_R5 20
236#define S_R4 16
237#define S_R3 12
238#define S_R2 8
239#define S_R1 4
240#define S_R0 0
241
242#define MODE_SVC 0x13
243#define I_BIT 0x80
244
245/*
246 * use bad_save_user_regs for abort/prefetch/undef/swi ...
247 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
248 */
249
250 .macro bad_save_user_regs
251 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack
252 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
253
405d023b 254 ldr r2, IRQ_STACK_START_IN
2e5983d2
WD
255 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
256 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
257
258 add r5, sp, #S_SP
259 mov r1, lr
260 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr
261 mov r0, sp @ save current stack into r0 (param register)
262 .endm
263
264 .macro irq_save_user_regs
265 sub sp, sp, #S_FRAME_SIZE
266 stmia sp, {r0 - r12} @ Calling r0-r12
267 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good.
268 stmdb r8, {sp, lr}^ @ Calling SP, LR
269 str lr, [r8, #0] @ Save calling PC
270 mrs r6, spsr
271 str r6, [r8, #4] @ Save CPSR
272 str r0, [r8, #8] @ Save OLD_R0
273 mov r0, sp
274 .endm
275
276 .macro irq_restore_user_regs
277 ldmia sp, {r0 - lr}^ @ Calling r0 - lr
278 mov r0, r0
279 ldr lr, [sp, #S_PC] @ Get PC
280 add sp, sp, #S_FRAME_SIZE
281 subs pc, lr, #4 @ return & move spsr_svc into cpsr
282 .endm
283
284 .macro get_bad_stack
405d023b 285 ldr r13, IRQ_STACK_START_IN
2e5983d2
WD
286
287 str lr, [r13] @ save caller lr in position 0 of saved stack
288 mrs lr, spsr @ get the spsr
289 str lr, [r13, #4] @ save spsr in position 1 of saved stack
290
291 mov r13, #MODE_SVC @ prepare SVC-Mode
292 @ msr spsr_c, r13
293 msr spsr, r13 @ switch modes, make sure moves will execute
294 mov lr, pc @ capture return pc
295 movs pc, lr @ jump to next instruction & switch modes.
296 .endm
297
298 .macro get_irq_stack @ setup IRQ stack
299 ldr sp, IRQ_STACK_START
300 .endm
301
302 .macro get_fiq_stack @ setup FIQ stack
303 ldr sp, FIQ_STACK_START
304 .endm
305
306/*
307 * exception handlers
308 */
309 .align 5
310undefined_instruction:
311 get_bad_stack
312 bad_save_user_regs
53677ef1 313 bl do_undefined_instruction
2e5983d2
WD
314
315 .align 5
316software_interrupt:
317 get_bad_stack
318 bad_save_user_regs
53677ef1 319 bl do_software_interrupt
2e5983d2
WD
320
321 .align 5
322prefetch_abort:
323 get_bad_stack
324 bad_save_user_regs
53677ef1 325 bl do_prefetch_abort
2e5983d2
WD
326
327 .align 5
328data_abort:
329 get_bad_stack
330 bad_save_user_regs
53677ef1 331 bl do_data_abort
2e5983d2
WD
332
333 .align 5
334not_used:
335 get_bad_stack
336 bad_save_user_regs
53677ef1 337 bl do_not_used
2e5983d2
WD
338
339#ifdef CONFIG_USE_IRQ
340
341 .align 5
342irq:
343 get_irq_stack
344 irq_save_user_regs
53677ef1 345 bl do_irq
2e5983d2
WD
346 irq_restore_user_regs
347
348 .align 5
349fiq:
350 get_fiq_stack
351 /* someone ought to write a more effiction fiq_save_user_regs */
352 irq_save_user_regs
53677ef1 353 bl do_fiq
2e5983d2
WD
354 irq_restore_user_regs
355
356#else
357
358 .align 5
359irq:
360 get_bad_stack
361 bad_save_user_regs
53677ef1 362 bl do_irq
2e5983d2
WD
363
364 .align 5
365fiq:
366 get_bad_stack
367 bad_save_user_regs
53677ef1 368 bl do_fiq
2e5983d2
WD
369
370#endif
371
372 .align 5
373.globl reset_cpu
374reset_cpu:
375 ldr r1, rstctl1 /* get clkm1 reset ctl */
1f4bb37d
WD
376 mov r3, #0x3 /* dsp_en + arm_rst = global reset */
377 strh r3, [r1] /* force reset */
378 mov r0, r0
2e5983d2
WD
379_loop_forever:
380 b _loop_forever
381rstctl1:
382 .word 0xfffece10