xref: /rk3399_rockchip-uboot/arch/arm/cpu/armv7/start.S (revision 7cbe638e41cd4cf199bfb7798fe572ddf3a39f0a)
1f56348afSSteve Sakoman/*
2f56348afSSteve Sakoman * armboot - Startup Code for OMAP3530/ARM Cortex CPU-core
3f56348afSSteve Sakoman *
4f56348afSSteve Sakoman * Copyright (c) 2004	Texas Instruments <r-woodruff2@ti.com>
5f56348afSSteve Sakoman *
6f56348afSSteve Sakoman * Copyright (c) 2001	Marius Gröger <mag@sysgo.de>
7f56348afSSteve Sakoman * Copyright (c) 2002	Alex Züpke <azu@sysgo.de>
8f56348afSSteve Sakoman * Copyright (c) 2002	Gary Jennejohn <garyj@denx.de>
9f56348afSSteve Sakoman * Copyright (c) 2003	Richard Woodruff <r-woodruff2@ti.com>
10f56348afSSteve Sakoman * Copyright (c) 2003	Kshitij <kshitij@ti.com>
11f56348afSSteve Sakoman * Copyright (c) 2006-2008 Syed Mohammed Khasim <x0khasim@ti.com>
12f56348afSSteve Sakoman *
131a459660SWolfgang Denk * SPDX-License-Identifier:	GPL-2.0+
14f56348afSSteve Sakoman */
15f56348afSSteve Sakoman
1625ddd1fbSWolfgang Denk#include <asm-offsets.h>
17f56348afSSteve Sakoman#include <config.h>
18f56348afSSteve Sakoman#include <version.h>
19a8c68639SAneesh V#include <asm/system.h>
2074236acaSAneesh V#include <linux/linkage.h>
21f56348afSSteve Sakoman
22f56348afSSteve Sakoman.globl _start
23f56348afSSteve Sakoman_start: b	reset
24f56348afSSteve Sakoman	ldr	pc, _undefined_instruction
25f56348afSSteve Sakoman	ldr	pc, _software_interrupt
26f56348afSSteve Sakoman	ldr	pc, _prefetch_abort
27f56348afSSteve Sakoman	ldr	pc, _data_abort
28f56348afSSteve Sakoman	ldr	pc, _not_used
29f56348afSSteve Sakoman	ldr	pc, _irq
30f56348afSSteve Sakoman	ldr	pc, _fiq
31033ca724SAneesh V#ifdef CONFIG_SPL_BUILD
32033ca724SAneesh V_undefined_instruction: .word _undefined_instruction
33033ca724SAneesh V_software_interrupt:	.word _software_interrupt
34033ca724SAneesh V_prefetch_abort:	.word _prefetch_abort
35033ca724SAneesh V_data_abort:		.word _data_abort
36033ca724SAneesh V_not_used:		.word _not_used
37033ca724SAneesh V_irq:			.word _irq
38033ca724SAneesh V_fiq:			.word _fiq
39033ca724SAneesh V_pad:			.word 0x12345678 /* now 16*4=64 */
40033ca724SAneesh V#else
41*7cbe638eSMarek Vasut.globl _undefined_instruction
42f56348afSSteve Sakoman_undefined_instruction: .word undefined_instruction
43*7cbe638eSMarek Vasut.globl _software_interrupt
44f56348afSSteve Sakoman_software_interrupt:	.word software_interrupt
45*7cbe638eSMarek Vasut.globl _prefetch_abort
46f56348afSSteve Sakoman_prefetch_abort:	.word prefetch_abort
47*7cbe638eSMarek Vasut.globl _data_abort
48f56348afSSteve Sakoman_data_abort:		.word data_abort
49*7cbe638eSMarek Vasut.globl _not_used
50f56348afSSteve Sakoman_not_used:		.word not_used
51*7cbe638eSMarek Vasut.globl _irq
52f56348afSSteve Sakoman_irq:			.word irq
53*7cbe638eSMarek Vasut.globl _fiq
54f56348afSSteve Sakoman_fiq:			.word fiq
55f56348afSSteve Sakoman_pad:			.word 0x12345678 /* now 16*4=64 */
56033ca724SAneesh V#endif	/* CONFIG_SPL_BUILD */
57033ca724SAneesh V
58f56348afSSteve Sakoman.global _end_vect
59f56348afSSteve Sakoman_end_vect:
60f56348afSSteve Sakoman
61f56348afSSteve Sakoman	.balignl 16,0xdeadbeef
62f56348afSSteve Sakoman/*************************************************************************
63f56348afSSteve Sakoman *
64f56348afSSteve Sakoman * Startup Code (reset vector)
65f56348afSSteve Sakoman *
66f56348afSSteve Sakoman * do important init only if we don't start from memory!
67f56348afSSteve Sakoman * setup Memory and board specific bits prior to relocation.
68f56348afSSteve Sakoman * relocate armboot to ram
69f56348afSSteve Sakoman * setup stack
70f56348afSSteve Sakoman *
71f56348afSSteve Sakoman *************************************************************************/
72f56348afSSteve Sakoman
73561142afSHeiko Schocher.globl _TEXT_BASE
74f56348afSSteve Sakoman_TEXT_BASE:
75508611bcSBenoît Thébaudeau#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
76508611bcSBenoît Thébaudeau	.word	CONFIG_SPL_TEXT_BASE
77508611bcSBenoît Thébaudeau#else
7814d0a02aSWolfgang Denk	.word	CONFIG_SYS_TEXT_BASE
79508611bcSBenoît Thébaudeau#endif
80f56348afSSteve Sakoman
81f56348afSSteve Sakoman/*
82f56348afSSteve Sakoman * These are defined in the board-specific linker script.
83f56348afSSteve Sakoman */
84c3d3a541SHeiko Schocher.globl _bss_start_ofs
85c3d3a541SHeiko Schocher_bss_start_ofs:
86c3d3a541SHeiko Schocher	.word __bss_start - _start
87f56348afSSteve Sakoman
88c3d3a541SHeiko Schocher.globl _bss_end_ofs
89c3d3a541SHeiko Schocher_bss_end_ofs:
903929fb0aSSimon Glass	.word __bss_end - _start
91f56348afSSteve Sakoman
92f326cbbaSPo-Yu Chuang.globl _end_ofs
93f326cbbaSPo-Yu Chuang_end_ofs:
94f326cbbaSPo-Yu Chuang	.word _end - _start
95f326cbbaSPo-Yu Chuang
96f56348afSSteve Sakoman#ifdef CONFIG_USE_IRQ
97f56348afSSteve Sakoman/* IRQ stack memory (calculated at run-time) */
98f56348afSSteve Sakoman.globl IRQ_STACK_START
99f56348afSSteve SakomanIRQ_STACK_START:
100f56348afSSteve Sakoman	.word	0x0badc0de
101f56348afSSteve Sakoman
102f56348afSSteve Sakoman/* IRQ stack memory (calculated at run-time) */
103f56348afSSteve Sakoman.globl FIQ_STACK_START
104f56348afSSteve SakomanFIQ_STACK_START:
105f56348afSSteve Sakoman	.word 0x0badc0de
106f56348afSSteve Sakoman#endif
107f56348afSSteve Sakoman
108561142afSHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */
109561142afSHeiko Schocher.globl IRQ_STACK_START_IN
110561142afSHeiko SchocherIRQ_STACK_START_IN:
111561142afSHeiko Schocher	.word	0x0badc0de
112561142afSHeiko Schocher
113561142afSHeiko Schocher/*
114561142afSHeiko Schocher * the actual reset code
115561142afSHeiko Schocher */
116561142afSHeiko Schocher
117561142afSHeiko Schocherreset:
1188cf686e1SAneesh V	bl	save_boot_params
119561142afSHeiko Schocher	/*
120c4a4e2e2SAndre Przywara	 * disable interrupts (FIQ and IRQ), also set the cpu to SVC32 mode,
121c4a4e2e2SAndre Przywara	 * except if in HYP mode already
122561142afSHeiko Schocher	 */
123561142afSHeiko Schocher	mrs	r0, cpsr
124c4a4e2e2SAndre Przywara	and	r1, r0, #0x1f		@ mask mode bits
125c4a4e2e2SAndre Przywara	teq	r1, #0x1a		@ test for HYP mode
126c4a4e2e2SAndre Przywara	bicne	r0, r0, #0x1f		@ clear all mode bits
127c4a4e2e2SAndre Przywara	orrne	r0, r0, #0x13		@ set SVC mode
128c4a4e2e2SAndre Przywara	orr	r0, r0, #0xc0		@ disable FIQ and IRQ
129561142afSHeiko Schocher	msr	cpsr,r0
130561142afSHeiko Schocher
131a8c68639SAneesh V/*
132a8c68639SAneesh V * Setup vector:
133a8c68639SAneesh V * (OMAP4 spl TEXT_BASE is not 32 byte aligned.
134a8c68639SAneesh V * Continue to use ROM code vector only in OMAP4 spl)
135a8c68639SAneesh V */
136a8c68639SAneesh V#if !(defined(CONFIG_OMAP44XX) && defined(CONFIG_SPL_BUILD))
137a8c68639SAneesh V	/* Set V=0 in CP15 SCTRL register - for VBAR to point to vector */
138a8c68639SAneesh V	mrc	p15, 0, r0, c1, c0, 0	@ Read CP15 SCTRL Register
139a8c68639SAneesh V	bic	r0, #CR_V		@ V = 0
140a8c68639SAneesh V	mcr	p15, 0, r0, c1, c0, 0	@ Write CP15 SCTRL Register
141a8c68639SAneesh V
142a8c68639SAneesh V	/* Set vector address in CP15 VBAR register */
143a8c68639SAneesh V	ldr	r0, =_start
144a8c68639SAneesh V	mcr	p15, 0, r0, c12, c0, 0	@Set VBAR
145a8c68639SAneesh V#endif
146a8c68639SAneesh V
147561142afSHeiko Schocher	/* the mask ROM code should have PLL and others stable */
148561142afSHeiko Schocher#ifndef CONFIG_SKIP_LOWLEVEL_INIT
14980433c9aSSimon Glass	bl	cpu_init_cp15
150561142afSHeiko Schocher	bl	cpu_init_crit
151561142afSHeiko Schocher#endif
152561142afSHeiko Schocher
153e05e5de7SAlbert ARIBAUD	bl	_main
154561142afSHeiko Schocher
155561142afSHeiko Schocher/*------------------------------------------------------------------------------*/
156561142afSHeiko Schocher
157e05e5de7SAlbert ARIBAUDENTRY(c_runtime_cpu_setup)
158c2dd0d45SAneesh V/*
159c2dd0d45SAneesh V * If I-cache is enabled invalidate it
160c2dd0d45SAneesh V */
161c2dd0d45SAneesh V#ifndef CONFIG_SYS_ICACHE_OFF
162c2dd0d45SAneesh V	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
163c2dd0d45SAneesh V	mcr     p15, 0, r0, c7, c10, 4	@ DSB
164c2dd0d45SAneesh V	mcr     p15, 0, r0, c7, c5, 4	@ ISB
165c2dd0d45SAneesh V#endif
166f8b9d1d3STetsuyuki Kobayashi/*
167f8b9d1d3STetsuyuki Kobayashi * Move vector table
168f8b9d1d3STetsuyuki Kobayashi */
169f8b9d1d3STetsuyuki Kobayashi	/* Set vector address in CP15 VBAR register */
170f8b9d1d3STetsuyuki Kobayashi	ldr     r0, =_start
171f8b9d1d3STetsuyuki Kobayashi	mcr     p15, 0, r0, c12, c0, 0  @Set VBAR
172f8b9d1d3STetsuyuki Kobayashi
173e05e5de7SAlbert ARIBAUD	bx	lr
174561142afSHeiko Schocher
175e05e5de7SAlbert ARIBAUDENDPROC(c_runtime_cpu_setup)
176c3d3a541SHeiko Schocher
177f56348afSSteve Sakoman/*************************************************************************
178f56348afSSteve Sakoman *
1796f0dba85STetsuyuki Kobayashi * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
1806f0dba85STetsuyuki Kobayashi *	__attribute__((weak));
1816f0dba85STetsuyuki Kobayashi *
1826f0dba85STetsuyuki Kobayashi * Stack pointer is not yet initialized at this moment
1836f0dba85STetsuyuki Kobayashi * Don't save anything to stack even if compiled with -O0
1846f0dba85STetsuyuki Kobayashi *
1856f0dba85STetsuyuki Kobayashi *************************************************************************/
1866f0dba85STetsuyuki KobayashiENTRY(save_boot_params)
1876f0dba85STetsuyuki Kobayashi	bx	lr			@ back to my caller
1886f0dba85STetsuyuki KobayashiENDPROC(save_boot_params)
1896f0dba85STetsuyuki Kobayashi	.weak	save_boot_params
1906f0dba85STetsuyuki Kobayashi
1916f0dba85STetsuyuki Kobayashi/*************************************************************************
1926f0dba85STetsuyuki Kobayashi *
19380433c9aSSimon Glass * cpu_init_cp15
194f56348afSSteve Sakoman *
19580433c9aSSimon Glass * Setup CP15 registers (cache, MMU, TLBs). The I-cache is turned on unless
19680433c9aSSimon Glass * CONFIG_SYS_ICACHE_OFF is defined.
197f56348afSSteve Sakoman *
198f56348afSSteve Sakoman *************************************************************************/
19974236acaSAneesh VENTRY(cpu_init_cp15)
200f56348afSSteve Sakoman	/*
201f56348afSSteve Sakoman	 * Invalidate L1 I/D
202f56348afSSteve Sakoman	 */
203f56348afSSteve Sakoman	mov	r0, #0			@ set up for MCR
204f56348afSSteve Sakoman	mcr	p15, 0, r0, c8, c7, 0	@ invalidate TLBs
205f56348afSSteve Sakoman	mcr	p15, 0, r0, c7, c5, 0	@ invalidate icache
206c2dd0d45SAneesh V	mcr	p15, 0, r0, c7, c5, 6	@ invalidate BP array
207c2dd0d45SAneesh V	mcr     p15, 0, r0, c7, c10, 4	@ DSB
208c2dd0d45SAneesh V	mcr     p15, 0, r0, c7, c5, 4	@ ISB
209f56348afSSteve Sakoman
210f56348afSSteve Sakoman	/*
211f56348afSSteve Sakoman	 * disable MMU stuff and caches
212f56348afSSteve Sakoman	 */
213f56348afSSteve Sakoman	mrc	p15, 0, r0, c1, c0, 0
214f56348afSSteve Sakoman	bic	r0, r0, #0x00002000	@ clear bits 13 (--V-)
215f56348afSSteve Sakoman	bic	r0, r0, #0x00000007	@ clear bits 2:0 (-CAM)
216f56348afSSteve Sakoman	orr	r0, r0, #0x00000002	@ set bit 1 (--A-) Align
217c2dd0d45SAneesh V	orr	r0, r0, #0x00000800	@ set bit 11 (Z---) BTB
218c2dd0d45SAneesh V#ifdef CONFIG_SYS_ICACHE_OFF
219c2dd0d45SAneesh V	bic	r0, r0, #0x00001000	@ clear bit 12 (I) I-cache
220c2dd0d45SAneesh V#else
221c2dd0d45SAneesh V	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-cache
222c2dd0d45SAneesh V#endif
223f56348afSSteve Sakoman	mcr	p15, 0, r0, c1, c0, 0
2240678587fSStephen Warren
225c5d4752cSStephen Warren#ifdef CONFIG_ARM_ERRATA_716044
226c5d4752cSStephen Warren	mrc	p15, 0, r0, c1, c0, 0	@ read system control register
227c5d4752cSStephen Warren	orr	r0, r0, #1 << 11	@ set bit #11
228c5d4752cSStephen Warren	mcr	p15, 0, r0, c1, c0, 0	@ write system control register
229c5d4752cSStephen Warren#endif
230c5d4752cSStephen Warren
2310678587fSStephen Warren#ifdef CONFIG_ARM_ERRATA_742230
2320678587fSStephen Warren	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
2330678587fSStephen Warren	orr	r0, r0, #1 << 4		@ set bit #4
2340678587fSStephen Warren	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
2350678587fSStephen Warren#endif
2360678587fSStephen Warren
2370678587fSStephen Warren#ifdef CONFIG_ARM_ERRATA_743622
2380678587fSStephen Warren	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
2390678587fSStephen Warren	orr	r0, r0, #1 << 6		@ set bit #6
2400678587fSStephen Warren	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
2410678587fSStephen Warren#endif
2420678587fSStephen Warren
2430678587fSStephen Warren#ifdef CONFIG_ARM_ERRATA_751472
2440678587fSStephen Warren	mrc	p15, 0, r0, c15, c0, 1	@ read diagnostic register
2450678587fSStephen Warren	orr	r0, r0, #1 << 11	@ set bit #11
2460678587fSStephen Warren	mcr	p15, 0, r0, c15, c0, 1	@ write diagnostic register
2470678587fSStephen Warren#endif
2480678587fSStephen Warren
24980433c9aSSimon Glass	mov	pc, lr			@ back to my caller
25074236acaSAneesh VENDPROC(cpu_init_cp15)
25180433c9aSSimon Glass
25280433c9aSSimon Glass#ifndef CONFIG_SKIP_LOWLEVEL_INIT
25380433c9aSSimon Glass/*************************************************************************
25480433c9aSSimon Glass *
25580433c9aSSimon Glass * CPU_init_critical registers
25680433c9aSSimon Glass *
25780433c9aSSimon Glass * setup important registers
25880433c9aSSimon Glass * setup memory timing
25980433c9aSSimon Glass *
26080433c9aSSimon Glass *************************************************************************/
26174236acaSAneesh VENTRY(cpu_init_crit)
262f56348afSSteve Sakoman	/*
263f56348afSSteve Sakoman	 * Jump to board specific initialization...
264f56348afSSteve Sakoman	 * The Mask ROM will have already initialized
265f56348afSSteve Sakoman	 * basic memory. Go here to bump up clock rate and handle
266f56348afSSteve Sakoman	 * wake up conditions.
267f56348afSSteve Sakoman	 */
26863ee53a7SBenoît Thébaudeau	b	lowlevel_init		@ go setup pll,mux,memory
26974236acaSAneesh VENDPROC(cpu_init_crit)
27022193540SRob Herring#endif
271033ca724SAneesh V
272033ca724SAneesh V#ifndef CONFIG_SPL_BUILD
273f56348afSSteve Sakoman/*
274f56348afSSteve Sakoman *************************************************************************
275f56348afSSteve Sakoman *
276f56348afSSteve Sakoman * Interrupt handling
277f56348afSSteve Sakoman *
278f56348afSSteve Sakoman *************************************************************************
279f56348afSSteve Sakoman */
280f56348afSSteve Sakoman@
281f56348afSSteve Sakoman@ IRQ stack frame.
282f56348afSSteve Sakoman@
283f56348afSSteve Sakoman#define S_FRAME_SIZE	72
284f56348afSSteve Sakoman
285f56348afSSteve Sakoman#define S_OLD_R0	68
286f56348afSSteve Sakoman#define S_PSR		64
287f56348afSSteve Sakoman#define S_PC		60
288f56348afSSteve Sakoman#define S_LR		56
289f56348afSSteve Sakoman#define S_SP		52
290f56348afSSteve Sakoman
291f56348afSSteve Sakoman#define S_IP		48
292f56348afSSteve Sakoman#define S_FP		44
293f56348afSSteve Sakoman#define S_R10		40
294f56348afSSteve Sakoman#define S_R9		36
295f56348afSSteve Sakoman#define S_R8		32
296f56348afSSteve Sakoman#define S_R7		28
297f56348afSSteve Sakoman#define S_R6		24
298f56348afSSteve Sakoman#define S_R5		20
299f56348afSSteve Sakoman#define S_R4		16
300f56348afSSteve Sakoman#define S_R3		12
301f56348afSSteve Sakoman#define S_R2		8
302f56348afSSteve Sakoman#define S_R1		4
303f56348afSSteve Sakoman#define S_R0		0
304f56348afSSteve Sakoman
305f56348afSSteve Sakoman#define MODE_SVC 0x13
306f56348afSSteve Sakoman#define I_BIT	 0x80
307f56348afSSteve Sakoman
308f56348afSSteve Sakoman/*
309f56348afSSteve Sakoman * use bad_save_user_regs for abort/prefetch/undef/swi ...
310f56348afSSteve Sakoman * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
311f56348afSSteve Sakoman */
312f56348afSSteve Sakoman
313f56348afSSteve Sakoman	.macro	bad_save_user_regs
314f56348afSSteve Sakoman	sub	sp, sp, #S_FRAME_SIZE		@ carve out a frame on current
315f56348afSSteve Sakoman						@ user stack
316f56348afSSteve Sakoman	stmia	sp, {r0 - r12}			@ Save user registers (now in
317f56348afSSteve Sakoman						@ svc mode) r0-r12
318561142afSHeiko Schocher	ldr	r2, IRQ_STACK_START_IN		@ set base 2 words into abort
319f56348afSSteve Sakoman						@ stack
320f56348afSSteve Sakoman	ldmia	r2, {r2 - r3}			@ get values for "aborted" pc
321f56348afSSteve Sakoman						@ and cpsr (into parm regs)
322f56348afSSteve Sakoman	add	r0, sp, #S_FRAME_SIZE		@ grab pointer to old stack
323f56348afSSteve Sakoman
324f56348afSSteve Sakoman	add	r5, sp, #S_SP
325f56348afSSteve Sakoman	mov	r1, lr
326f56348afSSteve Sakoman	stmia	r5, {r0 - r3}			@ save sp_SVC, lr_SVC, pc, cpsr
327f56348afSSteve Sakoman	mov	r0, sp				@ save current stack into r0
328f56348afSSteve Sakoman						@ (param register)
329f56348afSSteve Sakoman	.endm
330f56348afSSteve Sakoman
331f56348afSSteve Sakoman	.macro	irq_save_user_regs
332f56348afSSteve Sakoman	sub	sp, sp, #S_FRAME_SIZE
333f56348afSSteve Sakoman	stmia	sp, {r0 - r12}			@ Calling r0-r12
334f56348afSSteve Sakoman	add	r8, sp, #S_PC			@ !! R8 NEEDS to be saved !!
335f56348afSSteve Sakoman						@ a reserved stack spot would
336f56348afSSteve Sakoman						@ be good.
337f56348afSSteve Sakoman	stmdb	r8, {sp, lr}^			@ Calling SP, LR
338f56348afSSteve Sakoman	str	lr, [r8, #0]			@ Save calling PC
339f56348afSSteve Sakoman	mrs	r6, spsr
340f56348afSSteve Sakoman	str	r6, [r8, #4]			@ Save CPSR
341f56348afSSteve Sakoman	str	r0, [r8, #8]			@ Save OLD_R0
342f56348afSSteve Sakoman	mov	r0, sp
343f56348afSSteve Sakoman	.endm
344f56348afSSteve Sakoman
345f56348afSSteve Sakoman	.macro	irq_restore_user_regs
346f56348afSSteve Sakoman	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
347f56348afSSteve Sakoman	mov	r0, r0
348f56348afSSteve Sakoman	ldr	lr, [sp, #S_PC]			@ Get PC
349f56348afSSteve Sakoman	add	sp, sp, #S_FRAME_SIZE
350f56348afSSteve Sakoman	subs	pc, lr, #4			@ return & move spsr_svc into
351f56348afSSteve Sakoman						@ cpsr
352f56348afSSteve Sakoman	.endm
353f56348afSSteve Sakoman
354f56348afSSteve Sakoman	.macro get_bad_stack
355561142afSHeiko Schocher	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack (enter
356561142afSHeiko Schocher						@ in banked mode)
357f56348afSSteve Sakoman
358f56348afSSteve Sakoman	str	lr, [r13]			@ save caller lr in position 0
359f56348afSSteve Sakoman						@ of saved stack
360f56348afSSteve Sakoman	mrs	lr, spsr			@ get the spsr
361f56348afSSteve Sakoman	str	lr, [r13, #4]			@ save spsr in position 1 of
362f56348afSSteve Sakoman						@ saved stack
363f56348afSSteve Sakoman
364f56348afSSteve Sakoman	mov	r13, #MODE_SVC			@ prepare SVC-Mode
365f56348afSSteve Sakoman	@ msr	spsr_c, r13
366f56348afSSteve Sakoman	msr	spsr, r13			@ switch modes, make sure
367f56348afSSteve Sakoman						@ moves will execute
368f56348afSSteve Sakoman	mov	lr, pc				@ capture return pc
369f56348afSSteve Sakoman	movs	pc, lr				@ jump to next instruction &
370f56348afSSteve Sakoman						@ switch modes.
371f56348afSSteve Sakoman	.endm
372f56348afSSteve Sakoman
373f56348afSSteve Sakoman	.macro get_bad_stack_swi
374f56348afSSteve Sakoman	sub	r13, r13, #4			@ space on current stack for
375f56348afSSteve Sakoman						@ scratch reg.
376f56348afSSteve Sakoman	str	r0, [r13]			@ save R0's value.
377561142afSHeiko Schocher	ldr	r0, IRQ_STACK_START_IN		@ get data regions start
378f56348afSSteve Sakoman						@ spots for abort stack
379f56348afSSteve Sakoman	str	lr, [r0]			@ save caller lr in position 0
380f56348afSSteve Sakoman						@ of saved stack
3814411b2aeSTetsuyuki Kobayashi	mrs	lr, spsr			@ get the spsr
382f56348afSSteve Sakoman	str	lr, [r0, #4]			@ save spsr in position 1 of
383f56348afSSteve Sakoman						@ saved stack
3844411b2aeSTetsuyuki Kobayashi	ldr	lr, [r0]			@ restore lr
385f56348afSSteve Sakoman	ldr	r0, [r13]			@ restore r0
386f56348afSSteve Sakoman	add	r13, r13, #4			@ pop stack entry
387f56348afSSteve Sakoman	.endm
388f56348afSSteve Sakoman
389f56348afSSteve Sakoman	.macro get_irq_stack			@ setup IRQ stack
390f56348afSSteve Sakoman	ldr	sp, IRQ_STACK_START
391f56348afSSteve Sakoman	.endm
392f56348afSSteve Sakoman
393f56348afSSteve Sakoman	.macro get_fiq_stack			@ setup FIQ stack
394f56348afSSteve Sakoman	ldr	sp, FIQ_STACK_START
395f56348afSSteve Sakoman	.endm
396f56348afSSteve Sakoman
397f56348afSSteve Sakoman/*
398f56348afSSteve Sakoman * exception handlers
399f56348afSSteve Sakoman */
400f56348afSSteve Sakoman	.align	5
401f56348afSSteve Sakomanundefined_instruction:
402f56348afSSteve Sakoman	get_bad_stack
403f56348afSSteve Sakoman	bad_save_user_regs
404f56348afSSteve Sakoman	bl	do_undefined_instruction
405f56348afSSteve Sakoman
406f56348afSSteve Sakoman	.align	5
407f56348afSSteve Sakomansoftware_interrupt:
408f56348afSSteve Sakoman	get_bad_stack_swi
409f56348afSSteve Sakoman	bad_save_user_regs
410f56348afSSteve Sakoman	bl	do_software_interrupt
411f56348afSSteve Sakoman
412f56348afSSteve Sakoman	.align	5
413f56348afSSteve Sakomanprefetch_abort:
414f56348afSSteve Sakoman	get_bad_stack
415f56348afSSteve Sakoman	bad_save_user_regs
416f56348afSSteve Sakoman	bl	do_prefetch_abort
417f56348afSSteve Sakoman
418f56348afSSteve Sakoman	.align	5
419f56348afSSteve Sakomandata_abort:
420f56348afSSteve Sakoman	get_bad_stack
421f56348afSSteve Sakoman	bad_save_user_regs
422f56348afSSteve Sakoman	bl	do_data_abort
423f56348afSSteve Sakoman
424f56348afSSteve Sakoman	.align	5
425f56348afSSteve Sakomannot_used:
426f56348afSSteve Sakoman	get_bad_stack
427f56348afSSteve Sakoman	bad_save_user_regs
428f56348afSSteve Sakoman	bl	do_not_used
429f56348afSSteve Sakoman
430f56348afSSteve Sakoman#ifdef CONFIG_USE_IRQ
431f56348afSSteve Sakoman
432f56348afSSteve Sakoman	.align	5
433f56348afSSteve Sakomanirq:
434f56348afSSteve Sakoman	get_irq_stack
435f56348afSSteve Sakoman	irq_save_user_regs
436f56348afSSteve Sakoman	bl	do_irq
437f56348afSSteve Sakoman	irq_restore_user_regs
438f56348afSSteve Sakoman
439f56348afSSteve Sakoman	.align	5
440f56348afSSteve Sakomanfiq:
441f56348afSSteve Sakoman	get_fiq_stack
442f56348afSSteve Sakoman	/* someone ought to write a more effective fiq_save_user_regs */
443f56348afSSteve Sakoman	irq_save_user_regs
444f56348afSSteve Sakoman	bl	do_fiq
445f56348afSSteve Sakoman	irq_restore_user_regs
446f56348afSSteve Sakoman
447f56348afSSteve Sakoman#else
448f56348afSSteve Sakoman
449f56348afSSteve Sakoman	.align	5
450f56348afSSteve Sakomanirq:
451f56348afSSteve Sakoman	get_bad_stack
452f56348afSSteve Sakoman	bad_save_user_regs
453f56348afSSteve Sakoman	bl	do_irq
454f56348afSSteve Sakoman
455f56348afSSteve Sakoman	.align	5
456f56348afSSteve Sakomanfiq:
457f56348afSSteve Sakoman	get_bad_stack
458f56348afSSteve Sakoman	bad_save_user_regs
459f56348afSSteve Sakoman	bl	do_fiq
460f56348afSSteve Sakoman
461033ca724SAneesh V#endif /* CONFIG_USE_IRQ */
462033ca724SAneesh V#endif /* CONFIG_SPL_BUILD */
463