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