xref: /rk3399_rockchip-uboot/arch/arm/cpu/arm1176/start.S (revision 678e008c3a3a27fe2d30cf423679d2d11d0fa5c2)
184ad6884SPeter Tyser/*
2*678e008cSCyril 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
9884ad6884SPeter Tyser_TEXT_BASE:
9984ad6884SPeter Tyser	.word	TEXT_BASE
10084ad6884SPeter Tyser
10184ad6884SPeter Tyser/*
10284ad6884SPeter Tyser * Below variable is very important because we use MMU in U-Boot.
10384ad6884SPeter Tyser * Without it, we cannot run code correctly before MMU is ON.
10484ad6884SPeter Tyser * by scsuh.
10584ad6884SPeter Tyser */
10684ad6884SPeter Tyser_TEXT_PHY_BASE:
10784ad6884SPeter Tyser	.word	CONFIG_SYS_PHY_UBOOT_BASE
10884ad6884SPeter Tyser
10984ad6884SPeter Tyser.globl _armboot_start
11084ad6884SPeter Tyser_armboot_start:
11184ad6884SPeter Tyser	.word _start
11284ad6884SPeter Tyser
11384ad6884SPeter Tyser/*
11484ad6884SPeter Tyser * These are defined in the board-specific linker script.
11584ad6884SPeter Tyser */
11684ad6884SPeter Tyser.globl _bss_start
11784ad6884SPeter Tyser_bss_start:
11884ad6884SPeter Tyser	.word __bss_start
11984ad6884SPeter Tyser
12084ad6884SPeter Tyser.globl _bss_end
12184ad6884SPeter Tyser_bss_end:
12284ad6884SPeter Tyser	.word _end
12384ad6884SPeter Tyser
12484ad6884SPeter Tyser/*
12584ad6884SPeter Tyser * the actual reset code
12684ad6884SPeter Tyser */
12784ad6884SPeter Tyser
12884ad6884SPeter Tyserreset:
12984ad6884SPeter Tyser	/*
13084ad6884SPeter Tyser	 * set the cpu to SVC32 mode
13184ad6884SPeter Tyser	 */
13284ad6884SPeter Tyser	mrs	r0, cpsr
13384ad6884SPeter Tyser	bic	r0, r0, #0x3f
13484ad6884SPeter Tyser	orr	r0, r0, #0xd3
13584ad6884SPeter Tyser	msr	cpsr, r0
13684ad6884SPeter Tyser
13784ad6884SPeter Tyser/*
13884ad6884SPeter Tyser *************************************************************************
13984ad6884SPeter Tyser *
14084ad6884SPeter Tyser * CPU_init_critical registers
14184ad6884SPeter Tyser *
14284ad6884SPeter Tyser * setup important registers
14384ad6884SPeter Tyser * setup memory timing
14484ad6884SPeter Tyser *
14584ad6884SPeter Tyser *************************************************************************
14684ad6884SPeter Tyser */
14784ad6884SPeter Tyser	/*
14884ad6884SPeter Tyser	 * we do sys-critical inits only at reboot,
14984ad6884SPeter Tyser	 * not when booting from ram!
15084ad6884SPeter Tyser	 */
15184ad6884SPeter Tysercpu_init_crit:
15284ad6884SPeter Tyser	/*
15384ad6884SPeter Tyser	 * When booting from NAND - it has definitely been a reset, so, no need
15484ad6884SPeter Tyser	 * to flush caches and disable the MMU
15584ad6884SPeter Tyser	 */
15684ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL
15784ad6884SPeter Tyser	/*
15884ad6884SPeter Tyser	 * flush v4 I/D caches
15984ad6884SPeter Tyser	 */
16084ad6884SPeter Tyser	mov	r0, #0
16184ad6884SPeter Tyser	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
16284ad6884SPeter Tyser	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
16384ad6884SPeter Tyser
16484ad6884SPeter Tyser	/*
16584ad6884SPeter Tyser	 * disable MMU stuff and caches
16684ad6884SPeter Tyser	 */
16784ad6884SPeter Tyser	mrc	p15, 0, r0, c1, c0, 0
16884ad6884SPeter Tyser	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
16984ad6884SPeter Tyser	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
17084ad6884SPeter Tyser	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
17184ad6884SPeter Tyser	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
172*678e008cSCyril Chemparathy
17384ad6884SPeter Tyser	/* Prepare to disable the MMU */
174*678e008cSCyril Chemparathy	adr	r2, mmu_disable_phys
175*678e008cSCyril Chemparathy	sub	r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - TEXT_BASE)
17684ad6884SPeter Tyser	b	mmu_disable
17784ad6884SPeter Tyser
17884ad6884SPeter Tyser	.align 5
17984ad6884SPeter Tyser	/* Run in a single cache-line */
18084ad6884SPeter Tysermmu_disable:
18184ad6884SPeter Tyser	mcr	p15, 0, r0, c1, c0, 0
18284ad6884SPeter Tyser	nop
18384ad6884SPeter Tyser	nop
18484ad6884SPeter Tyser	mov	pc, r2
185*678e008cSCyril Chemparathymmu_disable_phys:
186*678e008cSCyril Chemparathy
187*678e008cSCyril Chemparathy#ifdef CONFIG_DISABLE_TCM
188*678e008cSCyril Chemparathy	/*
189*678e008cSCyril Chemparathy	 * Disable the TCMs
190*678e008cSCyril Chemparathy	 */
191*678e008cSCyril Chemparathy	mrc	p15, 0, r0, c0, c0, 2	/* Return TCM details */
192*678e008cSCyril Chemparathy	cmp	r0, #0
193*678e008cSCyril Chemparathy	beq	skip_tcmdisable
194*678e008cSCyril Chemparathy	mov	r1, #0
195*678e008cSCyril Chemparathy	mov	r2, #1
196*678e008cSCyril Chemparathy	tst	r0, r2
197*678e008cSCyril Chemparathy	mcrne	p15, 0, r1, c9, c1, 1	/* Disable Instruction TCM if present*/
198*678e008cSCyril Chemparathy	tst	r0, r2, LSL #16
199*678e008cSCyril Chemparathy	mcrne	p15, 0, r1, c9, c1, 0	/* Disable Data TCM if present*/
200*678e008cSCyril Chemparathyskip_tcmdisable:
201*678e008cSCyril Chemparathy#endif
20284ad6884SPeter Tyser#endif
20384ad6884SPeter Tyser
204*678e008cSCyril Chemparathy#ifdef CONFIG_PERIPORT_REMAP
20584ad6884SPeter Tyser	/* Peri port setup */
206*678e008cSCyril Chemparathy	ldr	r0, =CONFIG_PERIPORT_BASE
207*678e008cSCyril Chemparathy	orr	r0, r0, #CONFIG_PERIPORT_SIZE
208*678e008cSCyril Chemparathy	mcr	p15,0,r0,c15,c2,4
20984ad6884SPeter Tyser#endif
21084ad6884SPeter Tyser
21184ad6884SPeter Tyser	/*
21284ad6884SPeter Tyser	 * Go setup Memory and board specific bits prior to relocation.
21384ad6884SPeter Tyser	 */
21484ad6884SPeter Tyser	bl	lowlevel_init		/* go setup pll,mux,memory */
21584ad6884SPeter Tyser
216*678e008cSCyril Chemparathy#ifndef CONFIG_SKIP_RELOCATE_UBOOT
217*678e008cSCyril Chemparathyrelocate:				/* relocate U-Boot to RAM	    */
218*678e008cSCyril Chemparathy	adr	r0, _start		/* r0 <- current position of code   */
219*678e008cSCyril Chemparathy	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
220*678e008cSCyril Chemparathy	cmp     r0, r1                  /* don't reloc during debug         */
221*678e008cSCyril Chemparathy	beq     stack_setup
222*678e008cSCyril Chemparathy
223*678e008cSCyril Chemparathy	ldr	r2, _armboot_start
224*678e008cSCyril Chemparathy	ldr	r3, _bss_start
225*678e008cSCyril Chemparathy	sub	r2, r3, r2		/* r2 <- size of armboot            */
226*678e008cSCyril Chemparathy	add	r2, r0, r2		/* r2 <- source end address         */
227*678e008cSCyril Chemparathy
228*678e008cSCyril Chemparathycopy_loop:
229*678e008cSCyril Chemparathy	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
230*678e008cSCyril Chemparathy	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
231*678e008cSCyril Chemparathy	cmp	r0, r2			/* until source end addreee [r2]    */
232*678e008cSCyril Chemparathy	ble	copy_loop
233*678e008cSCyril Chemparathy#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
234*678e008cSCyril Chemparathy
23584ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU
23684ad6884SPeter Tyserenable_mmu:
23784ad6884SPeter Tyser	/* enable domain access */
23884ad6884SPeter Tyser	ldr	r5, =0x0000ffff
23984ad6884SPeter Tyser	mcr	p15, 0, r5, c3, c0, 0	/* load domain access register */
24084ad6884SPeter Tyser
24184ad6884SPeter Tyser	/* Set the TTB register */
24284ad6884SPeter Tyser	ldr	r0, _mmu_table_base
24384ad6884SPeter Tyser	ldr	r1, =CONFIG_SYS_PHY_UBOOT_BASE
24484ad6884SPeter Tyser	ldr	r2, =0xfff00000
24584ad6884SPeter Tyser	bic	r0, r0, r2
24684ad6884SPeter Tyser	orr	r1, r0, r1
24784ad6884SPeter Tyser	mcr	p15, 0, r1, c2, c0, 0
24884ad6884SPeter Tyser
24984ad6884SPeter Tyser	/* Enable the MMU */
25084ad6884SPeter Tyser	mrc	p15, 0, r0, c1, c0, 0
25184ad6884SPeter Tyser	orr	r0, r0, #1		/* Set CR_M to enable MMU */
25284ad6884SPeter Tyser
25384ad6884SPeter Tyser	/* Prepare to enable the MMU */
25484ad6884SPeter Tyser	adr	r1, skip_hw_init
25584ad6884SPeter Tyser	and	r1, r1, #0x3fc
25684ad6884SPeter Tyser	ldr	r2, _TEXT_BASE
25784ad6884SPeter Tyser	ldr	r3, =0xfff00000
25884ad6884SPeter Tyser	and	r2, r2, r3
25984ad6884SPeter Tyser	orr	r2, r2, r1
26084ad6884SPeter Tyser	b	mmu_enable
26184ad6884SPeter Tyser
26284ad6884SPeter Tyser	.align 5
26384ad6884SPeter Tyser	/* Run in a single cache-line */
26484ad6884SPeter Tysermmu_enable:
26584ad6884SPeter Tyser
26684ad6884SPeter Tyser	mcr	p15, 0, r0, c1, c0, 0
26784ad6884SPeter Tyser	nop
26884ad6884SPeter Tyser	nop
26984ad6884SPeter Tyser	mov	pc, r2
270*678e008cSCyril Chemparathyskip_hw_init:
27184ad6884SPeter Tyser#endif
27284ad6884SPeter Tyser
27384ad6884SPeter Tyser	/* Set up the stack						    */
27484ad6884SPeter Tyserstack_setup:
27584ad6884SPeter Tyser	ldr	r0, =CONFIG_SYS_UBOOT_BASE	/* base of copy in DRAM	    */
27684ad6884SPeter Tyser	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN	/* malloc area                      */
27784ad6884SPeter Tyser	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                        */
27884ad6884SPeter Tyser	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
27984ad6884SPeter Tyser
28084ad6884SPeter Tyserclear_bss:
28184ad6884SPeter Tyser	ldr	r0, _bss_start		/* find start of bss segment        */
28284ad6884SPeter Tyser	ldr	r1, _bss_end		/* stop here                        */
28384ad6884SPeter Tyser	mov 	r2, #0			/* clear                            */
28484ad6884SPeter Tyser
28584ad6884SPeter Tyserclbss_l:
28684ad6884SPeter Tyser	str	r2, [r0]		/* clear loop...                    */
28784ad6884SPeter Tyser	add	r0, r0, #4
28884ad6884SPeter Tyser	cmp	r0, r1
28984ad6884SPeter Tyser	ble	clbss_l
29084ad6884SPeter Tyser
29184ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL
29284ad6884SPeter Tyser	ldr	pc, _start_armboot
29384ad6884SPeter Tyser
29484ad6884SPeter Tyser_start_armboot:
29584ad6884SPeter Tyser	.word start_armboot
29684ad6884SPeter Tyser#else
29784ad6884SPeter Tyser	b	nand_boot
29884ad6884SPeter Tyser/*	.word nand_boot*/
29984ad6884SPeter Tyser#endif
30084ad6884SPeter Tyser
30184ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU
30284ad6884SPeter Tyser_mmu_table_base:
30384ad6884SPeter Tyser	.word mmu_table
30484ad6884SPeter Tyser#endif
30584ad6884SPeter Tyser
30684ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL
30784ad6884SPeter Tyser/*
30884ad6884SPeter Tyser * we assume that cache operation is done before. (eg. cleanup_before_linux())
30984ad6884SPeter Tyser * actually, we don't need to do anything about cache if not use d-cache in
31084ad6884SPeter Tyser * U-Boot. So, in this function we clean only MMU. by scsuh
31184ad6884SPeter Tyser *
31284ad6884SPeter Tyser * void	theLastJump(void *kernel, int arch_num, uint boot_params);
31384ad6884SPeter Tyser */
31484ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU
31584ad6884SPeter Tyser	.globl theLastJump
31684ad6884SPeter TysertheLastJump:
31784ad6884SPeter Tyser	mov	r9, r0
31884ad6884SPeter Tyser	ldr	r3, =0xfff00000
31984ad6884SPeter Tyser	ldr	r4, _TEXT_PHY_BASE
32084ad6884SPeter Tyser	adr	r5, phy_last_jump
32184ad6884SPeter Tyser	bic	r5, r5, r3
32284ad6884SPeter Tyser	orr	r5, r5, r4
32384ad6884SPeter Tyser	mov	pc, r5
32484ad6884SPeter Tyserphy_last_jump:
32584ad6884SPeter Tyser	/*
32684ad6884SPeter Tyser	 * disable MMU stuff
32784ad6884SPeter Tyser	 */
32884ad6884SPeter Tyser	mrc	p15, 0, r0, c1, c0, 0
32984ad6884SPeter Tyser	bic	r0, r0, #0x00002300	/* clear bits 13, 9:8 (--V- --RS) */
33084ad6884SPeter Tyser	bic	r0, r0, #0x00000087	/* clear bits 7, 2:0 (B--- -CAM) */
33184ad6884SPeter Tyser	orr	r0, r0, #0x00000002	/* set bit 2 (A) Align */
33284ad6884SPeter Tyser	orr	r0, r0, #0x00001000	/* set bit 12 (I) I-Cache */
33384ad6884SPeter Tyser	mcr	p15, 0, r0, c1, c0, 0
33484ad6884SPeter Tyser
33584ad6884SPeter Tyser	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
33684ad6884SPeter Tyser
33784ad6884SPeter Tyser	mov	r0, #0
33884ad6884SPeter Tyser	mov	pc, r9
33984ad6884SPeter Tyser#endif
340*678e008cSCyril Chemparathy
341*678e008cSCyril Chemparathy
34284ad6884SPeter Tyser/*
34384ad6884SPeter Tyser *************************************************************************
34484ad6884SPeter Tyser *
34584ad6884SPeter Tyser * Interrupt handling
34684ad6884SPeter Tyser *
34784ad6884SPeter Tyser *************************************************************************
34884ad6884SPeter Tyser */
34984ad6884SPeter Tyser@
35084ad6884SPeter Tyser@ IRQ stack frame.
35184ad6884SPeter Tyser@
35284ad6884SPeter Tyser#define S_FRAME_SIZE	72
35384ad6884SPeter Tyser
35484ad6884SPeter Tyser#define S_OLD_R0	68
35584ad6884SPeter Tyser#define S_PSR		64
35684ad6884SPeter Tyser#define S_PC		60
35784ad6884SPeter Tyser#define S_LR		56
35884ad6884SPeter Tyser#define S_SP		52
35984ad6884SPeter Tyser
36084ad6884SPeter Tyser#define S_IP		48
36184ad6884SPeter Tyser#define S_FP		44
36284ad6884SPeter Tyser#define S_R10		40
36384ad6884SPeter Tyser#define S_R9		36
36484ad6884SPeter Tyser#define S_R8		32
36584ad6884SPeter Tyser#define S_R7		28
36684ad6884SPeter Tyser#define S_R6		24
36784ad6884SPeter Tyser#define S_R5		20
36884ad6884SPeter Tyser#define S_R4		16
36984ad6884SPeter Tyser#define S_R3		12
37084ad6884SPeter Tyser#define S_R2		8
37184ad6884SPeter Tyser#define S_R1		4
37284ad6884SPeter Tyser#define S_R0		0
37384ad6884SPeter Tyser
37484ad6884SPeter Tyser#define MODE_SVC 0x13
37584ad6884SPeter Tyser#define I_BIT	 0x80
37684ad6884SPeter Tyser
37784ad6884SPeter Tyser/*
37884ad6884SPeter Tyser * use bad_save_user_regs for abort/prefetch/undef/swi ...
37984ad6884SPeter Tyser */
38084ad6884SPeter Tyser
38184ad6884SPeter Tyser	.macro	bad_save_user_regs
38284ad6884SPeter Tyser	/* carve out a frame on current user stack */
38384ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
38484ad6884SPeter Tyser	/* Save user registers (now in svc mode) r0-r12 */
38584ad6884SPeter Tyser	stmia	sp, {r0 - r12}
38684ad6884SPeter Tyser
38784ad6884SPeter Tyser	ldr	r2, _armboot_start
38884ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_SYS_MALLOC_LEN)
38984ad6884SPeter Tyser	/* set base 2 words into abort stack */
39084ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)
39184ad6884SPeter Tyser	/* get values for "aborted" pc and cpsr (into parm regs) */
39284ad6884SPeter Tyser	ldmia	r2, {r2 - r3}
39384ad6884SPeter Tyser	/* grab pointer to old stack */
39484ad6884SPeter Tyser	add	r0, sp, #S_FRAME_SIZE
39584ad6884SPeter Tyser
39684ad6884SPeter Tyser	add	r5, sp, #S_SP
39784ad6884SPeter Tyser	mov	r1, lr
39884ad6884SPeter Tyser	/* save sp_SVC, lr_SVC, pc, cpsr */
39984ad6884SPeter Tyser	stmia	r5, {r0 - r3}
40084ad6884SPeter Tyser	/* save current stack into r0 (param register) */
40184ad6884SPeter Tyser	mov	r0, sp
40284ad6884SPeter Tyser	.endm
40384ad6884SPeter Tyser
40484ad6884SPeter Tyser	.macro get_bad_stack
40584ad6884SPeter Tyser	/* setup our mode stack (enter in banked mode) */
40684ad6884SPeter Tyser	ldr	r13, _armboot_start
40784ad6884SPeter Tyser	/* move past malloc pool */
40884ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_SYS_MALLOC_LEN)
40984ad6884SPeter Tyser	/* move to reserved a couple spots for abort stack */
41084ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
41184ad6884SPeter Tyser
41284ad6884SPeter Tyser	/* save caller lr in position 0 of saved stack */
41384ad6884SPeter Tyser	str	lr, [r13]
41484ad6884SPeter Tyser	/* get the spsr */
41584ad6884SPeter Tyser	mrs	lr, spsr
41684ad6884SPeter Tyser	/* save spsr in position 1 of saved stack */
41784ad6884SPeter Tyser	str	lr, [r13, #4]
41884ad6884SPeter Tyser
41984ad6884SPeter Tyser	/* prepare SVC-Mode */
42084ad6884SPeter Tyser	mov	r13, #MODE_SVC
42184ad6884SPeter Tyser	@ msr	spsr_c, r13
42284ad6884SPeter Tyser	/* switch modes, make sure moves will execute */
42384ad6884SPeter Tyser	msr	spsr, r13
42484ad6884SPeter Tyser	/* capture return pc */
42584ad6884SPeter Tyser	mov	lr, pc
42684ad6884SPeter Tyser	/* jump to next instruction & switch modes. */
42784ad6884SPeter Tyser	movs	pc, lr
42884ad6884SPeter Tyser	.endm
42984ad6884SPeter Tyser
43084ad6884SPeter Tyser	.macro get_bad_stack_swi
43184ad6884SPeter Tyser	/* space on current stack for scratch reg. */
43284ad6884SPeter Tyser	sub	r13, r13, #4
43384ad6884SPeter Tyser	/* save R0's value. */
43484ad6884SPeter Tyser	str	r0, [r13]
43584ad6884SPeter Tyser	/* get data regions start */
43684ad6884SPeter Tyser	ldr	r0, _armboot_start
43784ad6884SPeter Tyser	/* move past malloc pool */
43884ad6884SPeter Tyser	sub	r0, r0, #(CONFIG_SYS_MALLOC_LEN)
43984ad6884SPeter Tyser	/* move past gbl and a couple spots for abort stack */
44084ad6884SPeter Tyser	sub	r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8)
44184ad6884SPeter Tyser	/* save caller lr in position 0 of saved stack */
44284ad6884SPeter Tyser	str	lr, [r0]
44384ad6884SPeter Tyser	/* get the spsr */
44484ad6884SPeter Tyser	mrs	r0, spsr
44584ad6884SPeter Tyser	/* save spsr in position 1 of saved stack */
44684ad6884SPeter Tyser	str	lr, [r0, #4]
44784ad6884SPeter Tyser	/* restore r0 */
44884ad6884SPeter Tyser	ldr	r0, [r13]
44984ad6884SPeter Tyser	/* pop stack entry */
45084ad6884SPeter Tyser	add	r13, r13, #4
45184ad6884SPeter Tyser	.endm
45284ad6884SPeter Tyser
45384ad6884SPeter Tyser/*
45484ad6884SPeter Tyser * exception handlers
45584ad6884SPeter Tyser */
45684ad6884SPeter Tyser	.align	5
45784ad6884SPeter Tyserundefined_instruction:
45884ad6884SPeter Tyser	get_bad_stack
45984ad6884SPeter Tyser	bad_save_user_regs
46084ad6884SPeter Tyser	bl	do_undefined_instruction
46184ad6884SPeter Tyser
46284ad6884SPeter Tyser	.align	5
46384ad6884SPeter Tysersoftware_interrupt:
46484ad6884SPeter Tyser	get_bad_stack_swi
46584ad6884SPeter Tyser	bad_save_user_regs
46684ad6884SPeter Tyser	bl	do_software_interrupt
46784ad6884SPeter Tyser
46884ad6884SPeter Tyser	.align	5
46984ad6884SPeter Tyserprefetch_abort:
47084ad6884SPeter Tyser	get_bad_stack
47184ad6884SPeter Tyser	bad_save_user_regs
47284ad6884SPeter Tyser	bl	do_prefetch_abort
47384ad6884SPeter Tyser
47484ad6884SPeter Tyser	.align	5
47584ad6884SPeter Tyserdata_abort:
47684ad6884SPeter Tyser	get_bad_stack
47784ad6884SPeter Tyser	bad_save_user_regs
47884ad6884SPeter Tyser	bl	do_data_abort
47984ad6884SPeter Tyser
48084ad6884SPeter Tyser	.align	5
48184ad6884SPeter Tysernot_used:
48284ad6884SPeter Tyser	get_bad_stack
48384ad6884SPeter Tyser	bad_save_user_regs
48484ad6884SPeter Tyser	bl	do_not_used
48584ad6884SPeter Tyser
48684ad6884SPeter Tyser	.align	5
48784ad6884SPeter Tyserirq:
48884ad6884SPeter Tyser	get_bad_stack
48984ad6884SPeter Tyser	bad_save_user_regs
49084ad6884SPeter Tyser	bl	do_irq
49184ad6884SPeter Tyser
49284ad6884SPeter Tyser	.align	5
49384ad6884SPeter Tyserfiq:
49484ad6884SPeter Tyser	get_bad_stack
49584ad6884SPeter Tyser	bad_save_user_regs
49684ad6884SPeter Tyser	bl	do_fiq
49784ad6884SPeter Tyser#endif /* CONFIG_NAND_SPL */
498