xref: /rk3399_rockchip-uboot/arch/arm/cpu/arm1176/start.S (revision a51dd67a03d5a43c6c9a2964cfd854d332f52860)
184ad6884SPeter Tyser/*
2678e008cSCyril Chemparathy *  armboot - Startup Code for ARM1176 CPU-core
384ad6884SPeter Tyser *
484ad6884SPeter Tyser * Copyright (c) 2007	Samsung Electronics
584ad6884SPeter Tyser *
684ad6884SPeter Tyser * Copyright (C) 2008
784ad6884SPeter Tyser * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
884ad6884SPeter Tyser *
984ad6884SPeter Tyser * See file CREDITS for list of people who contributed to this
1084ad6884SPeter Tyser * project.
1184ad6884SPeter Tyser *
1284ad6884SPeter Tyser * This program is free software; you can redistribute it and/or
1384ad6884SPeter Tyser * modify it under the terms of the GNU General Public License as
1484ad6884SPeter Tyser * published by the Free Software Foundation; either version 2 of
1584ad6884SPeter Tyser * the License, or (at your option) any later version.
1684ad6884SPeter Tyser *
1784ad6884SPeter Tyser * This program is distributed in the hope that it will be useful,
1884ad6884SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of
1984ad6884SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
2084ad6884SPeter Tyser * GNU General Public License for more details.
2184ad6884SPeter Tyser *
2284ad6884SPeter Tyser * You should have received a copy of the GNU General Public License
2384ad6884SPeter Tyser * along with this program; if not, write to the Free Software
2484ad6884SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
2584ad6884SPeter Tyser * MA 02111-1307 USA
2684ad6884SPeter Tyser *
2784ad6884SPeter Tyser * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com)
2884ad6884SPeter Tyser * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
2984ad6884SPeter Tyser * jsgood (jsgood.yang@samsung.com)
3084ad6884SPeter Tyser * Base codes by scsuh (sc.suh)
3184ad6884SPeter Tyser */
3284ad6884SPeter Tyser
3384ad6884SPeter Tyser#include <config.h>
3484ad6884SPeter Tyser#include <version.h>
3584ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU
3684ad6884SPeter Tyser#include <asm/proc/domain.h>
3784ad6884SPeter Tyser#endif
3884ad6884SPeter Tyser
3984ad6884SPeter Tyser#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE)
4084ad6884SPeter Tyser#define CONFIG_SYS_PHY_UBOOT_BASE	CONFIG_SYS_UBOOT_BASE
4184ad6884SPeter Tyser#endif
4284ad6884SPeter Tyser
4384ad6884SPeter Tyser/*
4484ad6884SPeter Tyser *************************************************************************
4584ad6884SPeter Tyser *
4684ad6884SPeter Tyser * Jump vector table as in table 3.1 in [1]
4784ad6884SPeter Tyser *
4884ad6884SPeter Tyser *************************************************************************
4984ad6884SPeter Tyser */
5084ad6884SPeter Tyser
5184ad6884SPeter Tyser.globl _start
5284ad6884SPeter Tyser_start: b	reset
5384ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL
5484ad6884SPeter Tyser	ldr	pc, _undefined_instruction
5584ad6884SPeter Tyser	ldr	pc, _software_interrupt
5684ad6884SPeter Tyser	ldr	pc, _prefetch_abort
5784ad6884SPeter Tyser	ldr	pc, _data_abort
5884ad6884SPeter Tyser	ldr	pc, _not_used
5984ad6884SPeter Tyser	ldr	pc, _irq
6084ad6884SPeter Tyser	ldr	pc, _fiq
6184ad6884SPeter Tyser
6284ad6884SPeter Tyser_undefined_instruction:
6384ad6884SPeter Tyser	.word undefined_instruction
6484ad6884SPeter Tyser_software_interrupt:
6584ad6884SPeter Tyser	.word software_interrupt
6684ad6884SPeter Tyser_prefetch_abort:
6784ad6884SPeter Tyser	.word prefetch_abort
6884ad6884SPeter Tyser_data_abort:
6984ad6884SPeter Tyser	.word data_abort
7084ad6884SPeter Tyser_not_used:
7184ad6884SPeter Tyser	.word not_used
7284ad6884SPeter Tyser_irq:
7384ad6884SPeter Tyser	.word irq
7484ad6884SPeter Tyser_fiq:
7584ad6884SPeter Tyser	.word fiq
7684ad6884SPeter Tyser_pad:
7784ad6884SPeter Tyser	.word 0x12345678 /* now 16*4=64 */
7884ad6884SPeter Tyser#else
7984ad6884SPeter Tyser	. = _start + 64
8084ad6884SPeter Tyser#endif
8184ad6884SPeter Tyser
8284ad6884SPeter Tyser.global _end_vect
8384ad6884SPeter Tyser_end_vect:
8484ad6884SPeter Tyser	.balignl 16,0xdeadbeef
8584ad6884SPeter Tyser/*
8684ad6884SPeter Tyser *************************************************************************
8784ad6884SPeter Tyser *
8884ad6884SPeter Tyser * Startup Code (reset vector)
8984ad6884SPeter Tyser *
9084ad6884SPeter Tyser * do important init only if we don't start from memory!
9184ad6884SPeter Tyser * setup Memory and board specific bits prior to relocation.
9284ad6884SPeter Tyser * relocate armboot to ram
9384ad6884SPeter Tyser * setup stack
9484ad6884SPeter Tyser *
9584ad6884SPeter Tyser *************************************************************************
9684ad6884SPeter Tyser */
9784ad6884SPeter Tyser
98*a51dd67aSHeiko Schocher.globl _TEXT_BASE
9984ad6884SPeter Tyser_TEXT_BASE:
10084ad6884SPeter Tyser	.word	TEXT_BASE
10184ad6884SPeter Tyser
10284ad6884SPeter Tyser/*
10384ad6884SPeter Tyser * Below variable is very important because we use MMU in U-Boot.
10484ad6884SPeter Tyser * Without it, we cannot run code correctly before MMU is ON.
10584ad6884SPeter Tyser * by scsuh.
10684ad6884SPeter Tyser */
10784ad6884SPeter Tyser_TEXT_PHY_BASE:
10884ad6884SPeter Tyser	.word	CONFIG_SYS_PHY_UBOOT_BASE
10984ad6884SPeter Tyser
110*a51dd67aSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
11184ad6884SPeter Tyser.globl _armboot_start
11284ad6884SPeter Tyser_armboot_start:
11384ad6884SPeter Tyser	.word _start
114*a51dd67aSHeiko Schocher#endif
11584ad6884SPeter Tyser
11684ad6884SPeter Tyser/*
11784ad6884SPeter Tyser * These are defined in the board-specific linker script.
11884ad6884SPeter Tyser */
11984ad6884SPeter Tyser.globl _bss_start
12084ad6884SPeter Tyser_bss_start:
12184ad6884SPeter Tyser	.word __bss_start
12284ad6884SPeter Tyser
12384ad6884SPeter Tyser.globl _bss_end
12484ad6884SPeter Tyser_bss_end:
12584ad6884SPeter Tyser	.word _end
12684ad6884SPeter Tyser
127*a51dd67aSHeiko Schocher#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
128*a51dd67aSHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */
129*a51dd67aSHeiko Schocher.globl IRQ_STACK_START_IN
130*a51dd67aSHeiko SchocherIRQ_STACK_START_IN:
131*a51dd67aSHeiko Schocher	.word	0x0badc0de
132*a51dd67aSHeiko Schocher
133*a51dd67aSHeiko Schocher.globl _datarel_start
134*a51dd67aSHeiko Schocher_datarel_start:
135*a51dd67aSHeiko Schocher	.word __datarel_start
136*a51dd67aSHeiko Schocher
137*a51dd67aSHeiko Schocher.globl _datarelrolocal_start
138*a51dd67aSHeiko Schocher_datarelrolocal_start:
139*a51dd67aSHeiko Schocher	.word __datarelrolocal_start
140*a51dd67aSHeiko Schocher
141*a51dd67aSHeiko Schocher.globl _datarellocal_start
142*a51dd67aSHeiko Schocher_datarellocal_start:
143*a51dd67aSHeiko Schocher	.word __datarellocal_start
144*a51dd67aSHeiko Schocher
145*a51dd67aSHeiko Schocher.globl _datarelro_start
146*a51dd67aSHeiko Schocher_datarelro_start:
147*a51dd67aSHeiko Schocher	.word __datarelro_start
148*a51dd67aSHeiko Schocher
149*a51dd67aSHeiko Schocher.globl _got_start
150*a51dd67aSHeiko Schocher_got_start:
151*a51dd67aSHeiko Schocher	.word __got_start
152*a51dd67aSHeiko Schocher
153*a51dd67aSHeiko Schocher.globl _got_end
154*a51dd67aSHeiko Schocher_got_end:
155*a51dd67aSHeiko Schocher	.word __got_end
156*a51dd67aSHeiko Schocher
157*a51dd67aSHeiko Schocher/*
158*a51dd67aSHeiko Schocher * the actual reset code
159*a51dd67aSHeiko Schocher */
160*a51dd67aSHeiko Schocher
161*a51dd67aSHeiko Schocherreset:
162*a51dd67aSHeiko Schocher	/*
163*a51dd67aSHeiko Schocher	 * set the cpu to SVC32 mode
164*a51dd67aSHeiko Schocher	 */
165*a51dd67aSHeiko Schocher	mrs	r0, cpsr
166*a51dd67aSHeiko Schocher	bic	r0, r0, #0x3f
167*a51dd67aSHeiko Schocher	orr	r0, r0, #0xd3
168*a51dd67aSHeiko Schocher	msr	cpsr, r0
169*a51dd67aSHeiko Schocher
170*a51dd67aSHeiko Schocher/*
171*a51dd67aSHeiko Schocher *************************************************************************
172*a51dd67aSHeiko Schocher *
173*a51dd67aSHeiko Schocher * CPU_init_critical registers
174*a51dd67aSHeiko Schocher *
175*a51dd67aSHeiko Schocher * setup important registers
176*a51dd67aSHeiko Schocher * setup memory timing
177*a51dd67aSHeiko Schocher *
178*a51dd67aSHeiko Schocher *************************************************************************
179*a51dd67aSHeiko Schocher */
180*a51dd67aSHeiko Schocher	/*
181*a51dd67aSHeiko Schocher	 * we do sys-critical inits only at reboot,
182*a51dd67aSHeiko Schocher	 * not when booting from ram!
183*a51dd67aSHeiko Schocher	 */
184*a51dd67aSHeiko Schochercpu_init_crit:
185*a51dd67aSHeiko Schocher	/*
186*a51dd67aSHeiko Schocher	 * When booting from NAND - it has definitely been a reset, so, no need
187*a51dd67aSHeiko Schocher	 * to flush caches and disable the MMU
188*a51dd67aSHeiko Schocher	 */
189*a51dd67aSHeiko Schocher#ifndef CONFIG_NAND_SPL
190*a51dd67aSHeiko Schocher	/*
191*a51dd67aSHeiko Schocher	 * flush v4 I/D caches
192*a51dd67aSHeiko Schocher	 */
193*a51dd67aSHeiko Schocher	mov	r0, #0
194*a51dd67aSHeiko Schocher	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
195*a51dd67aSHeiko Schocher	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
196*a51dd67aSHeiko Schocher
197*a51dd67aSHeiko Schocher	/*
198*a51dd67aSHeiko Schocher	 * disable MMU stuff and caches
199*a51dd67aSHeiko Schocher	 */
200*a51dd67aSHeiko Schocher	mrc	p15, 0, r0, c1, c0, 0
201*a51dd67aSHeiko Schocher	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
202*a51dd67aSHeiko Schocher	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
203*a51dd67aSHeiko Schocher	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
204*a51dd67aSHeiko Schocher	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
205*a51dd67aSHeiko Schocher
206*a51dd67aSHeiko Schocher	/* Prepare to disable the MMU */
207*a51dd67aSHeiko Schocher	adr	r2, mmu_disable_phys
208*a51dd67aSHeiko Schocher	sub	r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - TEXT_BASE)
209*a51dd67aSHeiko Schocher	b	mmu_disable
210*a51dd67aSHeiko Schocher
211*a51dd67aSHeiko Schocher	.align 5
212*a51dd67aSHeiko Schocher	/* Run in a single cache-line */
213*a51dd67aSHeiko Schochermmu_disable:
214*a51dd67aSHeiko Schocher	mcr	p15, 0, r0, c1, c0, 0
215*a51dd67aSHeiko Schocher	nop
216*a51dd67aSHeiko Schocher	nop
217*a51dd67aSHeiko Schocher	mov	pc, r2
218*a51dd67aSHeiko Schochermmu_disable_phys:
219*a51dd67aSHeiko Schocher
220*a51dd67aSHeiko Schocher#ifdef CONFIG_DISABLE_TCM
221*a51dd67aSHeiko Schocher	/*
222*a51dd67aSHeiko Schocher	 * Disable the TCMs
223*a51dd67aSHeiko Schocher	 */
224*a51dd67aSHeiko Schocher	mrc	p15, 0, r0, c0, c0, 2	/* Return TCM details */
225*a51dd67aSHeiko Schocher	cmp	r0, #0
226*a51dd67aSHeiko Schocher	beq	skip_tcmdisable
227*a51dd67aSHeiko Schocher	mov	r1, #0
228*a51dd67aSHeiko Schocher	mov	r2, #1
229*a51dd67aSHeiko Schocher	tst	r0, r2
230*a51dd67aSHeiko Schocher	mcrne	p15, 0, r1, c9, c1, 1	/* Disable Instruction TCM if present*/
231*a51dd67aSHeiko Schocher	tst	r0, r2, LSL #16
232*a51dd67aSHeiko Schocher	mcrne	p15, 0, r1, c9, c1, 0	/* Disable Data TCM if present*/
233*a51dd67aSHeiko Schocherskip_tcmdisable:
234*a51dd67aSHeiko Schocher#endif
235*a51dd67aSHeiko Schocher#endif
236*a51dd67aSHeiko Schocher
237*a51dd67aSHeiko Schocher#ifdef CONFIG_PERIPORT_REMAP
238*a51dd67aSHeiko Schocher	/* Peri port setup */
239*a51dd67aSHeiko Schocher	ldr	r0, =CONFIG_PERIPORT_BASE
240*a51dd67aSHeiko Schocher	orr	r0, r0, #CONFIG_PERIPORT_SIZE
241*a51dd67aSHeiko Schocher	mcr	p15,0,r0,c15,c2,4
242*a51dd67aSHeiko Schocher#endif
243*a51dd67aSHeiko Schocher
244*a51dd67aSHeiko Schocher	/*
245*a51dd67aSHeiko Schocher	 * Go setup Memory and board specific bits prior to relocation.
246*a51dd67aSHeiko Schocher	 */
247*a51dd67aSHeiko Schocher	bl	lowlevel_init		/* go setup pll,mux,memory */
248*a51dd67aSHeiko Schocher
249*a51dd67aSHeiko Schocher/* Set stackpointer in internal RAM to call board_init_f */
250*a51dd67aSHeiko Schochercall_board_init_f:
251*a51dd67aSHeiko Schocher	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
252*a51dd67aSHeiko Schocher	ldr	r0,=0x00000000
253*a51dd67aSHeiko Schocher	bl	board_init_f
254*a51dd67aSHeiko Schocher
255*a51dd67aSHeiko Schocher/*------------------------------------------------------------------------------*/
256*a51dd67aSHeiko Schocher
257*a51dd67aSHeiko Schocher/*
258*a51dd67aSHeiko Schocher * void relocate_code (addr_sp, gd, addr_moni)
259*a51dd67aSHeiko Schocher *
260*a51dd67aSHeiko Schocher * This "function" does not return, instead it continues in RAM
261*a51dd67aSHeiko Schocher * after relocating the monitor code.
262*a51dd67aSHeiko Schocher *
263*a51dd67aSHeiko Schocher */
264*a51dd67aSHeiko Schocher	.globl	relocate_code
265*a51dd67aSHeiko Schocherrelocate_code:
266*a51dd67aSHeiko Schocher	mov	r4, r0	/* save addr_sp */
267*a51dd67aSHeiko Schocher	mov	r5, r1	/* save addr of gd */
268*a51dd67aSHeiko Schocher	mov	r6, r2	/* save addr of destination */
269*a51dd67aSHeiko Schocher	mov	r7, r2	/* save addr of destination */
270*a51dd67aSHeiko Schocher
271*a51dd67aSHeiko Schocher	/* Set up the stack						    */
272*a51dd67aSHeiko Schocherstack_setup:
273*a51dd67aSHeiko Schocher	mov	sp, r4
274*a51dd67aSHeiko Schocher
275*a51dd67aSHeiko Schocher	adr	r0, _start
276*a51dd67aSHeiko Schocher	ldr	r2, _TEXT_BASE
277*a51dd67aSHeiko Schocher	ldr	r3, _bss_start
278*a51dd67aSHeiko Schocher	sub	r2, r3, r2		/* r2 <- size of armboot	    */
279*a51dd67aSHeiko Schocher	add	r2, r0, r2		/* r2 <- source end address	    */
280*a51dd67aSHeiko Schocher	cmp	r0, r6
281*a51dd67aSHeiko Schocher	beq	clear_bss
282*a51dd67aSHeiko Schocher
283*a51dd67aSHeiko Schocher#ifndef CONFIG_SKIP_RELOCATE_UBOOT
284*a51dd67aSHeiko Schochercopy_loop:
285*a51dd67aSHeiko Schocher	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
286*a51dd67aSHeiko Schocher	stmia	r6!, {r9-r10}		/* copy to   target address [r1]    */
287*a51dd67aSHeiko Schocher	cmp	r0, r2			/* until source end addreee [r2]    */
288*a51dd67aSHeiko Schocher	ble	copy_loop
289*a51dd67aSHeiko Schocher
290*a51dd67aSHeiko Schocher#ifndef CONFIG_PRELOADER
291*a51dd67aSHeiko Schocher	/* fix got entries */
292*a51dd67aSHeiko Schocher	ldr	r1, _TEXT_BASE		/* Text base */
293*a51dd67aSHeiko Schocher	mov	r0, r7			/* reloc addr */
294*a51dd67aSHeiko Schocher	ldr	r2, _got_start		/* addr in Flash */
295*a51dd67aSHeiko Schocher	ldr	r3, _got_end		/* addr in Flash */
296*a51dd67aSHeiko Schocher	sub	r3, r3, r1
297*a51dd67aSHeiko Schocher	add	r3, r3, r0
298*a51dd67aSHeiko Schocher	sub	r2, r2, r1
299*a51dd67aSHeiko Schocher	add	r2, r2, r0
300*a51dd67aSHeiko Schocher
301*a51dd67aSHeiko Schocherfixloop:
302*a51dd67aSHeiko Schocher	ldr	r4, [r2]
303*a51dd67aSHeiko Schocher	sub	r4, r4, r1
304*a51dd67aSHeiko Schocher	add	r4, r4, r0
305*a51dd67aSHeiko Schocher	str	r4, [r2]
306*a51dd67aSHeiko Schocher	add	r2, r2, #4
307*a51dd67aSHeiko Schocher	cmp	r2, r3
308*a51dd67aSHeiko Schocher	bne	fixloop
309*a51dd67aSHeiko Schocher#endif
310*a51dd67aSHeiko Schocher#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
311*a51dd67aSHeiko Schocher
312*a51dd67aSHeiko Schocher#ifdef CONFIG_ENABLE_MMU
313*a51dd67aSHeiko Schocherenable_mmu:
314*a51dd67aSHeiko Schocher	/* enable domain access */
315*a51dd67aSHeiko Schocher	ldr	r5, =0x0000ffff
316*a51dd67aSHeiko Schocher	mcr	p15, 0, r5, c3, c0, 0	/* load domain access register */
317*a51dd67aSHeiko Schocher
318*a51dd67aSHeiko Schocher	/* Set the TTB register */
319*a51dd67aSHeiko Schocher	ldr	r0, _mmu_table_base
320*a51dd67aSHeiko Schocher	ldr	r1, =CONFIG_SYS_PHY_UBOOT_BASE
321*a51dd67aSHeiko Schocher	ldr	r2, =0xfff00000
322*a51dd67aSHeiko Schocher	bic	r0, r0, r2
323*a51dd67aSHeiko Schocher	orr	r1, r0, r1
324*a51dd67aSHeiko Schocher	mcr	p15, 0, r1, c2, c0, 0
325*a51dd67aSHeiko Schocher
326*a51dd67aSHeiko Schocher	/* Enable the MMU */
327*a51dd67aSHeiko Schocher	mrc	p15, 0, r0, c1, c0, 0
328*a51dd67aSHeiko Schocher	orr	r0, r0, #1		/* Set CR_M to enable MMU */
329*a51dd67aSHeiko Schocher
330*a51dd67aSHeiko Schocher	/* Prepare to enable the MMU */
331*a51dd67aSHeiko Schocher	adr	r1, skip_hw_init
332*a51dd67aSHeiko Schocher	and	r1, r1, #0x3fc
333*a51dd67aSHeiko Schocher	ldr	r2, _TEXT_BASE
334*a51dd67aSHeiko Schocher	ldr	r3, =0xfff00000
335*a51dd67aSHeiko Schocher	and	r2, r2, r3
336*a51dd67aSHeiko Schocher	orr	r2, r2, r1
337*a51dd67aSHeiko Schocher	b	mmu_enable
338*a51dd67aSHeiko Schocher
339*a51dd67aSHeiko Schocher	.align 5
340*a51dd67aSHeiko Schocher	/* Run in a single cache-line */
341*a51dd67aSHeiko Schochermmu_enable:
342*a51dd67aSHeiko Schocher
343*a51dd67aSHeiko Schocher	mcr	p15, 0, r0, c1, c0, 0
344*a51dd67aSHeiko Schocher	nop
345*a51dd67aSHeiko Schocher	nop
346*a51dd67aSHeiko Schocher	mov	pc, r2
347*a51dd67aSHeiko Schocherskip_hw_init:
348*a51dd67aSHeiko Schocher#endif
349*a51dd67aSHeiko Schocher
350*a51dd67aSHeiko Schocherclear_bss:
351*a51dd67aSHeiko Schocher#ifndef CONFIG_PRELOADER
352*a51dd67aSHeiko Schocher	ldr	r0, _bss_start
353*a51dd67aSHeiko Schocher	ldr	r1, _bss_end
354*a51dd67aSHeiko Schocher	ldr	r3, _TEXT_BASE		/* Text base */
355*a51dd67aSHeiko Schocher	mov	r4, r7			/* reloc addr */
356*a51dd67aSHeiko Schocher	sub	r0, r0, r3
357*a51dd67aSHeiko Schocher	add	r0, r0, r4
358*a51dd67aSHeiko Schocher	sub	r1, r1, r3
359*a51dd67aSHeiko Schocher	add	r1, r1, r4
360*a51dd67aSHeiko Schocher	mov	r2, #0x00000000		/* clear			    */
361*a51dd67aSHeiko Schocher
362*a51dd67aSHeiko Schocherclbss_l:str	r2, [r0]		/* clear loop...		    */
363*a51dd67aSHeiko Schocher	add	r0, r0, #4
364*a51dd67aSHeiko Schocher	cmp	r0, r1
365*a51dd67aSHeiko Schocher	bne	clbss_l
366*a51dd67aSHeiko Schocher
367*a51dd67aSHeiko Schocher	bl coloured_LED_init
368*a51dd67aSHeiko Schocher	bl red_LED_on
369*a51dd67aSHeiko Schocher#endif
370*a51dd67aSHeiko Schocher
371*a51dd67aSHeiko Schocher/*
372*a51dd67aSHeiko Schocher * We are done. Do not return, instead branch to second part of board
373*a51dd67aSHeiko Schocher * initialization, now running from RAM.
374*a51dd67aSHeiko Schocher */
375*a51dd67aSHeiko Schocher#ifdef CONFIG_NAND_SPL
376*a51dd67aSHeiko Schocher	ldr     pc, _nand_boot
377*a51dd67aSHeiko Schocher
378*a51dd67aSHeiko Schocher_nand_boot: .word nand_boot
379*a51dd67aSHeiko Schocher#else
380*a51dd67aSHeiko Schocher	ldr	r0, _TEXT_BASE
381*a51dd67aSHeiko Schocher	ldr	r2, _board_init_r
382*a51dd67aSHeiko Schocher	sub	r2, r2, r0
383*a51dd67aSHeiko Schocher	add	r2, r2, r7	/* position from board_init_r in RAM */
384*a51dd67aSHeiko Schocher	/* setup parameters for board_init_r */
385*a51dd67aSHeiko Schocher	mov	r0, r5		/* gd_t */
386*a51dd67aSHeiko Schocher	mov	r1, r7		/* dest_addr */
387*a51dd67aSHeiko Schocher	/* jump to it ... */
388*a51dd67aSHeiko Schocher	mov	lr, r2
389*a51dd67aSHeiko Schocher	mov	pc, lr
390*a51dd67aSHeiko Schocher
391*a51dd67aSHeiko Schocher_board_init_r: .word board_init_r
392*a51dd67aSHeiko Schocher#endif
393*a51dd67aSHeiko Schocher
394*a51dd67aSHeiko Schocher#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
395*a51dd67aSHeiko Schocher
39684ad6884SPeter Tyser/*
39784ad6884SPeter Tyser * the actual reset code
39884ad6884SPeter Tyser */
39984ad6884SPeter Tyser
40084ad6884SPeter Tyserreset:
40184ad6884SPeter Tyser	/*
40284ad6884SPeter Tyser	 * set the cpu to SVC32 mode
40384ad6884SPeter Tyser	 */
40484ad6884SPeter Tyser	mrs	r0, cpsr
40584ad6884SPeter Tyser	bic	r0, r0, #0x3f
40684ad6884SPeter Tyser	orr	r0, r0, #0xd3
40784ad6884SPeter Tyser	msr	cpsr, r0
40884ad6884SPeter Tyser
40984ad6884SPeter Tyser/*
41084ad6884SPeter Tyser *************************************************************************
41184ad6884SPeter Tyser *
41284ad6884SPeter Tyser * CPU_init_critical registers
41384ad6884SPeter Tyser *
41484ad6884SPeter Tyser * setup important registers
41584ad6884SPeter Tyser * setup memory timing
41684ad6884SPeter Tyser *
41784ad6884SPeter Tyser *************************************************************************
41884ad6884SPeter Tyser */
41984ad6884SPeter Tyser	/*
42084ad6884SPeter Tyser	 * we do sys-critical inits only at reboot,
42184ad6884SPeter Tyser	 * not when booting from ram!
42284ad6884SPeter Tyser	 */
42384ad6884SPeter Tysercpu_init_crit:
42484ad6884SPeter Tyser	/*
42584ad6884SPeter Tyser	 * When booting from NAND - it has definitely been a reset, so, no need
42684ad6884SPeter Tyser	 * to flush caches and disable the MMU
42784ad6884SPeter Tyser	 */
42884ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL
42984ad6884SPeter Tyser	/*
43084ad6884SPeter Tyser	 * flush v4 I/D caches
43184ad6884SPeter Tyser	 */
43284ad6884SPeter Tyser	mov	r0, #0
43384ad6884SPeter Tyser	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
43484ad6884SPeter Tyser	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
43584ad6884SPeter Tyser
43684ad6884SPeter Tyser	/*
43784ad6884SPeter Tyser	 * disable MMU stuff and caches
43884ad6884SPeter Tyser	 */
43984ad6884SPeter Tyser	mrc	p15, 0, r0, c1, c0, 0
44084ad6884SPeter Tyser	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
44184ad6884SPeter Tyser	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
44284ad6884SPeter Tyser	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
44384ad6884SPeter Tyser	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
444678e008cSCyril Chemparathy
44584ad6884SPeter Tyser	/* Prepare to disable the MMU */
446678e008cSCyril Chemparathy	adr	r2, mmu_disable_phys
447678e008cSCyril Chemparathy	sub	r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - TEXT_BASE)
44884ad6884SPeter Tyser	b	mmu_disable
44984ad6884SPeter Tyser
45084ad6884SPeter Tyser	.align 5
45184ad6884SPeter Tyser	/* Run in a single cache-line */
45284ad6884SPeter Tysermmu_disable:
45384ad6884SPeter Tyser	mcr	p15, 0, r0, c1, c0, 0
45484ad6884SPeter Tyser	nop
45584ad6884SPeter Tyser	nop
45684ad6884SPeter Tyser	mov	pc, r2
457678e008cSCyril Chemparathymmu_disable_phys:
458678e008cSCyril Chemparathy
459678e008cSCyril Chemparathy#ifdef CONFIG_DISABLE_TCM
460678e008cSCyril Chemparathy	/*
461678e008cSCyril Chemparathy	 * Disable the TCMs
462678e008cSCyril Chemparathy	 */
463678e008cSCyril Chemparathy	mrc	p15, 0, r0, c0, c0, 2	/* Return TCM details */
464678e008cSCyril Chemparathy	cmp	r0, #0
465678e008cSCyril Chemparathy	beq	skip_tcmdisable
466678e008cSCyril Chemparathy	mov	r1, #0
467678e008cSCyril Chemparathy	mov	r2, #1
468678e008cSCyril Chemparathy	tst	r0, r2
469678e008cSCyril Chemparathy	mcrne	p15, 0, r1, c9, c1, 1	/* Disable Instruction TCM if present*/
470678e008cSCyril Chemparathy	tst	r0, r2, LSL #16
471678e008cSCyril Chemparathy	mcrne	p15, 0, r1, c9, c1, 0	/* Disable Data TCM if present*/
472678e008cSCyril Chemparathyskip_tcmdisable:
473678e008cSCyril Chemparathy#endif
47484ad6884SPeter Tyser#endif
47584ad6884SPeter Tyser
476678e008cSCyril Chemparathy#ifdef CONFIG_PERIPORT_REMAP
47784ad6884SPeter Tyser	/* Peri port setup */
478678e008cSCyril Chemparathy	ldr	r0, =CONFIG_PERIPORT_BASE
479678e008cSCyril Chemparathy	orr	r0, r0, #CONFIG_PERIPORT_SIZE
480678e008cSCyril Chemparathy	mcr	p15,0,r0,c15,c2,4
48184ad6884SPeter Tyser#endif
48284ad6884SPeter Tyser
48384ad6884SPeter Tyser	/*
48484ad6884SPeter Tyser	 * Go setup Memory and board specific bits prior to relocation.
48584ad6884SPeter Tyser	 */
48684ad6884SPeter Tyser	bl	lowlevel_init		/* go setup pll,mux,memory */
48784ad6884SPeter Tyser
488678e008cSCyril Chemparathy#ifndef CONFIG_SKIP_RELOCATE_UBOOT
489678e008cSCyril Chemparathyrelocate:				/* relocate U-Boot to RAM	    */
490678e008cSCyril Chemparathy	adr	r0, _start		/* r0 <- current position of code   */
491678e008cSCyril Chemparathy	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
492678e008cSCyril Chemparathy	cmp     r0, r1                  /* don't reloc during debug         */
493678e008cSCyril Chemparathy	beq     stack_setup
494678e008cSCyril Chemparathy
495678e008cSCyril Chemparathy	ldr	r2, _armboot_start
496678e008cSCyril Chemparathy	ldr	r3, _bss_start
497678e008cSCyril Chemparathy	sub	r2, r3, r2		/* r2 <- size of armboot            */
498678e008cSCyril Chemparathy	add	r2, r0, r2		/* r2 <- source end address         */
499678e008cSCyril Chemparathy
500678e008cSCyril Chemparathycopy_loop:
501678e008cSCyril Chemparathy	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
502678e008cSCyril Chemparathy	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
503678e008cSCyril Chemparathy	cmp	r0, r2			/* until source end addreee [r2]    */
504678e008cSCyril Chemparathy	ble	copy_loop
505678e008cSCyril Chemparathy#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
506678e008cSCyril Chemparathy
50784ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU
50884ad6884SPeter Tyserenable_mmu:
50984ad6884SPeter Tyser	/* enable domain access */
51084ad6884SPeter Tyser	ldr	r5, =0x0000ffff
51184ad6884SPeter Tyser	mcr	p15, 0, r5, c3, c0, 0	/* load domain access register */
51284ad6884SPeter Tyser
51384ad6884SPeter Tyser	/* Set the TTB register */
51484ad6884SPeter Tyser	ldr	r0, _mmu_table_base
51584ad6884SPeter Tyser	ldr	r1, =CONFIG_SYS_PHY_UBOOT_BASE
51684ad6884SPeter Tyser	ldr	r2, =0xfff00000
51784ad6884SPeter Tyser	bic	r0, r0, r2
51884ad6884SPeter Tyser	orr	r1, r0, r1
51984ad6884SPeter Tyser	mcr	p15, 0, r1, c2, c0, 0
52084ad6884SPeter Tyser
52184ad6884SPeter Tyser	/* Enable the MMU */
52284ad6884SPeter Tyser	mrc	p15, 0, r0, c1, c0, 0
52384ad6884SPeter Tyser	orr	r0, r0, #1		/* Set CR_M to enable MMU */
52484ad6884SPeter Tyser
52584ad6884SPeter Tyser	/* Prepare to enable the MMU */
52684ad6884SPeter Tyser	adr	r1, skip_hw_init
52784ad6884SPeter Tyser	and	r1, r1, #0x3fc
52884ad6884SPeter Tyser	ldr	r2, _TEXT_BASE
52984ad6884SPeter Tyser	ldr	r3, =0xfff00000
53084ad6884SPeter Tyser	and	r2, r2, r3
53184ad6884SPeter Tyser	orr	r2, r2, r1
53284ad6884SPeter Tyser	b	mmu_enable
53384ad6884SPeter Tyser
53484ad6884SPeter Tyser	.align 5
53584ad6884SPeter Tyser	/* Run in a single cache-line */
53684ad6884SPeter Tysermmu_enable:
53784ad6884SPeter Tyser
53884ad6884SPeter Tyser	mcr	p15, 0, r0, c1, c0, 0
53984ad6884SPeter Tyser	nop
54084ad6884SPeter Tyser	nop
54184ad6884SPeter Tyser	mov	pc, r2
542678e008cSCyril Chemparathyskip_hw_init:
54384ad6884SPeter Tyser#endif
54484ad6884SPeter Tyser
54584ad6884SPeter Tyser	/* Set up the stack						    */
54684ad6884SPeter Tyserstack_setup:
54784ad6884SPeter Tyser	ldr	r0, =CONFIG_SYS_UBOOT_BASE	/* base of copy in DRAM	    */
54884ad6884SPeter Tyser	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN	/* malloc area                      */
54984ad6884SPeter Tyser	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */
55084ad6884SPeter Tyser	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
5511a27f7d9SVitaly Kuzmichev	bic	sp, sp, #7		/* 8-byte alignment for ABI compliance */
55284ad6884SPeter Tyser
55384ad6884SPeter Tyserclear_bss:
55484ad6884SPeter Tyser	ldr	r0, _bss_start		/* find start of bss segment        */
55584ad6884SPeter Tyser	ldr	r1, _bss_end		/* stop here                        */
55684ad6884SPeter Tyser	mov 	r2, #0			/* clear                            */
55784ad6884SPeter Tyser
55884ad6884SPeter Tyserclbss_l:
55984ad6884SPeter Tyser	str	r2, [r0]		/* clear loop...                    */
56084ad6884SPeter Tyser	add	r0, r0, #4
56184ad6884SPeter Tyser	cmp	r0, r1
56284ad6884SPeter Tyser	ble	clbss_l
56384ad6884SPeter Tyser
56484ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL
56584ad6884SPeter Tyser	ldr	pc, _start_armboot
56684ad6884SPeter Tyser
56784ad6884SPeter Tyser_start_armboot:
56884ad6884SPeter Tyser	.word start_armboot
56984ad6884SPeter Tyser#else
57084ad6884SPeter Tyser	b	nand_boot
57184ad6884SPeter Tyser/*	.word nand_boot*/
57284ad6884SPeter Tyser#endif
57384ad6884SPeter Tyser
574*a51dd67aSHeiko Schocher#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
575*a51dd67aSHeiko Schocher
57684ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU
57784ad6884SPeter Tyser_mmu_table_base:
57884ad6884SPeter Tyser	.word mmu_table
57984ad6884SPeter Tyser#endif
58084ad6884SPeter Tyser
58184ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL
58284ad6884SPeter Tyser/*
58384ad6884SPeter Tyser * we assume that cache operation is done before. (eg. cleanup_before_linux())
58484ad6884SPeter Tyser * actually, we don't need to do anything about cache if not use d-cache in
58584ad6884SPeter Tyser * U-Boot. So, in this function we clean only MMU. by scsuh
58684ad6884SPeter Tyser *
58784ad6884SPeter Tyser * void	theLastJump(void *kernel, int arch_num, uint boot_params);
58884ad6884SPeter Tyser */
58984ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU
59084ad6884SPeter Tyser	.globl theLastJump
59184ad6884SPeter TysertheLastJump:
59284ad6884SPeter Tyser	mov	r9, r0
59384ad6884SPeter Tyser	ldr	r3, =0xfff00000
59484ad6884SPeter Tyser	ldr	r4, _TEXT_PHY_BASE
59584ad6884SPeter Tyser	adr	r5, phy_last_jump
59684ad6884SPeter Tyser	bic	r5, r5, r3
59784ad6884SPeter Tyser	orr	r5, r5, r4
59884ad6884SPeter Tyser	mov	pc, r5
59984ad6884SPeter Tyserphy_last_jump:
60084ad6884SPeter Tyser	/*
60184ad6884SPeter Tyser	 * disable MMU stuff
60284ad6884SPeter Tyser	 */
60384ad6884SPeter Tyser	mrc	p15, 0, r0, c1, c0, 0
60484ad6884SPeter Tyser	bic	r0, r0, #0x00002300	/* clear bits 13, 9:8 (--V- --RS) */
60584ad6884SPeter Tyser	bic	r0, r0, #0x00000087	/* clear bits 7, 2:0 (B--- -CAM) */
60684ad6884SPeter Tyser	orr	r0, r0, #0x00000002	/* set bit 2 (A) Align */
60784ad6884SPeter Tyser	orr	r0, r0, #0x00001000	/* set bit 12 (I) I-Cache */
60884ad6884SPeter Tyser	mcr	p15, 0, r0, c1, c0, 0
60984ad6884SPeter Tyser
61084ad6884SPeter Tyser	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
61184ad6884SPeter Tyser
61284ad6884SPeter Tyser	mov	r0, #0
61384ad6884SPeter Tyser	mov	pc, r9
61484ad6884SPeter Tyser#endif
615678e008cSCyril Chemparathy
616678e008cSCyril Chemparathy
61784ad6884SPeter Tyser/*
61884ad6884SPeter Tyser *************************************************************************
61984ad6884SPeter Tyser *
62084ad6884SPeter Tyser * Interrupt handling
62184ad6884SPeter Tyser *
62284ad6884SPeter Tyser *************************************************************************
62384ad6884SPeter Tyser */
62484ad6884SPeter Tyser@
62584ad6884SPeter Tyser@ IRQ stack frame.
62684ad6884SPeter Tyser@
62784ad6884SPeter Tyser#define S_FRAME_SIZE	72
62884ad6884SPeter Tyser
62984ad6884SPeter Tyser#define S_OLD_R0	68
63084ad6884SPeter Tyser#define S_PSR		64
63184ad6884SPeter Tyser#define S_PC		60
63284ad6884SPeter Tyser#define S_LR		56
63384ad6884SPeter Tyser#define S_SP		52
63484ad6884SPeter Tyser
63584ad6884SPeter Tyser#define S_IP		48
63684ad6884SPeter Tyser#define S_FP		44
63784ad6884SPeter Tyser#define S_R10		40
63884ad6884SPeter Tyser#define S_R9		36
63984ad6884SPeter Tyser#define S_R8		32
64084ad6884SPeter Tyser#define S_R7		28
64184ad6884SPeter Tyser#define S_R6		24
64284ad6884SPeter Tyser#define S_R5		20
64384ad6884SPeter Tyser#define S_R4		16
64484ad6884SPeter Tyser#define S_R3		12
64584ad6884SPeter Tyser#define S_R2		8
64684ad6884SPeter Tyser#define S_R1		4
64784ad6884SPeter Tyser#define S_R0		0
64884ad6884SPeter Tyser
64984ad6884SPeter Tyser#define MODE_SVC 0x13
65084ad6884SPeter Tyser#define I_BIT	 0x80
65184ad6884SPeter Tyser
65284ad6884SPeter Tyser/*
65384ad6884SPeter Tyser * use bad_save_user_regs for abort/prefetch/undef/swi ...
65484ad6884SPeter Tyser */
65584ad6884SPeter Tyser
65684ad6884SPeter Tyser	.macro	bad_save_user_regs
65784ad6884SPeter Tyser	/* carve out a frame on current user stack */
65884ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
65984ad6884SPeter Tyser	/* Save user registers (now in svc mode) r0-r12 */
66084ad6884SPeter Tyser	stmia	sp, {r0 - r12}
66184ad6884SPeter Tyser
662*a51dd67aSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
66384ad6884SPeter Tyser	ldr	r2, _armboot_start
66484ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_SYS_MALLOC_LEN)
66584ad6884SPeter Tyser	/* set base 2 words into abort stack */
66684ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
667*a51dd67aSHeiko Schocher#else
668*a51dd67aSHeiko Schocher	ldr	r2, IRQ_STACK_START_IN
669*a51dd67aSHeiko Schocher#endif
67084ad6884SPeter Tyser	/* get values for "aborted" pc and cpsr (into parm regs) */
67184ad6884SPeter Tyser	ldmia	r2, {r2 - r3}
67284ad6884SPeter Tyser	/* grab pointer to old stack */
67384ad6884SPeter Tyser	add	r0, sp, #S_FRAME_SIZE
67484ad6884SPeter Tyser
67584ad6884SPeter Tyser	add	r5, sp, #S_SP
67684ad6884SPeter Tyser	mov	r1, lr
67784ad6884SPeter Tyser	/* save sp_SVC, lr_SVC, pc, cpsr */
67884ad6884SPeter Tyser	stmia	r5, {r0 - r3}
67984ad6884SPeter Tyser	/* save current stack into r0 (param register) */
68084ad6884SPeter Tyser	mov	r0, sp
68184ad6884SPeter Tyser	.endm
68284ad6884SPeter Tyser
68384ad6884SPeter Tyser	.macro get_bad_stack
684*a51dd67aSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
68584ad6884SPeter Tyser	/* setup our mode stack (enter in banked mode) */
68684ad6884SPeter Tyser	ldr	r13, _armboot_start
68784ad6884SPeter Tyser	/* move past malloc pool */
68884ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_SYS_MALLOC_LEN)
68984ad6884SPeter Tyser	/* move to reserved a couple spots for abort stack */
69084ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
691*a51dd67aSHeiko Schocher#else
692*a51dd67aSHeiko Schocher	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
693*a51dd67aSHeiko Schocher#endif
69484ad6884SPeter Tyser
69584ad6884SPeter Tyser	/* save caller lr in position 0 of saved stack */
69684ad6884SPeter Tyser	str	lr, [r13]
69784ad6884SPeter Tyser	/* get the spsr */
69884ad6884SPeter Tyser	mrs	lr, spsr
69984ad6884SPeter Tyser	/* save spsr in position 1 of saved stack */
70084ad6884SPeter Tyser	str	lr, [r13, #4]
70184ad6884SPeter Tyser
70284ad6884SPeter Tyser	/* prepare SVC-Mode */
70384ad6884SPeter Tyser	mov	r13, #MODE_SVC
70484ad6884SPeter Tyser	@ msr	spsr_c, r13
70584ad6884SPeter Tyser	/* switch modes, make sure moves will execute */
70684ad6884SPeter Tyser	msr	spsr, r13
70784ad6884SPeter Tyser	/* capture return pc */
70884ad6884SPeter Tyser	mov	lr, pc
70984ad6884SPeter Tyser	/* jump to next instruction & switch modes. */
71084ad6884SPeter Tyser	movs	pc, lr
71184ad6884SPeter Tyser	.endm
71284ad6884SPeter Tyser
71384ad6884SPeter Tyser	.macro get_bad_stack_swi
71484ad6884SPeter Tyser	/* space on current stack for scratch reg. */
71584ad6884SPeter Tyser	sub	r13, r13, #4
71684ad6884SPeter Tyser	/* save R0's value. */
71784ad6884SPeter Tyser	str	r0, [r13]
718*a51dd67aSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
71984ad6884SPeter Tyser	/* get data regions start */
72084ad6884SPeter Tyser	ldr	r0, _armboot_start
72184ad6884SPeter Tyser	/* move past malloc pool */
72284ad6884SPeter Tyser	sub	r0, r0, #(CONFIG_SYS_MALLOC_LEN)
72384ad6884SPeter Tyser	/* move past gbl and a couple spots for abort stack */
72484ad6884SPeter Tyser	sub	r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
725*a51dd67aSHeiko Schocher#else
726*a51dd67aSHeiko Schocher	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
727*a51dd67aSHeiko Schocher#endif
72884ad6884SPeter Tyser	/* save caller lr in position 0 of saved stack */
72984ad6884SPeter Tyser	str	lr, [r0]
73084ad6884SPeter Tyser	/* get the spsr */
73184ad6884SPeter Tyser	mrs	r0, spsr
73284ad6884SPeter Tyser	/* save spsr in position 1 of saved stack */
73384ad6884SPeter Tyser	str	lr, [r0, #4]
73484ad6884SPeter Tyser	/* restore r0 */
73584ad6884SPeter Tyser	ldr	r0, [r13]
73684ad6884SPeter Tyser	/* pop stack entry */
73784ad6884SPeter Tyser	add	r13, r13, #4
73884ad6884SPeter Tyser	.endm
73984ad6884SPeter Tyser
74084ad6884SPeter Tyser/*
74184ad6884SPeter Tyser * exception handlers
74284ad6884SPeter Tyser */
74384ad6884SPeter Tyser	.align	5
74484ad6884SPeter Tyserundefined_instruction:
74584ad6884SPeter Tyser	get_bad_stack
74684ad6884SPeter Tyser	bad_save_user_regs
74784ad6884SPeter Tyser	bl	do_undefined_instruction
74884ad6884SPeter Tyser
74984ad6884SPeter Tyser	.align	5
75084ad6884SPeter Tysersoftware_interrupt:
75184ad6884SPeter Tyser	get_bad_stack_swi
75284ad6884SPeter Tyser	bad_save_user_regs
75384ad6884SPeter Tyser	bl	do_software_interrupt
75484ad6884SPeter Tyser
75584ad6884SPeter Tyser	.align	5
75684ad6884SPeter Tyserprefetch_abort:
75784ad6884SPeter Tyser	get_bad_stack
75884ad6884SPeter Tyser	bad_save_user_regs
75984ad6884SPeter Tyser	bl	do_prefetch_abort
76084ad6884SPeter Tyser
76184ad6884SPeter Tyser	.align	5
76284ad6884SPeter Tyserdata_abort:
76384ad6884SPeter Tyser	get_bad_stack
76484ad6884SPeter Tyser	bad_save_user_regs
76584ad6884SPeter Tyser	bl	do_data_abort
76684ad6884SPeter Tyser
76784ad6884SPeter Tyser	.align	5
76884ad6884SPeter Tysernot_used:
76984ad6884SPeter Tyser	get_bad_stack
77084ad6884SPeter Tyser	bad_save_user_regs
77184ad6884SPeter Tyser	bl	do_not_used
77284ad6884SPeter Tyser
77384ad6884SPeter Tyser	.align	5
77484ad6884SPeter Tyserirq:
77584ad6884SPeter Tyser	get_bad_stack
77684ad6884SPeter Tyser	bad_save_user_regs
77784ad6884SPeter Tyser	bl	do_irq
77884ad6884SPeter Tyser
77984ad6884SPeter Tyser	.align	5
78084ad6884SPeter Tyserfiq:
78184ad6884SPeter Tyser	get_bad_stack
78284ad6884SPeter Tyser	bad_save_user_regs
78384ad6884SPeter Tyser	bl	do_fiq
78484ad6884SPeter Tyser#endif /* CONFIG_NAND_SPL */
785