xref: /openbmc/u-boot/arch/arm/cpu/arm720t/start.S (revision 544d97e9)
1/*
2 *  armboot - Startup Code for ARM720 CPU-core
3 *
4 *  Copyright (c) 2001	Marius Gr�ger <mag@sysgo.de>
5 *  Copyright (c) 2002	Alex Z�pke <azu@sysgo.de>
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 */
25
26
27#include <config.h>
28#include <version.h>
29#include <asm/hardware.h>
30
31/*
32 *************************************************************************
33 *
34 * Jump vector table as in table 3.1 in [1]
35 *
36 *************************************************************************
37 */
38
39
40.globl _start
41_start: b	reset
42	ldr	pc, _undefined_instruction
43	ldr	pc, _software_interrupt
44	ldr	pc, _prefetch_abort
45	ldr	pc, _data_abort
46#ifdef CONFIG_LPC2292
47	.word	0xB4405F76 /* 2's complement of the checksum of the vectors */
48#else
49	ldr	pc, _not_used
50#endif
51	ldr	pc, _irq
52	ldr	pc, _fiq
53
54_undefined_instruction: .word undefined_instruction
55_software_interrupt:	.word software_interrupt
56_prefetch_abort:	.word prefetch_abort
57_data_abort:		.word data_abort
58_not_used:		.word not_used
59_irq:			.word irq
60_fiq:			.word fiq
61
62	.balignl 16,0xdeadbeef
63
64
65/*
66 *************************************************************************
67 *
68 * Startup Code (reset vector)
69 *
70 * do important init only if we don't start from RAM!
71 * relocate armboot to ram
72 * setup stack
73 * jump to second stage
74 *
75 *************************************************************************
76 */
77
78.globl _TEXT_BASE
79_TEXT_BASE:
80	.word	TEXT_BASE
81
82#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
83.globl _armboot_start
84_armboot_start:
85	.word _start
86#endif
87
88/*
89 * These are defined in the board-specific linker script.
90 */
91.globl _bss_start
92_bss_start:
93	.word __bss_start
94
95.globl _bss_end
96_bss_end:
97	.word _end
98
99#ifdef CONFIG_USE_IRQ
100/* IRQ stack memory (calculated at run-time) */
101.globl IRQ_STACK_START
102IRQ_STACK_START:
103	.word	0x0badc0de
104
105/* IRQ stack memory (calculated at run-time) */
106.globl FIQ_STACK_START
107FIQ_STACK_START:
108	.word 0x0badc0de
109#endif
110
111#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
112/* IRQ stack memory (calculated at run-time) + 8 bytes */
113.globl IRQ_STACK_START_IN
114IRQ_STACK_START_IN:
115	.word	0x0badc0de
116
117.globl _datarel_start
118_datarel_start:
119	.word __datarel_start
120
121.globl _datarelrolocal_start
122_datarelrolocal_start:
123	.word __datarelrolocal_start
124
125.globl _datarellocal_start
126_datarellocal_start:
127	.word __datarellocal_start
128
129.globl _datarelro_start
130_datarelro_start:
131	.word __datarelro_start
132
133.globl _got_start
134_got_start:
135	.word __got_start
136
137.globl _got_end
138_got_end:
139	.word __got_end
140
141/*
142 * the actual reset code
143 */
144
145reset:
146	/*
147	 * set the cpu to SVC32 mode
148	 */
149	mrs	r0,cpsr
150	bic	r0,r0,#0x1f
151	orr	r0,r0,#0xd3
152	msr	cpsr,r0
153
154	/*
155	 * we do sys-critical inits only at reboot,
156	 * not when booting from ram!
157	 */
158#ifndef CONFIG_SKIP_LOWLEVEL_INIT
159	bl	cpu_init_crit
160#endif
161
162#ifdef CONFIG_LPC2292
163	bl	lowlevel_init
164#endif
165
166/* Set stackpointer in internal RAM to call board_init_f */
167call_board_init_f:
168	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
169	ldr	r0,=0x00000000
170	bl	board_init_f
171
172/*------------------------------------------------------------------------------*/
173
174/*
175 * void relocate_code (addr_sp, gd, addr_moni)
176 *
177 * This "function" does not return, instead it continues in RAM
178 * after relocating the monitor code.
179 *
180 */
181	.globl	relocate_code
182relocate_code:
183	mov	r4, r0	/* save addr_sp */
184	mov	r5, r1	/* save addr of gd */
185	mov	r6, r2	/* save addr of destination */
186	mov	r7, r2	/* save addr of destination */
187
188	/* Set up the stack						    */
189stack_setup:
190	mov	sp, r4
191
192	adr	r0, _start
193	ldr	r2, _TEXT_BASE
194	ldr	r3, _bss_start
195	sub	r2, r3, r2		/* r2 <- size of armboot	    */
196	add	r2, r0, r2		/* r2 <- source end address	    */
197	cmp	r0, r6
198	beq	clear_bss
199
200#ifndef CONFIG_SKIP_RELOCATE_UBOOT
201copy_loop:
202	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
203	stmia	r6!, {r9-r10}		/* copy to   target address [r1]    */
204	cmp	r0, r2			/* until source end addreee [r2]    */
205	ble	copy_loop
206
207#ifndef CONFIG_PRELOADER
208	/* fix got entries */
209	ldr	r1, _TEXT_BASE		/* Text base */
210	mov	r0, r7			/* reloc addr */
211	ldr	r2, _got_start		/* addr in Flash */
212	ldr	r3, _got_end		/* addr in Flash */
213	sub	r3, r3, r1
214	add	r3, r3, r0
215	sub	r2, r2, r1
216	add	r2, r2, r0
217
218fixloop:
219	ldr	r4, [r2]
220	sub	r4, r4, r1
221	add	r4, r4, r0
222	str	r4, [r2]
223	add	r2, r2, #4
224	cmp	r2, r3
225	bne	fixloop
226#endif
227#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
228
229clear_bss:
230#ifndef CONFIG_PRELOADER
231	ldr	r0, _bss_start
232	ldr	r1, _bss_end
233	ldr	r3, _TEXT_BASE		/* Text base */
234	mov	r4, r7			/* reloc addr */
235	sub	r0, r0, r3
236	add	r0, r0, r4
237	sub	r1, r1, r3
238	add	r1, r1, r4
239	mov	r2, #0x00000000		/* clear			    */
240
241clbss_l:str	r2, [r0]		/* clear loop...		    */
242	add	r0, r0, #4
243	cmp	r0, r1
244	bne	clbss_l
245
246	bl coloured_LED_init
247	bl red_LED_on
248#endif
249
250/*
251 * We are done. Do not return, instead branch to second part of board
252 * initialization, now running from RAM.
253 */
254	ldr	r0, _TEXT_BASE
255	ldr	r2, _board_init_r
256	sub	r2, r2, r0
257	add	r2, r2, r7	/* position from board_init_r in RAM */
258	/* setup parameters for board_init_r */
259	mov	r0, r5		/* gd_t */
260	mov	r1, r7		/* dest_addr */
261	/* jump to it ... */
262	mov	lr, r2
263	mov	pc, lr
264
265_board_init_r: .word board_init_r
266
267#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
268
269/*
270 * the actual reset code
271 */
272
273reset:
274	/*
275	 * set the cpu to SVC32 mode
276	 */
277	mrs	r0,cpsr
278	bic	r0,r0,#0x1f
279	orr	r0,r0,#0x13
280	msr	cpsr,r0
281
282	/*
283	 * we do sys-critical inits only at reboot,
284	 * not when booting from ram!
285	 */
286#ifndef CONFIG_SKIP_LOWLEVEL_INIT
287	bl	cpu_init_crit
288#endif
289
290#ifdef CONFIG_LPC2292
291	bl	lowlevel_init
292#endif
293
294#ifndef CONFIG_SKIP_RELOCATE_UBOOT
295relocate:				/* relocate U-Boot to RAM	    */
296	adr	r0, _start		/* r0 <- current position of code   */
297	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
298	cmp	r0, r1			/* don't reloc during debug	    */
299	beq	stack_setup
300
301#if TEXT_BASE
302#ifndef CONFIG_LPC2292 /* already done in lowlevel_init */
303	ldr	r2, =0x0		/* Relocate the exception vectors   */
304	cmp	r1, r2			/* and associated data to address   */
305	ldmneia r0!, {r3-r10}		/* 0x0. Do nothing if TEXT_BASE is  */
306	stmneia r2!, {r3-r10}		/* 0x0. Copy the first 15 words.    */
307	ldmneia r0, {r3-r9}
308	stmneia r2, {r3-r9}
309	adrne	r0, _start		/* restore r0			    */
310#endif	/* !CONFIG_LPC2292 */
311#endif
312
313	ldr	r2, _armboot_start
314	ldr	r3, _bss_start
315	sub	r2, r3, r2		/* r2 <- size of armboot	    */
316	add	r2, r0, r2		/* r2 <- source end address	    */
317
318copy_loop:
319	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
320	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
321	cmp	r0, r2			/* until source end addreee [r2]    */
322	ble	copy_loop
323
324#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */
325
326	/* Set up the stack						    */
327stack_setup:
328	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
329	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area			    */
330	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo			    */
331#ifdef CONFIG_USE_IRQ
332	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
333#endif
334	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
335	bic	sp, sp, #7		/* 8-byte alignment for ABI compliance */
336
337clear_bss:
338	ldr	r0, _bss_start		/* find start of bss segment	    */
339	ldr	r1, _bss_end		/* stop here			    */
340	mov	r2, #0x00000000		/* clear			    */
341
342clbss_l:str	r2, [r0]		/* clear loop...		    */
343	add	r0, r0, #4
344	cmp	r0, r1
345	ble	clbss_l
346
347	ldr	pc, _start_armboot
348
349_start_armboot: .word start_armboot
350
351#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
352
353/*
354 *************************************************************************
355 *
356 * CPU_init_critical registers
357 *
358 * setup important registers
359 * setup memory timing
360 *
361 *************************************************************************
362 */
363
364#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
365
366/* Interupt-Controller base addresses */
367INTMR1:		.word	0x80000280 @ 32 bit size
368INTMR2:		.word	0x80001280 @ 16 bit size
369INTMR3:		.word	0x80002280 @  8 bit size
370
371/* SYSCONs */
372SYSCON1:	.word	0x80000100
373SYSCON2:	.word	0x80001100
374SYSCON3:	.word	0x80002200
375
376#define CLKCTL	       0x6  /* mask */
377#define CLKCTL_18      0x0  /* 18.432 MHz */
378#define CLKCTL_36      0x2  /* 36.864 MHz */
379#define CLKCTL_49      0x4  /* 49.152 MHz */
380#define CLKCTL_73      0x6  /* 73.728 MHz */
381
382#elif defined(CONFIG_LPC2292)
383PLLCFG_ADR:	.word	PLLCFG
384PLLFEED_ADR:	.word	PLLFEED
385PLLCON_ADR:	.word	PLLCON
386PLLSTAT_ADR:	.word	PLLSTAT
387VPBDIV_ADR:	.word	VPBDIV
388MEMMAP_ADR:	.word	MEMMAP
389
390#endif
391
392cpu_init_crit:
393#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
394
395	/*
396	 * mask all IRQs by clearing all bits in the INTMRs
397	 */
398	mov	r1, #0x00
399	ldr	r0, INTMR1
400	str	r1, [r0]
401	ldr	r0, INTMR2
402	str	r1, [r0]
403	ldr	r0, INTMR3
404	str	r1, [r0]
405
406	/*
407	 * flush v4 I/D caches
408	 */
409	mov	r0, #0
410	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
411	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
412
413	/*
414	 * disable MMU stuff and caches
415	 */
416	mrc	p15,0,r0,c1,c0
417	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
418	bic	r0, r0, #0x0000008f	@ clear bits 7, 3:0 (B--- WCAM)
419	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
420	mcr	p15,0,r0,c1,c0
421#elif defined(CONFIG_NETARM)
422	/*
423	 * prior to software reset : need to set pin PORTC4 to be *HRESET
424	 */
425	ldr	r0, =NETARM_GEN_MODULE_BASE
426	ldr	r1, =(NETARM_GEN_PORT_MODE(0x10) | \
427			NETARM_GEN_PORT_DIR(0x10))
428	str	r1, [r0, #+NETARM_GEN_PORTC]
429	/*
430	 * software reset : see HW Ref. Guide 8.2.4 : Software Service register
431	 *		    for an explanation of this process
432	 */
433	ldr	r0, =NETARM_GEN_MODULE_BASE
434	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
435	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
436	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
437	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
438	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
439	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
440	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
441	str	r1, [r0, #+NETARM_GEN_SOFTWARE_SERVICE]
442	/*
443	 * setup PLL and System Config
444	 */
445	ldr	r0, =NETARM_GEN_MODULE_BASE
446
447	ldr	r1, =(	NETARM_GEN_SYS_CFG_LENDIAN | \
448			NETARM_GEN_SYS_CFG_BUSFULL | \
449			NETARM_GEN_SYS_CFG_USER_EN | \
450			NETARM_GEN_SYS_CFG_ALIGN_ABORT | \
451			NETARM_GEN_SYS_CFG_BUSARB_INT | \
452			NETARM_GEN_SYS_CFG_BUSMON_EN )
453
454	str	r1, [r0, #+NETARM_GEN_SYSTEM_CONTROL]
455
456#ifndef CONFIG_NETARM_PLL_BYPASS
457	ldr	r1, =(	NETARM_GEN_PLL_CTL_PLLCNT(NETARM_PLL_COUNT_VAL) | \
458			NETARM_GEN_PLL_CTL_POLTST_DEF | \
459			NETARM_GEN_PLL_CTL_INDIV(1) | \
460			NETARM_GEN_PLL_CTL_ICP_DEF | \
461			NETARM_GEN_PLL_CTL_OUTDIV(2) )
462	str	r1, [r0, #+NETARM_GEN_PLL_CONTROL]
463#endif
464
465	/*
466	 * mask all IRQs by clearing all bits in the INTMRs
467	 */
468	mov	r1, #0
469	ldr	r0, =NETARM_GEN_MODULE_BASE
470	str	r1, [r0, #+NETARM_GEN_INTR_ENABLE]
471
472#elif defined(CONFIG_S3C4510B)
473
474	/*
475	 * Mask off all IRQ sources
476	 */
477	ldr	r1, =REG_INTMASK
478	ldr	r0, =0x3FFFFF
479	str	r0, [r1]
480
481	/*
482	 * Disable Cache
483	 */
484	ldr r0, =REG_SYSCFG
485	ldr r1, =0x83ffffa0	/* cache-disabled  */
486	str r1, [r0]
487
488#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
489	/* No specific initialisation for IntegratorAP/CM720T as yet */
490#elif defined(CONFIG_LPC2292)
491	/* Set-up PLL */
492	mov	r3, #0xAA
493	mov	r4, #0x55
494	/* First disconnect and disable the PLL */
495	ldr	r0, PLLCON_ADR
496	mov	r1, #0x00
497	str	r1, [r0]
498	ldr	r0, PLLFEED_ADR /* start feed sequence */
499	str	r3, [r0]
500	str	r4, [r0]	/* feed sequence done */
501	/* Set new M and P values */
502	ldr	r0, PLLCFG_ADR
503	mov	r1, #0x23	/* M=4 and P=2 */
504	str	r1, [r0]
505	ldr	r0, PLLFEED_ADR /* start feed sequence */
506	str	r3, [r0]
507	str	r4, [r0]	/* feed sequence done */
508	/* Then enable the PLL */
509	ldr	r0, PLLCON_ADR
510	mov	r1, #0x01	/* PLL enable bit */
511	str	r1, [r0]
512	ldr	r0, PLLFEED_ADR /* start feed sequence */
513	str	r3, [r0]
514	str	r4, [r0]	/* feed sequence done */
515	/* Wait for the lock */
516	ldr	r0, PLLSTAT_ADR
517	mov	r1, #0x400	/* lock bit */
518lock_loop:
519	ldr	r2, [r0]
520	and	r2, r1, r2
521	cmp	r2, #0
522	beq	lock_loop
523	/* And finally connect the PLL */
524	ldr	r0, PLLCON_ADR
525	mov	r1, #0x03	/* PLL enable bit and connect bit */
526	str	r1, [r0]
527	ldr	r0, PLLFEED_ADR /* start feed sequence */
528	str	r3, [r0]
529	str	r4, [r0]	/* feed sequence done */
530	/* Set-up VPBDIV register */
531	ldr	r0, VPBDIV_ADR
532	mov	r1, #0x01	/* VPB clock is same as process clock */
533	str	r1, [r0]
534#else
535#error No cpu_init_crit() defined for current CPU type
536#endif
537
538#ifdef CONFIG_ARM7_REVD
539	/* set clock speed */
540	/* !!! we run @ 36 MHz due to a hardware flaw in Rev. D processors */
541	/* !!! not doing DRAM refresh properly! */
542	ldr	r0, SYSCON3
543	ldr	r1, [r0]
544	bic	r1, r1, #CLKCTL
545	orr	r1, r1, #CLKCTL_36
546	str	r1, [r0]
547#endif
548
549#ifndef CONFIG_LPC2292
550	mov	ip, lr
551	/*
552	 * before relocating, we have to setup RAM timing
553	 * because memory timing is board-dependent, you will
554	 * find a lowlevel_init.S in your board directory.
555	 */
556	bl	lowlevel_init
557	mov	lr, ip
558#endif
559
560	mov	pc, lr
561
562
563/*
564 *************************************************************************
565 *
566 * Interrupt handling
567 *
568 *************************************************************************
569 */
570
571@
572@ IRQ stack frame.
573@
574#define S_FRAME_SIZE	72
575
576#define S_OLD_R0	68
577#define S_PSR		64
578#define S_PC		60
579#define S_LR		56
580#define S_SP		52
581
582#define S_IP		48
583#define S_FP		44
584#define S_R10		40
585#define S_R9		36
586#define S_R8		32
587#define S_R7		28
588#define S_R6		24
589#define S_R5		20
590#define S_R4		16
591#define S_R3		12
592#define S_R2		8
593#define S_R1		4
594#define S_R0		0
595
596#define MODE_SVC 0x13
597#define I_BIT	 0x80
598
599/*
600 * use bad_save_user_regs for abort/prefetch/undef/swi ...
601 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling
602 */
603
604	.macro	bad_save_user_regs
605	sub	sp, sp, #S_FRAME_SIZE
606	stmia	sp, {r0 - r12}			@ Calling r0-r12
607	add	r8, sp, #S_PC
608
609#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
610	ldr	r2, _armboot_start
611	sub	r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
612	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)	@ set base 2 words into abort stack
613#else
614	ldr	r2, IRQ_STACK_START_IN
615#endif
616	ldmia	r2, {r2 - r4}			@ get pc, cpsr, old_r0
617	add	r0, sp, #S_FRAME_SIZE		@ restore sp_SVC
618
619	add	r5, sp, #S_SP
620	mov	r1, lr
621	stmia	r5, {r0 - r4}			@ save sp_SVC, lr_SVC, pc, cpsr, old_r
622	mov	r0, sp
623	.endm
624
625	.macro	irq_save_user_regs
626	sub	sp, sp, #S_FRAME_SIZE
627	stmia	sp, {r0 - r12}			@ Calling r0-r12
628	add	r8, sp, #S_PC
629	stmdb	r8, {sp, lr}^			@ Calling SP, LR
630	str	lr, [r8, #0]			@ Save calling PC
631	mrs	r6, spsr
632	str	r6, [r8, #4]			@ Save CPSR
633	str	r0, [r8, #8]			@ Save OLD_R0
634	mov	r0, sp
635	.endm
636
637	.macro	irq_restore_user_regs
638	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
639	mov	r0, r0
640	ldr	lr, [sp, #S_PC]			@ Get PC
641	add	sp, sp, #S_FRAME_SIZE
642	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
643	.endm
644
645	.macro get_bad_stack
646#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
647	ldr	r13, _armboot_start		@ setup our mode stack
648	sub	r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
649	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
650#else
651	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
652#endif
653
654	str	lr, [r13]			@ save caller lr / spsr
655	mrs	lr, spsr
656	str	lr, [r13, #4]
657
658	mov	r13, #MODE_SVC			@ prepare SVC-Mode
659	msr	spsr_c, r13
660	mov	lr, pc
661	movs	pc, lr
662	.endm
663
664	.macro get_irq_stack			@ setup IRQ stack
665	ldr	sp, IRQ_STACK_START
666	.endm
667
668	.macro get_fiq_stack			@ setup FIQ stack
669	ldr	sp, FIQ_STACK_START
670	.endm
671
672/*
673 * exception handlers
674 */
675	.align	5
676undefined_instruction:
677	get_bad_stack
678	bad_save_user_regs
679	bl	do_undefined_instruction
680
681	.align	5
682software_interrupt:
683	get_bad_stack
684	bad_save_user_regs
685	bl	do_software_interrupt
686
687	.align	5
688prefetch_abort:
689	get_bad_stack
690	bad_save_user_regs
691	bl	do_prefetch_abort
692
693	.align	5
694data_abort:
695	get_bad_stack
696	bad_save_user_regs
697	bl	do_data_abort
698
699	.align	5
700not_used:
701	get_bad_stack
702	bad_save_user_regs
703	bl	do_not_used
704
705#ifdef CONFIG_USE_IRQ
706
707	.align	5
708irq:
709	get_irq_stack
710	irq_save_user_regs
711	bl	do_irq
712	irq_restore_user_regs
713
714	.align	5
715fiq:
716	get_fiq_stack
717	/* someone ought to write a more effiction fiq_save_user_regs */
718	irq_save_user_regs
719	bl	do_fiq
720	irq_restore_user_regs
721
722#else
723
724	.align	5
725irq:
726	get_bad_stack
727	bad_save_user_regs
728	bl	do_irq
729
730	.align	5
731fiq:
732	get_bad_stack
733	bad_save_user_regs
734	bl	do_fiq
735
736#endif
737
738#if defined(CONFIG_IMPA7) || defined(CONFIG_EP7312) || defined(CONFIG_ARMADILLO)
739	.align	5
740.globl reset_cpu
741reset_cpu:
742	mov	ip, #0
743	mcr	p15, 0, ip, c7, c7, 0		@ invalidate cache
744	mcr	p15, 0, ip, c8, c7, 0		@ flush TLB (v4)
745	mrc	p15, 0, ip, c1, c0, 0		@ get ctrl register
746	bic	ip, ip, #0x000f			@ ............wcam
747	bic	ip, ip, #0x2100			@ ..v....s........
748	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
749	mov	pc, r0
750#elif defined(CONFIG_NETARM)
751	.align	5
752.globl reset_cpu
753reset_cpu:
754	ldr	r1, =NETARM_MEM_MODULE_BASE
755	ldr	r0, [r1, #+NETARM_MEM_CS0_BASE_ADDR]
756	ldr	r1, =0xFFFFF000
757	and	r0, r1, r0
758	ldr	r1, =(relocate-TEXT_BASE)
759	add	r0, r1, r0
760	ldr	r4, =NETARM_GEN_MODULE_BASE
761	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
762	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
763	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
764	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
765	ldr	r1, =NETARM_GEN_SW_SVC_RESETA
766	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
767	ldr	r1, =NETARM_GEN_SW_SVC_RESETB
768	str	r1, [r4, #+NETARM_GEN_SOFTWARE_SERVICE]
769	mov	pc, r0
770#elif defined(CONFIG_S3C4510B)
771/* Nothing done here as reseting the CPU is board specific, depending
772 * on external peripherals such as watchdog timers, etc. */
773#elif defined(CONFIG_INTEGRATOR) && defined(CONFIG_ARCH_INTEGRATOR)
774	/* No specific reset actions for IntegratorAP/CM720T as yet */
775#elif defined(CONFIG_LPC2292)
776	.align	5
777.globl reset_cpu
778reset_cpu:
779	mov	pc, r0
780#else
781#error No reset_cpu() defined for current CPU type
782#endif
783