xref: /openbmc/u-boot/arch/arm/cpu/pxa/start.S (revision 2cad92fd)
184ad6884SPeter Tyser/*
284ad6884SPeter Tyser *  armboot - Startup Code for XScale
384ad6884SPeter Tyser *
484ad6884SPeter Tyser *  Copyright (C) 1998	Dan Malek <dmalek@jlc.net>
584ad6884SPeter Tyser *  Copyright (C) 1999	Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se>
684ad6884SPeter Tyser *  Copyright (C) 2000	Wolfgang Denk <wd@denx.de>
784ad6884SPeter Tyser *  Copyright (C) 2001	Alex Zuepke <azu@sysgo.de>
884ad6884SPeter Tyser *  Copyright (C) 2002	Kyle Harris <kharris@nexus-tech.net>
984ad6884SPeter Tyser *  Copyright (C) 2003	Robert Schwebel <r.schwebel@pengutronix.de>
1084ad6884SPeter Tyser *  Copyright (C) 2003	Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de>
1184ad6884SPeter Tyser *
1284ad6884SPeter Tyser * See file CREDITS for list of people who contributed to this
1384ad6884SPeter Tyser * project.
1484ad6884SPeter Tyser *
1584ad6884SPeter Tyser * This program is free software; you can redistribute it and/or
1684ad6884SPeter Tyser * modify it under the terms of the GNU General Public License as
1784ad6884SPeter Tyser * published by the Free Software Foundation; either version 2 of
1884ad6884SPeter Tyser * the License, or (at your option) any later version.
1984ad6884SPeter Tyser *
2084ad6884SPeter Tyser * This program is distributed in the hope that it will be useful,
2184ad6884SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of
2284ad6884SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
2384ad6884SPeter Tyser * GNU General Public License for more details.
2484ad6884SPeter Tyser *
2584ad6884SPeter Tyser * You should have received a copy of the GNU General Public License
2684ad6884SPeter Tyser * along with this program; if not, write to the Free Software
2784ad6884SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
2884ad6884SPeter Tyser * MA 02111-1307 USA
2984ad6884SPeter Tyser */
3084ad6884SPeter Tyser
3184ad6884SPeter Tyser#include <config.h>
3284ad6884SPeter Tyser#include <version.h>
3384ad6884SPeter Tyser#include <asm/arch/pxa-regs.h>
34*2cad92fdSMarek Vasut#include <asm/arch/macro.h>
35*2cad92fdSMarek Vasut
36*2cad92fdSMarek Vasut/* takes care the CP15 update has taken place */
37*2cad92fdSMarek Vasut.macro CPWAIT reg
38*2cad92fdSMarek Vasutmrc  p15,0,\reg,c2,c0,0
39*2cad92fdSMarek Vasutmov  \reg,\reg
40*2cad92fdSMarek Vasutsub  pc,pc,#4
41*2cad92fdSMarek Vasut.endm
4284ad6884SPeter Tyser
4384ad6884SPeter Tyser.globl _start
4484ad6884SPeter Tyser_start: b	reset
455ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
465ab877b6SMarek Vasut	ldr	pc, _hang
475ab877b6SMarek Vasut	ldr	pc, _hang
485ab877b6SMarek Vasut	ldr	pc, _hang
495ab877b6SMarek Vasut	ldr	pc, _hang
505ab877b6SMarek Vasut	ldr	pc, _hang
515ab877b6SMarek Vasut	ldr	pc, _hang
525ab877b6SMarek Vasut	ldr	pc, _hang
535ab877b6SMarek Vasut
545ab877b6SMarek Vasut_hang:
555ab877b6SMarek Vasut	.word	do_hang
565ab877b6SMarek Vasut	.word	0x12345678
575ab877b6SMarek Vasut	.word	0x12345678
585ab877b6SMarek Vasut	.word	0x12345678
595ab877b6SMarek Vasut	.word	0x12345678
605ab877b6SMarek Vasut	.word	0x12345678
615ab877b6SMarek Vasut	.word	0x12345678
625ab877b6SMarek Vasut	.word	0x12345678	/* now 16*4=64 */
635ab877b6SMarek Vasut#else
6484ad6884SPeter Tyser	ldr	pc, _undefined_instruction
6584ad6884SPeter Tyser	ldr	pc, _software_interrupt
6684ad6884SPeter Tyser	ldr	pc, _prefetch_abort
6784ad6884SPeter Tyser	ldr	pc, _data_abort
6884ad6884SPeter Tyser	ldr	pc, _not_used
6984ad6884SPeter Tyser	ldr	pc, _irq
7084ad6884SPeter Tyser	ldr	pc, _fiq
7184ad6884SPeter Tyser
7284ad6884SPeter Tyser_undefined_instruction: .word undefined_instruction
7384ad6884SPeter Tyser_software_interrupt:	.word software_interrupt
7484ad6884SPeter Tyser_prefetch_abort:	.word prefetch_abort
7584ad6884SPeter Tyser_data_abort:		.word data_abort
7684ad6884SPeter Tyser_not_used:		.word not_used
7784ad6884SPeter Tyser_irq:			.word irq
7884ad6884SPeter Tyser_fiq:			.word fiq
795ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
8084ad6884SPeter Tyser
8184ad6884SPeter Tyser	.balignl 16,0xdeadbeef
8284ad6884SPeter Tyser
8384ad6884SPeter Tyser
8484ad6884SPeter Tyser/*
8584ad6884SPeter Tyser * Startup Code (reset vector)
8684ad6884SPeter Tyser *
8784ad6884SPeter Tyser * do important init only if we don't start from RAM!
8884ad6884SPeter Tyser * - relocate armboot to RAM
8984ad6884SPeter Tyser * - setup stack
9084ad6884SPeter Tyser * - jump to second stage
9184ad6884SPeter Tyser */
9284ad6884SPeter Tyser
935347f68cSHeiko Schocher.globl _TEXT_BASE
9484ad6884SPeter Tyser_TEXT_BASE:
9514d0a02aSWolfgang Denk	.word	CONFIG_SYS_TEXT_BASE
9684ad6884SPeter Tyser
9784ad6884SPeter Tyser.globl _armboot_start
9884ad6884SPeter Tyser_armboot_start:
9984ad6884SPeter Tyser	.word _start
10084ad6884SPeter Tyser
10184ad6884SPeter Tyser/*
10284ad6884SPeter Tyser * These are defined in the board-specific linker script.
10384ad6884SPeter Tyser */
10484ad6884SPeter Tyser.globl _bss_start
10584ad6884SPeter Tyser_bss_start:
10684ad6884SPeter Tyser	.word __bss_start
10784ad6884SPeter Tyser
10884ad6884SPeter Tyser.globl _bss_end
10984ad6884SPeter Tyser_bss_end:
11084ad6884SPeter Tyser	.word _end
11184ad6884SPeter Tyser
11284ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
11384ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
11484ad6884SPeter Tyser.globl IRQ_STACK_START
11584ad6884SPeter TyserIRQ_STACK_START:
11684ad6884SPeter Tyser	.word	0x0badc0de
11784ad6884SPeter Tyser
11884ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
11984ad6884SPeter Tyser.globl FIQ_STACK_START
12084ad6884SPeter TyserFIQ_STACK_START:
12184ad6884SPeter Tyser	.word 0x0badc0de
12284ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
12384ad6884SPeter Tyser
124*2cad92fdSMarek Vasut#ifndef CONFIG_PRELOADER
1255347f68cSHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */
1265347f68cSHeiko Schocher.globl IRQ_STACK_START_IN
1275347f68cSHeiko SchocherIRQ_STACK_START_IN:
1285347f68cSHeiko Schocher	.word	0x0badc0de
1295347f68cSHeiko Schocher
1305347f68cSHeiko Schocher.globl _datarel_start
1315347f68cSHeiko Schocher_datarel_start:
1325347f68cSHeiko Schocher	.word __datarel_start
1335347f68cSHeiko Schocher
1345347f68cSHeiko Schocher.globl _datarelrolocal_start
1355347f68cSHeiko Schocher_datarelrolocal_start:
1365347f68cSHeiko Schocher	.word __datarelrolocal_start
1375347f68cSHeiko Schocher
1385347f68cSHeiko Schocher.globl _datarellocal_start
1395347f68cSHeiko Schocher_datarellocal_start:
1405347f68cSHeiko Schocher	.word __datarellocal_start
1415347f68cSHeiko Schocher
1425347f68cSHeiko Schocher.globl _datarelro_start
1435347f68cSHeiko Schocher_datarelro_start:
1445347f68cSHeiko Schocher	.word __datarelro_start
1455347f68cSHeiko Schocher
1465347f68cSHeiko Schocher.globl _got_start
1475347f68cSHeiko Schocher_got_start:
1485347f68cSHeiko Schocher	.word __got_start
1495347f68cSHeiko Schocher
1505347f68cSHeiko Schocher.globl _got_end
1515347f68cSHeiko Schocher_got_end:
1525347f68cSHeiko Schocher	.word __got_end
1535347f68cSHeiko Schocher
1545347f68cSHeiko Schocher/*
1555347f68cSHeiko Schocher * the actual reset code
1565347f68cSHeiko Schocher */
1575347f68cSHeiko Schocher
1585347f68cSHeiko Schocherreset:
1595347f68cSHeiko Schocher	/*
1605347f68cSHeiko Schocher	 * set the cpu to SVC32 mode
1615347f68cSHeiko Schocher	 */
1625347f68cSHeiko Schocher	mrs	r0,cpsr
1635347f68cSHeiko Schocher	bic	r0,r0,#0x1f
1645347f68cSHeiko Schocher	orr	r0,r0,#0xd3
1655347f68cSHeiko Schocher	msr	cpsr,r0
1665347f68cSHeiko Schocher
1675347f68cSHeiko Schocher	/*
168*2cad92fdSMarek Vasut	 * Enable MMU to use DCache as DRAM
1695347f68cSHeiko Schocher	 */
170*2cad92fdSMarek Vasut	/* Domain access -- enable for all CPs */
171*2cad92fdSMarek Vasut	ldr	r0, =0x0000ffff
172*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c3, c0, 0
173*2cad92fdSMarek Vasut
174*2cad92fdSMarek Vasut	/* Point TTBR to MMU table */
175*2cad92fdSMarek Vasut	ldr	r0, =mmu_table
176*2cad92fdSMarek Vasut	adr	r2, _start
177*2cad92fdSMarek Vasut	orr	r0, r2
178*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c2, c0, 0
179*2cad92fdSMarek Vasut
180*2cad92fdSMarek Vasut/* !!! Hereby, check if the code is running from SRAM !!! */
181*2cad92fdSMarek Vasut/* If the code is running from SRAM, alias SRAM to 0x0 to simulate NOR. The code
182*2cad92fdSMarek Vasut * is linked to 0x0 too, so this makes things easier. */
183*2cad92fdSMarek Vasut	cmp	r2, #0x5c000000
184*2cad92fdSMarek Vasut
185*2cad92fdSMarek Vasut	ldreq	r1, [r0]
186*2cad92fdSMarek Vasut	orreq	r1, r2
187*2cad92fdSMarek Vasut	streq	r1, [r0]
188*2cad92fdSMarek Vasut
189*2cad92fdSMarek Vasut	/* Kick in MMU, ICache, DCache, BTB */
190*2cad92fdSMarek Vasut	mrc	p15, 0, r0, c1, c0, 0
191*2cad92fdSMarek Vasut	bic	r0, #0x1b00
192*2cad92fdSMarek Vasut	bic	r0, #0x0087
193*2cad92fdSMarek Vasut	orr	r0, #0x1800
194*2cad92fdSMarek Vasut	orr	r0, #0x0005
195*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c1, c0, 0
196*2cad92fdSMarek Vasut	CPWAIT	r0
197*2cad92fdSMarek Vasut
198*2cad92fdSMarek Vasut	/* Unlock Icache, Dcache */
199*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c1, 1
200*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c2, 1
201*2cad92fdSMarek Vasut
202*2cad92fdSMarek Vasut	/* Flush Icache, Dcache, BTB */
203*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c7, 0
204*2cad92fdSMarek Vasut
205*2cad92fdSMarek Vasut	/* Unlock I-TLB, D-TLB */
206*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c10, c4, 1
207*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c10, c8, 1
208*2cad92fdSMarek Vasut
209*2cad92fdSMarek Vasut	/* Flush TLB */
210*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c8, c7, 0
211*2cad92fdSMarek Vasut	/* Allocate 4096 bytes of Dcache as RAM */
212*2cad92fdSMarek Vasut
213*2cad92fdSMarek Vasut	/* Drain pending loads and stores */
214*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
215*2cad92fdSMarek Vasut
216*2cad92fdSMarek Vasut	mov	r4, #0x00
217*2cad92fdSMarek Vasut	mov	r5, #0x00
218*2cad92fdSMarek Vasut	mov	r2, #0x01
219*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c2, 0
220*2cad92fdSMarek Vasut	CPWAIT	r0
221*2cad92fdSMarek Vasut
222*2cad92fdSMarek Vasut	/* 128 lines reserved (128 x 32bytes = 4096 bytes total) */
223*2cad92fdSMarek Vasut	mov	r0, #128
224*2cad92fdSMarek Vasut	mov	r1, #0xa0000000
225*2cad92fdSMarek Vasutalloc:
226*2cad92fdSMarek Vasut	mcr	p15, 0, r1, c7, c2, 5
227*2cad92fdSMarek Vasut	/* Drain pending loads and stores */
228*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
229*2cad92fdSMarek Vasut	strd	r4, [r1], #8
230*2cad92fdSMarek Vasut	strd	r4, [r1], #8
231*2cad92fdSMarek Vasut	strd	r4, [r1], #8
232*2cad92fdSMarek Vasut	strd	r4, [r1], #8
233*2cad92fdSMarek Vasut	subs	r0, #0x01
234*2cad92fdSMarek Vasut	bne	alloc
235*2cad92fdSMarek Vasut	/* Drain pending loads and stores */
236*2cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
237*2cad92fdSMarek Vasut	mov	r2, #0x00
238*2cad92fdSMarek Vasut	mcr	p15, 0, r2, c9, c2, 0
239*2cad92fdSMarek Vasut	CPWAIT	r0
240*2cad92fdSMarek Vasut
241*2cad92fdSMarek Vasut	/* Jump to 0x0 ( + offset) if running from SRAM */
242*2cad92fdSMarek Vasut	adr	r0, zerojmp
243*2cad92fdSMarek Vasut	bic	r0, #0x5c000000
244*2cad92fdSMarek Vasut	mov	pc, r0
245*2cad92fdSMarek Vasutzerojmp:
2465347f68cSHeiko Schocher
2475347f68cSHeiko Schocher/* Set stackpointer in internal RAM to call board_init_f */
2485347f68cSHeiko Schochercall_board_init_f:
2495347f68cSHeiko Schocher	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
2505347f68cSHeiko Schocher	ldr	r0,=0x00000000
2515347f68cSHeiko Schocher	bl	board_init_f
2525347f68cSHeiko Schocher
2535347f68cSHeiko Schocher/*------------------------------------------------------------------------------*/
2545347f68cSHeiko Schocher
2555347f68cSHeiko Schocher/*
2565347f68cSHeiko Schocher * void relocate_code (addr_sp, gd, addr_moni)
2575347f68cSHeiko Schocher *
2585347f68cSHeiko Schocher * This "function" does not return, instead it continues in RAM
2595347f68cSHeiko Schocher * after relocating the monitor code.
2605347f68cSHeiko Schocher *
2615347f68cSHeiko Schocher */
2625347f68cSHeiko Schocher	.globl	relocate_code
2635347f68cSHeiko Schocherrelocate_code:
2645347f68cSHeiko Schocher	mov	r4, r0	/* save addr_sp */
2655347f68cSHeiko Schocher	mov	r5, r1	/* save addr of gd */
2665347f68cSHeiko Schocher	mov	r6, r2	/* save addr of destination */
2675347f68cSHeiko Schocher	mov	r7, r2	/* save addr of destination */
2685347f68cSHeiko Schocher
2695347f68cSHeiko Schocher	/* Set up the stack						    */
2705347f68cSHeiko Schocherstack_setup:
2715347f68cSHeiko Schocher	mov	sp, r4
2725347f68cSHeiko Schocher
2735347f68cSHeiko Schocher	adr	r0, _start
2745347f68cSHeiko Schocher	ldr	r2, _TEXT_BASE
2755347f68cSHeiko Schocher	ldr	r3, _bss_start
2765347f68cSHeiko Schocher	sub	r2, r3, r2		/* r2 <- size of armboot	    */
2775347f68cSHeiko Schocher	add	r2, r0, r2		/* r2 <- source end address	    */
2785347f68cSHeiko Schocher	cmp	r0, r6
2795347f68cSHeiko Schocher	beq	clear_bss
2805347f68cSHeiko Schocher
2815347f68cSHeiko Schocher#ifndef CONFIG_SKIP_RELOCATE_UBOOT
282*2cad92fdSMarek Vasut	stmfd sp!, {r0-r12}
2835347f68cSHeiko Schochercopy_loop:
284*2cad92fdSMarek Vasut	ldmia	r0!, {r3-r5, r7-r11}	/* copy from source address [r0]    */
285*2cad92fdSMarek Vasut	stmia	r6!, {r3-r5, r7-r11}	/* copy to   target address [r1]    */
286da90d4ceSAlbert Aribaud	cmp	r0, r2			/* until source end address [r2]    */
287da90d4ceSAlbert Aribaud	blo	copy_loop
288*2cad92fdSMarek Vasut	ldmfd sp!, {r0-r12}
2895347f68cSHeiko Schocher
2905347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
2915347f68cSHeiko Schocher	/* fix got entries */
2925347f68cSHeiko Schocher	ldr	r1, _TEXT_BASE		/* Text base */
2935347f68cSHeiko Schocher	mov	r0, r7			/* reloc addr */
2945347f68cSHeiko Schocher	ldr	r2, _got_start		/* addr in Flash */
2955347f68cSHeiko Schocher	ldr	r3, _got_end		/* addr in Flash */
2965347f68cSHeiko Schocher	sub	r3, r3, r1
2975347f68cSHeiko Schocher	add	r3, r3, r0
2985347f68cSHeiko Schocher	sub	r2, r2, r1
2995347f68cSHeiko Schocher	add	r2, r2, r0
3005347f68cSHeiko Schocher
3015347f68cSHeiko Schocherfixloop:
3025347f68cSHeiko Schocher	ldr	r4, [r2]
3035347f68cSHeiko Schocher	sub	r4, r4, r1
3045347f68cSHeiko Schocher	add	r4, r4, r0
3055347f68cSHeiko Schocher	str	r4, [r2]
3065347f68cSHeiko Schocher	add	r2, r2, #4
3075347f68cSHeiko Schocher	cmp	r2, r3
3085347f68cSHeiko Schocher	bne	fixloop
3095347f68cSHeiko Schocher#endif
3105347f68cSHeiko Schocher#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
3115347f68cSHeiko Schocher
3125347f68cSHeiko Schocherclear_bss:
3135347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
3145347f68cSHeiko Schocher	ldr	r0, _bss_start
3155347f68cSHeiko Schocher	ldr	r1, _bss_end
3165347f68cSHeiko Schocher	ldr	r3, _TEXT_BASE		/* Text base */
3175347f68cSHeiko Schocher	mov	r4, r7			/* reloc addr */
3185347f68cSHeiko Schocher	sub	r0, r0, r3
3195347f68cSHeiko Schocher	add	r0, r0, r4
3205347f68cSHeiko Schocher	sub	r1, r1, r3
3215347f68cSHeiko Schocher	add	r1, r1, r4
3225347f68cSHeiko Schocher	mov	r2, #0x00000000		/* clear			    */
3235347f68cSHeiko Schocher
3245347f68cSHeiko Schocherclbss_l:str	r2, [r0]		/* clear loop...		    */
3255347f68cSHeiko Schocher	add	r0, r0, #4
3265347f68cSHeiko Schocher	cmp	r0, r1
3275347f68cSHeiko Schocher	bne	clbss_l
3285347f68cSHeiko Schocher#endif
3295347f68cSHeiko Schocher
3305347f68cSHeiko Schocher/*
3315347f68cSHeiko Schocher * We are done. Do not return, instead branch to second part of board
3325347f68cSHeiko Schocher * initialization, now running from RAM.
3335347f68cSHeiko Schocher */
3345347f68cSHeiko Schocher#ifdef CONFIG_ONENAND_IPL
3355347f68cSHeiko Schocher	ldr     pc, _start_oneboot
3365347f68cSHeiko Schocher
3375347f68cSHeiko Schocher_start_oneboot: .word start_oneboot
3385347f68cSHeiko Schocher#else
3395347f68cSHeiko Schocher	ldr	r0, _TEXT_BASE
3405347f68cSHeiko Schocher	ldr	r2, _board_init_r
3415347f68cSHeiko Schocher	sub	r2, r2, r0
3425347f68cSHeiko Schocher	add	r2, r2, r7	/* position from board_init_r in RAM */
3435347f68cSHeiko Schocher	/* setup parameters for board_init_r */
3445347f68cSHeiko Schocher	mov	r0, r5		/* gd_t */
3455347f68cSHeiko Schocher	mov	r1, r7		/* dest_addr */
3465347f68cSHeiko Schocher	/* jump to it ... */
3475347f68cSHeiko Schocher	mov	lr, r2
3485347f68cSHeiko Schocher	mov	pc, lr
3495347f68cSHeiko Schocher
3505347f68cSHeiko Schocher_board_init_r: .word board_init_r
3515347f68cSHeiko Schocher#endif
3525347f68cSHeiko Schocher
3535347f68cSHeiko Schocher#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
35484ad6884SPeter Tyser
35584ad6884SPeter Tyser/****************************************************************************/
35684ad6884SPeter Tyser/*									    */
357*2cad92fdSMarek Vasut/* the actual reset code for OneNAND IPL				    */
35884ad6884SPeter Tyser/*									    */
35984ad6884SPeter Tyser/****************************************************************************/
36084ad6884SPeter Tyser
361*2cad92fdSMarek Vasut#ifndef	CONFIG_PXA27X
362*2cad92fdSMarek Vasut#error OneNAND IPL is not supported on PXA25x and 26x due to lack of SRAM
363*2cad92fdSMarek Vasut#endif
364*2cad92fdSMarek Vasut
36584ad6884SPeter Tyserreset:
366*2cad92fdSMarek Vasut	/* Set CPU to SVC32 mode */
367*2cad92fdSMarek Vasut	mrs	r0,cpsr
368*2cad92fdSMarek Vasut	bic	r0,r0,#0x1f
36984ad6884SPeter Tyser	orr	r0,r0,#0x13
37084ad6884SPeter Tyser	msr	cpsr,r0
37184ad6884SPeter Tyser
372*2cad92fdSMarek Vasut	/* Point stack at the end of SRAM and leave 32 words for abort-stack */
373*2cad92fdSMarek Vasut	ldr	sp, =0x5c03ff80
37484ad6884SPeter Tyser
375*2cad92fdSMarek Vasut	/* Start OneNAND IPL */
376*2cad92fdSMarek Vasut	ldr	pc, =start_oneboot
37784ad6884SPeter Tyser
378*2cad92fdSMarek Vasut#endif /* #if !defined(CONFIG_ONENAND_IPL) */
37984ad6884SPeter Tyser
3805ab877b6SMarek Vasut#ifndef CONFIG_PRELOADER
38184ad6884SPeter Tyser/****************************************************************************/
38284ad6884SPeter Tyser/*									    */
38384ad6884SPeter Tyser/* Interrupt handling							    */
38484ad6884SPeter Tyser/*									    */
38584ad6884SPeter Tyser/****************************************************************************/
38684ad6884SPeter Tyser
38784ad6884SPeter Tyser/* IRQ stack frame							    */
38884ad6884SPeter Tyser
38984ad6884SPeter Tyser#define S_FRAME_SIZE	72
39084ad6884SPeter Tyser
39184ad6884SPeter Tyser#define S_OLD_R0	68
39284ad6884SPeter Tyser#define S_PSR		64
39384ad6884SPeter Tyser#define S_PC		60
39484ad6884SPeter Tyser#define S_LR		56
39584ad6884SPeter Tyser#define S_SP		52
39684ad6884SPeter Tyser
39784ad6884SPeter Tyser#define S_IP		48
39884ad6884SPeter Tyser#define S_FP		44
39984ad6884SPeter Tyser#define S_R10		40
40084ad6884SPeter Tyser#define S_R9		36
40184ad6884SPeter Tyser#define S_R8		32
40284ad6884SPeter Tyser#define S_R7		28
40384ad6884SPeter Tyser#define S_R6		24
40484ad6884SPeter Tyser#define S_R5		20
40584ad6884SPeter Tyser#define S_R4		16
40684ad6884SPeter Tyser#define S_R3		12
40784ad6884SPeter Tyser#define S_R2		8
40884ad6884SPeter Tyser#define S_R1		4
40984ad6884SPeter Tyser#define S_R0		0
41084ad6884SPeter Tyser
41184ad6884SPeter Tyser#define MODE_SVC 0x13
41284ad6884SPeter Tyser
41384ad6884SPeter Tyser	/* use bad_save_user_regs for abort/prefetch/undef/swi ...	    */
41484ad6884SPeter Tyser
41584ad6884SPeter Tyser	.macro	bad_save_user_regs
41684ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
41784ad6884SPeter Tyser	stmia	sp, {r0 - r12}			/* Calling r0-r12	    */
41884ad6884SPeter Tyser	add	r8, sp, #S_PC
41984ad6884SPeter Tyser
4205347f68cSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
42184ad6884SPeter Tyser	ldr	r2, _armboot_start
42284ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
42384ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)	@ set base 2 words into abort stack
4245347f68cSHeiko Schocher#else
4255347f68cSHeiko Schocher	ldr	r2, IRQ_STACK_START_IN
4265347f68cSHeiko Schocher#endif
42784ad6884SPeter Tyser	ldmia	r2, {r2 - r4}			/* get pc, cpsr, old_r0	    */
42884ad6884SPeter Tyser	add	r0, sp, #S_FRAME_SIZE		/* restore sp_SVC	    */
42984ad6884SPeter Tyser
43084ad6884SPeter Tyser	add	r5, sp, #S_SP
43184ad6884SPeter Tyser	mov	r1, lr
43284ad6884SPeter Tyser	stmia	r5, {r0 - r4}			/* save sp_SVC, lr_SVC, pc, cpsr, old_r */
43384ad6884SPeter Tyser	mov	r0, sp
43484ad6884SPeter Tyser	.endm
43584ad6884SPeter Tyser
43684ad6884SPeter Tyser
43784ad6884SPeter Tyser	/* use irq_save_user_regs / irq_restore_user_regs for		     */
43884ad6884SPeter Tyser	/* IRQ/FIQ handling						     */
43984ad6884SPeter Tyser
44084ad6884SPeter Tyser	.macro	irq_save_user_regs
44184ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
44284ad6884SPeter Tyser	stmia	sp, {r0 - r12}			/* Calling r0-r12	     */
44384ad6884SPeter Tyser	add	r8, sp, #S_PC
44484ad6884SPeter Tyser	stmdb	r8, {sp, lr}^			/* Calling SP, LR	     */
44584ad6884SPeter Tyser	str	lr, [r8, #0]			/* Save calling PC	     */
44684ad6884SPeter Tyser	mrs	r6, spsr
44784ad6884SPeter Tyser	str	r6, [r8, #4]			/* Save CPSR		     */
44884ad6884SPeter Tyser	str	r0, [r8, #8]			/* Save OLD_R0		     */
44984ad6884SPeter Tyser	mov	r0, sp
45084ad6884SPeter Tyser	.endm
45184ad6884SPeter Tyser
45284ad6884SPeter Tyser	.macro	irq_restore_user_regs
45384ad6884SPeter Tyser	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
45484ad6884SPeter Tyser	mov	r0, r0
45584ad6884SPeter Tyser	ldr	lr, [sp, #S_PC]			@ Get PC
45684ad6884SPeter Tyser	add	sp, sp, #S_FRAME_SIZE
45784ad6884SPeter Tyser	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
45884ad6884SPeter Tyser	.endm
45984ad6884SPeter Tyser
46084ad6884SPeter Tyser	.macro get_bad_stack
4615347f68cSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
46284ad6884SPeter Tyser	ldr	r13, _armboot_start		@ setup our mode stack
46384ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
46484ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
4655347f68cSHeiko Schocher#else
4665347f68cSHeiko Schocher	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
4675347f68cSHeiko Schocher#endif
46884ad6884SPeter Tyser
46984ad6884SPeter Tyser	str	lr, [r13]			@ save caller lr / spsr
47084ad6884SPeter Tyser	mrs	lr, spsr
47184ad6884SPeter Tyser	str	lr, [r13, #4]
47284ad6884SPeter Tyser
47384ad6884SPeter Tyser	mov	r13, #MODE_SVC			@ prepare SVC-Mode
47484ad6884SPeter Tyser	msr	spsr_c, r13
47584ad6884SPeter Tyser	mov	lr, pc
47684ad6884SPeter Tyser	movs	pc, lr
47784ad6884SPeter Tyser	.endm
47884ad6884SPeter Tyser
47984ad6884SPeter Tyser	.macro get_irq_stack			@ setup IRQ stack
48084ad6884SPeter Tyser	ldr	sp, IRQ_STACK_START
48184ad6884SPeter Tyser	.endm
48284ad6884SPeter Tyser
48384ad6884SPeter Tyser	.macro get_fiq_stack			@ setup FIQ stack
48484ad6884SPeter Tyser	ldr	sp, FIQ_STACK_START
48584ad6884SPeter Tyser	.endm
4865ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
48784ad6884SPeter Tyser
48884ad6884SPeter Tyser
48984ad6884SPeter Tyser/****************************************************************************/
49084ad6884SPeter Tyser/*									    */
49184ad6884SPeter Tyser/* exception handlers							    */
49284ad6884SPeter Tyser/*									    */
49384ad6884SPeter Tyser/****************************************************************************/
49484ad6884SPeter Tyser
4955ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
4965ab877b6SMarek Vasut	.align	5
4975ab877b6SMarek Vasutdo_hang:
4985ab877b6SMarek Vasut	ldr	sp, _TEXT_BASE			/* use 32 words abort stack */
4995ab877b6SMarek Vasut	bl	hang				/* hang and never return */
5005ab877b6SMarek Vasut#else	/* !CONFIG_PRELOADER */
50184ad6884SPeter Tyser	.align	5
50284ad6884SPeter Tyserundefined_instruction:
50384ad6884SPeter Tyser	get_bad_stack
50484ad6884SPeter Tyser	bad_save_user_regs
50584ad6884SPeter Tyser	bl	do_undefined_instruction
50684ad6884SPeter Tyser
50784ad6884SPeter Tyser	.align	5
50884ad6884SPeter Tysersoftware_interrupt:
50984ad6884SPeter Tyser	get_bad_stack
51084ad6884SPeter Tyser	bad_save_user_regs
51184ad6884SPeter Tyser	bl	do_software_interrupt
51284ad6884SPeter Tyser
51384ad6884SPeter Tyser	.align	5
51484ad6884SPeter Tyserprefetch_abort:
51584ad6884SPeter Tyser	get_bad_stack
51684ad6884SPeter Tyser	bad_save_user_regs
51784ad6884SPeter Tyser	bl	do_prefetch_abort
51884ad6884SPeter Tyser
51984ad6884SPeter Tyser	.align	5
52084ad6884SPeter Tyserdata_abort:
52184ad6884SPeter Tyser	get_bad_stack
52284ad6884SPeter Tyser	bad_save_user_regs
52384ad6884SPeter Tyser	bl	do_data_abort
52484ad6884SPeter Tyser
52584ad6884SPeter Tyser	.align	5
52684ad6884SPeter Tysernot_used:
52784ad6884SPeter Tyser	get_bad_stack
52884ad6884SPeter Tyser	bad_save_user_regs
52984ad6884SPeter Tyser	bl	do_not_used
53084ad6884SPeter Tyser
53184ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
53284ad6884SPeter Tyser
53384ad6884SPeter Tyser	.align	5
53484ad6884SPeter Tyserirq:
53584ad6884SPeter Tyser	get_irq_stack
53684ad6884SPeter Tyser	irq_save_user_regs
53784ad6884SPeter Tyser	bl	do_irq
53884ad6884SPeter Tyser	irq_restore_user_regs
53984ad6884SPeter Tyser
54084ad6884SPeter Tyser	.align	5
54184ad6884SPeter Tyserfiq:
54284ad6884SPeter Tyser	get_fiq_stack
54384ad6884SPeter Tyser	irq_save_user_regs		/* someone ought to write a more    */
54484ad6884SPeter Tyser	bl	do_fiq			/* effiction fiq_save_user_regs	    */
54584ad6884SPeter Tyser	irq_restore_user_regs
54684ad6884SPeter Tyser
54784ad6884SPeter Tyser#else /* !CONFIG_USE_IRQ */
54884ad6884SPeter Tyser
54984ad6884SPeter Tyser	.align	5
55084ad6884SPeter Tyserirq:
55184ad6884SPeter Tyser	get_bad_stack
55284ad6884SPeter Tyser	bad_save_user_regs
55384ad6884SPeter Tyser	bl	do_irq
55484ad6884SPeter Tyser
55584ad6884SPeter Tyser	.align	5
55684ad6884SPeter Tyserfiq:
55784ad6884SPeter Tyser	get_bad_stack
55884ad6884SPeter Tyser	bad_save_user_regs
55984ad6884SPeter Tyser	bl	do_fiq
5605ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
56184ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
56284ad6884SPeter Tyser
56384ad6884SPeter Tyser/****************************************************************************/
56484ad6884SPeter Tyser/*									    */
56584ad6884SPeter Tyser/* Reset function: the PXA250 doesn't have a reset function, so we have to  */
56684ad6884SPeter Tyser/* perform a watchdog timeout for a soft reset.				    */
56784ad6884SPeter Tyser/*									    */
56884ad6884SPeter Tyser/****************************************************************************/
569*2cad92fdSMarek Vasut/* Operating System Timer */
570*2cad92fdSMarek VasutOSTIMER_BASE:	.word	0x40a00000
571*2cad92fdSMarek Vasut#define OSMR3	0x0C
572*2cad92fdSMarek Vasut#define OSCR	0x10
573*2cad92fdSMarek Vasut#define OWER	0x18
574*2cad92fdSMarek Vasut#define OIER	0x1C
57584ad6884SPeter Tyser
57684ad6884SPeter Tyser	.align	5
57784ad6884SPeter Tyser.globl reset_cpu
57884ad6884SPeter Tyser
57984ad6884SPeter Tyser	/* FIXME: this code is PXA250 specific. How is this handled on	    */
58084ad6884SPeter Tyser	/*	  other XScale processors?				    */
58184ad6884SPeter Tyser
58284ad6884SPeter Tyserreset_cpu:
58384ad6884SPeter Tyser
58484ad6884SPeter Tyser	/* We set OWE:WME (watchdog enable) and wait until timeout happens  */
58584ad6884SPeter Tyser
58684ad6884SPeter Tyser	ldr	r0, OSTIMER_BASE
58784ad6884SPeter Tyser	ldr	r1, [r0, #OWER]
58884ad6884SPeter Tyser	orr	r1, r1, #0x0001			/* bit0: WME		    */
58984ad6884SPeter Tyser	str	r1, [r0, #OWER]
59084ad6884SPeter Tyser
59184ad6884SPeter Tyser	/* OS timer does only wrap every 1165 seconds, so we have to set    */
59284ad6884SPeter Tyser	/* the match register as well.					    */
59384ad6884SPeter Tyser
59484ad6884SPeter Tyser	ldr	r1, [r0, #OSCR]			/* read OS timer	    */
59584ad6884SPeter Tyser	add	r1, r1, #0x800			/* let OSMR3 match after    */
59684ad6884SPeter Tyser	add	r1, r1, #0x800			/* 4096*(1/3.6864MHz)=1ms   */
59784ad6884SPeter Tyser	str	r1, [r0, #OSMR3]
59884ad6884SPeter Tyser
59984ad6884SPeter Tyserreset_endless:
60084ad6884SPeter Tyser
60184ad6884SPeter Tyser	b	reset_endless
602*2cad92fdSMarek Vasut
603*2cad92fdSMarek Vasut#ifndef CONFIG_PRELOADER
604*2cad92fdSMarek Vasut.section .mmudata, "a"
605*2cad92fdSMarek Vasut	.align	14
606*2cad92fdSMarek Vasut	.globl	mmu_table
607*2cad92fdSMarek Vasutmmu_table:
608*2cad92fdSMarek Vasut	/* 0x00000000 - 0xa0000000 : 1:1, uncached mapping */
609*2cad92fdSMarek Vasut	.set	__base, 0
610*2cad92fdSMarek Vasut	.rept	0xa00
611*2cad92fdSMarek Vasut	.word	(__base << 20) | 0xc12
612*2cad92fdSMarek Vasut	.set	__base, __base + 1
613*2cad92fdSMarek Vasut	.endr
614*2cad92fdSMarek Vasut
615*2cad92fdSMarek Vasut	/* 0xa0000000 - 0xa0100000 : 1:1, cached mapping */
616*2cad92fdSMarek Vasut	.word	(0xa00 << 20) | 0x1c1e
617*2cad92fdSMarek Vasut
618*2cad92fdSMarek Vasut	.set	__base, 0xa01
619*2cad92fdSMarek Vasut	.rept	0x1000 - 0xa01
620*2cad92fdSMarek Vasut	.word	(__base << 20) | 0xc12
621*2cad92fdSMarek Vasut	.set	__base, __base + 1
622*2cad92fdSMarek Vasut	.endr
623*2cad92fdSMarek Vasut#endif
624