xref: /openbmc/u-boot/arch/arm/cpu/pxa/start.S (revision 25ddd1fb)
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>
116e96cf9aSMarek Vasut *  Copyright (c) 2010	Marek Vasut <marek.vasut@gmail.com>
1284ad6884SPeter Tyser *
1384ad6884SPeter Tyser * See file CREDITS for list of people who contributed to this
1484ad6884SPeter Tyser * project.
1584ad6884SPeter Tyser *
1684ad6884SPeter Tyser * This program is free software; you can redistribute it and/or
1784ad6884SPeter Tyser * modify it under the terms of the GNU General Public License as
1884ad6884SPeter Tyser * published by the Free Software Foundation; either version 2 of
1984ad6884SPeter Tyser * the License, or (at your option) any later version.
2084ad6884SPeter Tyser *
2184ad6884SPeter Tyser * This program is distributed in the hope that it will be useful,
2284ad6884SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of
2384ad6884SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
2484ad6884SPeter Tyser * GNU General Public License for more details.
2584ad6884SPeter Tyser *
2684ad6884SPeter Tyser * You should have received a copy of the GNU General Public License
2784ad6884SPeter Tyser * along with this program; if not, write to the Free Software
2884ad6884SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
2984ad6884SPeter Tyser * MA 02111-1307 USA
3084ad6884SPeter Tyser */
3184ad6884SPeter Tyser
32*25ddd1fbSWolfgang Denk#include <asm-offsets.h>
3384ad6884SPeter Tyser#include <config.h>
3484ad6884SPeter Tyser#include <version.h>
3584ad6884SPeter Tyser#include <asm/arch/pxa-regs.h>
362cad92fdSMarek Vasut#include <asm/arch/macro.h>
372cad92fdSMarek Vasut
382cad92fdSMarek Vasut/* takes care the CP15 update has taken place */
392cad92fdSMarek Vasut.macro CPWAIT reg
402cad92fdSMarek Vasutmrc  p15,0,\reg,c2,c0,0
412cad92fdSMarek Vasutmov  \reg,\reg
422cad92fdSMarek Vasutsub  pc,pc,#4
432cad92fdSMarek Vasut.endm
4484ad6884SPeter Tyser
4584ad6884SPeter Tyser.globl _start
4684ad6884SPeter Tyser_start: b	reset
475ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
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	ldr	pc, _hang
545ab877b6SMarek Vasut	ldr	pc, _hang
555ab877b6SMarek Vasut
565ab877b6SMarek Vasut_hang:
575ab877b6SMarek Vasut	.word	do_hang
585ab877b6SMarek Vasut	.word	0x12345678
595ab877b6SMarek Vasut	.word	0x12345678
605ab877b6SMarek Vasut	.word	0x12345678
615ab877b6SMarek Vasut	.word	0x12345678
625ab877b6SMarek Vasut	.word	0x12345678
635ab877b6SMarek Vasut	.word	0x12345678
645ab877b6SMarek Vasut	.word	0x12345678	/* now 16*4=64 */
655ab877b6SMarek Vasut#else
6684ad6884SPeter Tyser	ldr	pc, _undefined_instruction
6784ad6884SPeter Tyser	ldr	pc, _software_interrupt
6884ad6884SPeter Tyser	ldr	pc, _prefetch_abort
6984ad6884SPeter Tyser	ldr	pc, _data_abort
7084ad6884SPeter Tyser	ldr	pc, _not_used
7184ad6884SPeter Tyser	ldr	pc, _irq
7284ad6884SPeter Tyser	ldr	pc, _fiq
7384ad6884SPeter Tyser
7484ad6884SPeter Tyser_undefined_instruction: .word undefined_instruction
7584ad6884SPeter Tyser_software_interrupt:	.word software_interrupt
7684ad6884SPeter Tyser_prefetch_abort:	.word prefetch_abort
7784ad6884SPeter Tyser_data_abort:		.word data_abort
7884ad6884SPeter Tyser_not_used:		.word not_used
7984ad6884SPeter Tyser_irq:			.word irq
8084ad6884SPeter Tyser_fiq:			.word fiq
815ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
8284ad6884SPeter Tyser
8384ad6884SPeter Tyser	.balignl 16,0xdeadbeef
8484ad6884SPeter Tyser
8584ad6884SPeter Tyser
8684ad6884SPeter Tyser/*
8784ad6884SPeter Tyser * Startup Code (reset vector)
8884ad6884SPeter Tyser *
8984ad6884SPeter Tyser * do important init only if we don't start from RAM!
9084ad6884SPeter Tyser * - relocate armboot to RAM
9184ad6884SPeter Tyser * - setup stack
9284ad6884SPeter Tyser * - jump to second stage
9384ad6884SPeter Tyser */
9484ad6884SPeter Tyser
955347f68cSHeiko Schocher.globl _TEXT_BASE
9684ad6884SPeter Tyser_TEXT_BASE:
9714d0a02aSWolfgang Denk	.word	CONFIG_SYS_TEXT_BASE
9884ad6884SPeter Tyser
9984ad6884SPeter Tyser/*
10084ad6884SPeter Tyser * These are defined in the board-specific linker script.
10184ad6884SPeter Tyser */
1026e96cf9aSMarek Vasut.globl _bss_start_ofs
1036e96cf9aSMarek Vasut_bss_start_ofs:
1046e96cf9aSMarek Vasut	.word __bss_start - _start
10584ad6884SPeter Tyser
1066e96cf9aSMarek Vasut.globl _bss_end_ofs
1076e96cf9aSMarek Vasut_bss_end_ofs:
1086e96cf9aSMarek Vasut	.word _end - _start
10984ad6884SPeter Tyser
11084ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
11184ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
11284ad6884SPeter Tyser.globl IRQ_STACK_START
11384ad6884SPeter TyserIRQ_STACK_START:
11484ad6884SPeter Tyser	.word	0x0badc0de
11584ad6884SPeter Tyser
11684ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
11784ad6884SPeter Tyser.globl FIQ_STACK_START
11884ad6884SPeter TyserFIQ_STACK_START:
11984ad6884SPeter Tyser	.word 0x0badc0de
12084ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
12184ad6884SPeter Tyser
1222cad92fdSMarek Vasut#ifndef CONFIG_PRELOADER
1235347f68cSHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */
1245347f68cSHeiko Schocher.globl IRQ_STACK_START_IN
1255347f68cSHeiko SchocherIRQ_STACK_START_IN:
1265347f68cSHeiko Schocher	.word	0x0badc0de
1275347f68cSHeiko Schocher
1285347f68cSHeiko Schocher/*
1295347f68cSHeiko Schocher * the actual reset code
1305347f68cSHeiko Schocher */
1315347f68cSHeiko Schocher
1325347f68cSHeiko Schocherreset:
1335347f68cSHeiko Schocher	/*
1345347f68cSHeiko Schocher	 * set the cpu to SVC32 mode
1355347f68cSHeiko Schocher	 */
1365347f68cSHeiko Schocher	mrs	r0,cpsr
1375347f68cSHeiko Schocher	bic	r0,r0,#0x1f
1385347f68cSHeiko Schocher	orr	r0,r0,#0xd3
1395347f68cSHeiko Schocher	msr	cpsr,r0
1405347f68cSHeiko Schocher
1415347f68cSHeiko Schocher	/*
1422cad92fdSMarek Vasut	 * Enable MMU to use DCache as DRAM
1435347f68cSHeiko Schocher	 */
1442cad92fdSMarek Vasut	/* Domain access -- enable for all CPs */
1452cad92fdSMarek Vasut	ldr	r0, =0x0000ffff
1462cad92fdSMarek Vasut	mcr	p15, 0, r0, c3, c0, 0
1472cad92fdSMarek Vasut
1482cad92fdSMarek Vasut	/* Point TTBR to MMU table */
1492cad92fdSMarek Vasut	ldr	r0, =mmu_table
1502cad92fdSMarek Vasut	adr	r2, _start
1512cad92fdSMarek Vasut	orr	r0, r2
1522cad92fdSMarek Vasut	mcr	p15, 0, r0, c2, c0, 0
1532cad92fdSMarek Vasut
1542cad92fdSMarek Vasut/* !!! Hereby, check if the code is running from SRAM !!! */
1552cad92fdSMarek Vasut/* If the code is running from SRAM, alias SRAM to 0x0 to simulate NOR. The code
1562cad92fdSMarek Vasut * is linked to 0x0 too, so this makes things easier. */
1572cad92fdSMarek Vasut	cmp	r2, #0x5c000000
1582cad92fdSMarek Vasut
1592cad92fdSMarek Vasut	ldreq	r1, [r0]
1602cad92fdSMarek Vasut	orreq	r1, r2
1612cad92fdSMarek Vasut	streq	r1, [r0]
1622cad92fdSMarek Vasut
1632cad92fdSMarek Vasut	/* Kick in MMU, ICache, DCache, BTB */
1642cad92fdSMarek Vasut	mrc	p15, 0, r0, c1, c0, 0
1652cad92fdSMarek Vasut	bic	r0, #0x1b00
1662cad92fdSMarek Vasut	bic	r0, #0x0087
1672cad92fdSMarek Vasut	orr	r0, #0x1800
1682cad92fdSMarek Vasut	orr	r0, #0x0005
1692cad92fdSMarek Vasut	mcr	p15, 0, r0, c1, c0, 0
1702cad92fdSMarek Vasut	CPWAIT	r0
1712cad92fdSMarek Vasut
1722cad92fdSMarek Vasut	/* Unlock Icache, Dcache */
1732cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c1, 1
1742cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c2, 1
1752cad92fdSMarek Vasut
1762cad92fdSMarek Vasut	/* Flush Icache, Dcache, BTB */
1772cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c7, 0
1782cad92fdSMarek Vasut
1792cad92fdSMarek Vasut	/* Unlock I-TLB, D-TLB */
1802cad92fdSMarek Vasut	mcr	p15, 0, r0, c10, c4, 1
1812cad92fdSMarek Vasut	mcr	p15, 0, r0, c10, c8, 1
1822cad92fdSMarek Vasut
1832cad92fdSMarek Vasut	/* Flush TLB */
1842cad92fdSMarek Vasut	mcr	p15, 0, r0, c8, c7, 0
1852cad92fdSMarek Vasut	/* Allocate 4096 bytes of Dcache as RAM */
1862cad92fdSMarek Vasut
1872cad92fdSMarek Vasut	/* Drain pending loads and stores */
1882cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
1892cad92fdSMarek Vasut
1902cad92fdSMarek Vasut	mov	r4, #0x00
1912cad92fdSMarek Vasut	mov	r5, #0x00
1922cad92fdSMarek Vasut	mov	r2, #0x01
1932cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c2, 0
1942cad92fdSMarek Vasut	CPWAIT	r0
1952cad92fdSMarek Vasut
1962cad92fdSMarek Vasut	/* 128 lines reserved (128 x 32bytes = 4096 bytes total) */
1972cad92fdSMarek Vasut	mov	r0, #128
1982cad92fdSMarek Vasut	mov	r1, #0xa0000000
1992cad92fdSMarek Vasutalloc:
2002cad92fdSMarek Vasut	mcr	p15, 0, r1, c7, c2, 5
2012cad92fdSMarek Vasut	/* Drain pending loads and stores */
2022cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
2032cad92fdSMarek Vasut	strd	r4, [r1], #8
2042cad92fdSMarek Vasut	strd	r4, [r1], #8
2052cad92fdSMarek Vasut	strd	r4, [r1], #8
2062cad92fdSMarek Vasut	strd	r4, [r1], #8
2072cad92fdSMarek Vasut	subs	r0, #0x01
2082cad92fdSMarek Vasut	bne	alloc
2092cad92fdSMarek Vasut	/* Drain pending loads and stores */
2102cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
2112cad92fdSMarek Vasut	mov	r2, #0x00
2122cad92fdSMarek Vasut	mcr	p15, 0, r2, c9, c2, 0
2132cad92fdSMarek Vasut	CPWAIT	r0
2142cad92fdSMarek Vasut
2152cad92fdSMarek Vasut	/* Jump to 0x0 ( + offset) if running from SRAM */
2162cad92fdSMarek Vasut	adr	r0, zerojmp
2172cad92fdSMarek Vasut	bic	r0, #0x5c000000
2182cad92fdSMarek Vasut	mov	pc, r0
2192cad92fdSMarek Vasutzerojmp:
2205347f68cSHeiko Schocher
2215347f68cSHeiko Schocher/* Set stackpointer in internal RAM to call board_init_f */
2225347f68cSHeiko Schochercall_board_init_f:
2235347f68cSHeiko Schocher	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
2245347f68cSHeiko Schocher	ldr	r0,=0x00000000
2255347f68cSHeiko Schocher	bl	board_init_f
2265347f68cSHeiko Schocher
2275347f68cSHeiko Schocher/*------------------------------------------------------------------------------*/
2285347f68cSHeiko Schocher
2295347f68cSHeiko Schocher/*
2305347f68cSHeiko Schocher * void relocate_code (addr_sp, gd, addr_moni)
2315347f68cSHeiko Schocher *
2325347f68cSHeiko Schocher * This "function" does not return, instead it continues in RAM
2335347f68cSHeiko Schocher * after relocating the monitor code.
2345347f68cSHeiko Schocher *
2355347f68cSHeiko Schocher */
2365347f68cSHeiko Schocher	.globl	relocate_code
2375347f68cSHeiko Schocherrelocate_code:
2385347f68cSHeiko Schocher	mov	r4, r0	/* save addr_sp */
2395347f68cSHeiko Schocher	mov	r5, r1	/* save addr of gd */
2405347f68cSHeiko Schocher	mov	r6, r2	/* save addr of destination */
2415347f68cSHeiko Schocher	mov	r7, r2	/* save addr of destination */
2425347f68cSHeiko Schocher
2435347f68cSHeiko Schocher	/* Set up the stack						    */
2445347f68cSHeiko Schocherstack_setup:
2455347f68cSHeiko Schocher	mov	sp, r4
2465347f68cSHeiko Schocher
2475347f68cSHeiko Schocher	adr	r0, _start
2485347f68cSHeiko Schocher	ldr	r2, _TEXT_BASE
2496e96cf9aSMarek Vasut	ldr	r3, _bss_start_ofs
2506e96cf9aSMarek Vasut	add	r2, r0, r3		/* r2 <- source end address	    */
2515347f68cSHeiko Schocher	cmp	r0, r6
2525347f68cSHeiko Schocher	beq	clear_bss
2535347f68cSHeiko Schocher
2545347f68cSHeiko Schocher#ifndef CONFIG_SKIP_RELOCATE_UBOOT
2552cad92fdSMarek Vasut	stmfd sp!, {r0-r12}
2565347f68cSHeiko Schochercopy_loop:
2572cad92fdSMarek Vasut	ldmia	r0!, {r3-r5, r7-r11}	/* copy from source address [r0]    */
2582cad92fdSMarek Vasut	stmia	r6!, {r3-r5, r7-r11}	/* copy to   target address [r1]    */
259da90d4ceSAlbert Aribaud	cmp	r0, r2			/* until source end address [r2]    */
260da90d4ceSAlbert Aribaud	blo	copy_loop
2612cad92fdSMarek Vasut	ldmfd sp!, {r0-r12}
2625347f68cSHeiko Schocher
2635347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
2646e96cf9aSMarek Vasut	/*
2656e96cf9aSMarek Vasut	 * fix .rel.dyn relocations
2666e96cf9aSMarek Vasut	 */
2676e96cf9aSMarek Vasut	ldr	r0, _TEXT_BASE		/* r0 <- Text base */
2686e96cf9aSMarek Vasut	sub	r9, r7, r0		/* r9 <- relocation offset */
2696e96cf9aSMarek Vasut	ldr	r10, _dynsym_start_ofs	/* r10 <- sym table ofs */
2706e96cf9aSMarek Vasut	add	r10, r10, r0		/* r10 <- sym table in FLASH */
2716e96cf9aSMarek Vasut	ldr	r2, _rel_dyn_start_ofs	/* r2 <- rel dyn start ofs */
2726e96cf9aSMarek Vasut	add	r2, r2, r0		/* r2 <- rel dyn start in FLASH */
2736e96cf9aSMarek Vasut	ldr	r3, _rel_dyn_end_ofs	/* r3 <- rel dyn end ofs */
2746e96cf9aSMarek Vasut	add	r3, r3, r0		/* r3 <- rel dyn end in FLASH */
2755347f68cSHeiko Schocherfixloop:
2766e96cf9aSMarek Vasut	ldr	r0, [r2]	/* r0 <- location to fix up, IN FLASH! */
2776e96cf9aSMarek Vasut	add	r0, r9		/* r0 <- location to fix up in RAM */
2786e96cf9aSMarek Vasut	ldr	r1, [r2, #4]
2796e96cf9aSMarek Vasut	and	r8, r1, #0xff
2806e96cf9aSMarek Vasut	cmp	r8, #23		/* relative fixup? */
2816e96cf9aSMarek Vasut	beq	fixrel
2826e96cf9aSMarek Vasut	cmp	r8, #2		/* absolute fixup? */
2836e96cf9aSMarek Vasut	beq	fixabs
2846e96cf9aSMarek Vasut	/* ignore unknown type of fixup */
2856e96cf9aSMarek Vasut	b	fixnext
2866e96cf9aSMarek Vasutfixabs:
2876e96cf9aSMarek Vasut	/* absolute fix: set location to (offset) symbol value */
2886e96cf9aSMarek Vasut	mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */
2896e96cf9aSMarek Vasut	add	r1, r10, r1		/* r1 <- address of symbol in table */
2906e96cf9aSMarek Vasut	ldr	r1, [r1, #4]		/* r1 <- symbol value */
2916e96cf9aSMarek Vasut	add	r1, r9			/* r1 <- relocated sym addr */
2926e96cf9aSMarek Vasut	b	fixnext
2936e96cf9aSMarek Vasutfixrel:
2946e96cf9aSMarek Vasut	/* relative fix: increase location by offset */
2956e96cf9aSMarek Vasut	ldr	r1, [r0]
2966e96cf9aSMarek Vasut	add	r1, r1, r9
2976e96cf9aSMarek Vasutfixnext:
2986e96cf9aSMarek Vasut	str	r1, [r0]
2996e96cf9aSMarek Vasut	add	r2, r2, #8	/* each rel.dyn entry is 8 bytes */
3005347f68cSHeiko Schocher	cmp	r2, r3
3016e96cf9aSMarek Vasut	blo	fixloop
3025347f68cSHeiko Schocher#endif
3035347f68cSHeiko Schocher#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
3045347f68cSHeiko Schocher
3055347f68cSHeiko Schocherclear_bss:
3065347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
3076e96cf9aSMarek Vasut	ldr	r0, _bss_start_ofs
3086e96cf9aSMarek Vasut	ldr	r1, _bss_end_ofs
3095347f68cSHeiko Schocher	ldr	r3, _TEXT_BASE		/* Text base */
3105347f68cSHeiko Schocher	mov	r4, r7			/* reloc addr */
3115347f68cSHeiko Schocher	add	r0, r0, r4
3125347f68cSHeiko Schocher	add	r1, r1, r4
3135347f68cSHeiko Schocher	mov	r2, #0x00000000		/* clear			    */
3145347f68cSHeiko Schocher
3155347f68cSHeiko Schocherclbss_l:str	r2, [r0]		/* clear loop...		    */
3165347f68cSHeiko Schocher	add	r0, r0, #4
3175347f68cSHeiko Schocher	cmp	r0, r1
3185347f68cSHeiko Schocher	bne	clbss_l
3195347f68cSHeiko Schocher#endif
3205347f68cSHeiko Schocher
3215347f68cSHeiko Schocher/*
3225347f68cSHeiko Schocher * We are done. Do not return, instead branch to second part of board
3235347f68cSHeiko Schocher * initialization, now running from RAM.
3245347f68cSHeiko Schocher */
3255347f68cSHeiko Schocher#ifdef CONFIG_ONENAND_IPL
3266e96cf9aSMarek Vasut	ldr     r0, _start_oneboot_ofs
3276e96cf9aSMarek Vasut	mov	pc, r0
3285347f68cSHeiko Schocher
3296e96cf9aSMarek Vasut_start_oneboot_ofs
3306e96cf9aSMarek Vasut	: .word start_oneboot
3315347f68cSHeiko Schocher#else
3326e96cf9aSMarek Vasut	ldr	r0, _board_init_r_ofs
3336e96cf9aSMarek Vasut	adr	r1, _start
3346e96cf9aSMarek Vasut	add	r0, r0, r1
3356e96cf9aSMarek Vasut	add	lr, r0, r9
3365347f68cSHeiko Schocher	/* setup parameters for board_init_r */
3375347f68cSHeiko Schocher	mov	r0, r5		/* gd_t */
3385347f68cSHeiko Schocher	mov	r1, r7		/* dest_addr */
3395347f68cSHeiko Schocher	/* jump to it ... */
3405347f68cSHeiko Schocher	mov	pc, lr
3415347f68cSHeiko Schocher
3426e96cf9aSMarek Vasut_board_init_r_ofs:
3436e96cf9aSMarek Vasut	.word board_init_r - _start
3445347f68cSHeiko Schocher#endif
3455347f68cSHeiko Schocher
3466e96cf9aSMarek Vasut_rel_dyn_start_ofs:
3476e96cf9aSMarek Vasut	.word __rel_dyn_start - _start
3486e96cf9aSMarek Vasut_rel_dyn_end_ofs:
3496e96cf9aSMarek Vasut	.word __rel_dyn_end - _start
3506e96cf9aSMarek Vasut_dynsym_start_ofs:
3516e96cf9aSMarek Vasut	.word __dynsym_start - _start
3526e96cf9aSMarek Vasut
3535347f68cSHeiko Schocher#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
35484ad6884SPeter Tyser
35584ad6884SPeter Tyser/****************************************************************************/
35684ad6884SPeter Tyser/*									    */
3572cad92fdSMarek Vasut/* the actual reset code for OneNAND IPL				    */
35884ad6884SPeter Tyser/*									    */
35984ad6884SPeter Tyser/****************************************************************************/
36084ad6884SPeter Tyser
3612cad92fdSMarek Vasut#ifndef	CONFIG_PXA27X
3622cad92fdSMarek Vasut#error OneNAND IPL is not supported on PXA25x and 26x due to lack of SRAM
3632cad92fdSMarek Vasut#endif
3642cad92fdSMarek Vasut
36584ad6884SPeter Tyserreset:
3662cad92fdSMarek Vasut	/* Set CPU to SVC32 mode */
3672cad92fdSMarek Vasut	mrs	r0,cpsr
3682cad92fdSMarek Vasut	bic	r0,r0,#0x1f
36984ad6884SPeter Tyser	orr	r0,r0,#0x13
37084ad6884SPeter Tyser	msr	cpsr,r0
37184ad6884SPeter Tyser
3722cad92fdSMarek Vasut	/* Point stack at the end of SRAM and leave 32 words for abort-stack */
3732cad92fdSMarek Vasut	ldr	sp, =0x5c03ff80
37484ad6884SPeter Tyser
3752cad92fdSMarek Vasut	/* Start OneNAND IPL */
3762cad92fdSMarek Vasut	ldr	pc, =start_oneboot
37784ad6884SPeter Tyser
3782cad92fdSMarek 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)
423*25ddd1fbSWolfgang Denk	sub	r2, r2, #(GENERATED_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)
464*25ddd1fbSWolfgang Denk	sub	r13, r13, #(GENERATED_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/****************************************************************************/
5692cad92fdSMarek Vasut/* Operating System Timer */
57084ad6884SPeter Tyser.align	5
57184ad6884SPeter Tyser.globl reset_cpu
57284ad6884SPeter Tyser
57384ad6884SPeter Tyser	/* FIXME: this code is PXA250 specific. How is this handled on	    */
57484ad6884SPeter Tyser	/*	  other XScale processors?				    */
57584ad6884SPeter Tyser
57684ad6884SPeter Tyserreset_cpu:
57784ad6884SPeter Tyser
57884ad6884SPeter Tyser	/* We set OWE:WME (watchdog enable) and wait until timeout happens  */
57984ad6884SPeter Tyser
5804abf2f7aSMarek Vasut	ldr	r0, =OWER
5814abf2f7aSMarek Vasut	ldr	r1, [r0]
58284ad6884SPeter Tyser	orr	r1, r1, #0x0001			/* bit0: WME		    */
5834abf2f7aSMarek Vasut	str	r1, [r0]
58484ad6884SPeter Tyser
58584ad6884SPeter Tyser	/* OS timer does only wrap every 1165 seconds, so we have to set    */
58684ad6884SPeter Tyser	/* the match register as well.					    */
58784ad6884SPeter Tyser
5884abf2f7aSMarek Vasut	ldr	r0, =OSCR
5894abf2f7aSMarek Vasut	ldr	r1, [r0]			/* read OS timer	    */
59084ad6884SPeter Tyser	add	r1, r1, #0x800			/* let OSMR3 match after    */
59184ad6884SPeter Tyser	add	r1, r1, #0x800			/* 4096*(1/3.6864MHz)=1ms   */
5924abf2f7aSMarek Vasut	ldr	r0, =OSMR3
5934abf2f7aSMarek Vasut	str	r1, [r0]
59484ad6884SPeter Tyser
59584ad6884SPeter Tyserreset_endless:
59684ad6884SPeter Tyser
59784ad6884SPeter Tyser	b	reset_endless
5982cad92fdSMarek Vasut
5992cad92fdSMarek Vasut#ifndef CONFIG_PRELOADER
6002cad92fdSMarek Vasut.section .mmudata, "a"
6012cad92fdSMarek Vasut	.align	14
6022cad92fdSMarek Vasut	.globl	mmu_table
6032cad92fdSMarek Vasutmmu_table:
6042cad92fdSMarek Vasut	/* 0x00000000 - 0xa0000000 : 1:1, uncached mapping */
6052cad92fdSMarek Vasut	.set	__base, 0
6062cad92fdSMarek Vasut	.rept	0xa00
6072cad92fdSMarek Vasut	.word	(__base << 20) | 0xc12
6082cad92fdSMarek Vasut	.set	__base, __base + 1
6092cad92fdSMarek Vasut	.endr
6102cad92fdSMarek Vasut
6112cad92fdSMarek Vasut	/* 0xa0000000 - 0xa0100000 : 1:1, cached mapping */
6122cad92fdSMarek Vasut	.word	(0xa00 << 20) | 0x1c1e
6132cad92fdSMarek Vasut
6142cad92fdSMarek Vasut	.set	__base, 0xa01
6152cad92fdSMarek Vasut	.rept	0x1000 - 0xa01
6162cad92fdSMarek Vasut	.word	(__base << 20) | 0xc12
6172cad92fdSMarek Vasut	.set	__base, __base + 1
6182cad92fdSMarek Vasut	.endr
6192cad92fdSMarek Vasut#endif
620