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