xref: /openbmc/u-boot/arch/arm/cpu/pxa/start.S (revision 4abf2f7a)
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
3284ad6884SPeter Tyser#include <config.h>
3384ad6884SPeter Tyser#include <version.h>
3484ad6884SPeter Tyser#include <asm/arch/pxa-regs.h>
352cad92fdSMarek Vasut#include <asm/arch/macro.h>
362cad92fdSMarek Vasut
372cad92fdSMarek Vasut/* takes care the CP15 update has taken place */
382cad92fdSMarek Vasut.macro CPWAIT reg
392cad92fdSMarek Vasutmrc  p15,0,\reg,c2,c0,0
402cad92fdSMarek Vasutmov  \reg,\reg
412cad92fdSMarek Vasutsub  pc,pc,#4
422cad92fdSMarek Vasut.endm
4384ad6884SPeter Tyser
4484ad6884SPeter Tyser.globl _start
4584ad6884SPeter Tyser_start: b	reset
465ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
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	ldr	pc, _hang
545ab877b6SMarek Vasut
555ab877b6SMarek Vasut_hang:
565ab877b6SMarek Vasut	.word	do_hang
575ab877b6SMarek Vasut	.word	0x12345678
585ab877b6SMarek Vasut	.word	0x12345678
595ab877b6SMarek Vasut	.word	0x12345678
605ab877b6SMarek Vasut	.word	0x12345678
615ab877b6SMarek Vasut	.word	0x12345678
625ab877b6SMarek Vasut	.word	0x12345678
635ab877b6SMarek Vasut	.word	0x12345678	/* now 16*4=64 */
645ab877b6SMarek Vasut#else
6584ad6884SPeter Tyser	ldr	pc, _undefined_instruction
6684ad6884SPeter Tyser	ldr	pc, _software_interrupt
6784ad6884SPeter Tyser	ldr	pc, _prefetch_abort
6884ad6884SPeter Tyser	ldr	pc, _data_abort
6984ad6884SPeter Tyser	ldr	pc, _not_used
7084ad6884SPeter Tyser	ldr	pc, _irq
7184ad6884SPeter Tyser	ldr	pc, _fiq
7284ad6884SPeter Tyser
7384ad6884SPeter Tyser_undefined_instruction: .word undefined_instruction
7484ad6884SPeter Tyser_software_interrupt:	.word software_interrupt
7584ad6884SPeter Tyser_prefetch_abort:	.word prefetch_abort
7684ad6884SPeter Tyser_data_abort:		.word data_abort
7784ad6884SPeter Tyser_not_used:		.word not_used
7884ad6884SPeter Tyser_irq:			.word irq
7984ad6884SPeter Tyser_fiq:			.word fiq
805ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
8184ad6884SPeter Tyser
8284ad6884SPeter Tyser	.balignl 16,0xdeadbeef
8384ad6884SPeter Tyser
8484ad6884SPeter Tyser
8584ad6884SPeter Tyser/*
8684ad6884SPeter Tyser * Startup Code (reset vector)
8784ad6884SPeter Tyser *
8884ad6884SPeter Tyser * do important init only if we don't start from RAM!
8984ad6884SPeter Tyser * - relocate armboot to RAM
9084ad6884SPeter Tyser * - setup stack
9184ad6884SPeter Tyser * - jump to second stage
9284ad6884SPeter Tyser */
9384ad6884SPeter Tyser
945347f68cSHeiko Schocher.globl _TEXT_BASE
9584ad6884SPeter Tyser_TEXT_BASE:
9614d0a02aSWolfgang Denk	.word	CONFIG_SYS_TEXT_BASE
9784ad6884SPeter Tyser
9884ad6884SPeter Tyser/*
9984ad6884SPeter Tyser * These are defined in the board-specific linker script.
10084ad6884SPeter Tyser */
1016e96cf9aSMarek Vasut.globl _bss_start_ofs
1026e96cf9aSMarek Vasut_bss_start_ofs:
1036e96cf9aSMarek Vasut	.word __bss_start - _start
10484ad6884SPeter Tyser
1056e96cf9aSMarek Vasut.globl _bss_end_ofs
1066e96cf9aSMarek Vasut_bss_end_ofs:
1076e96cf9aSMarek Vasut	.word _end - _start
10884ad6884SPeter Tyser
10984ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
11084ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
11184ad6884SPeter Tyser.globl IRQ_STACK_START
11284ad6884SPeter TyserIRQ_STACK_START:
11384ad6884SPeter Tyser	.word	0x0badc0de
11484ad6884SPeter Tyser
11584ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
11684ad6884SPeter Tyser.globl FIQ_STACK_START
11784ad6884SPeter TyserFIQ_STACK_START:
11884ad6884SPeter Tyser	.word 0x0badc0de
11984ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
12084ad6884SPeter Tyser
1212cad92fdSMarek Vasut#ifndef CONFIG_PRELOADER
1225347f68cSHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */
1235347f68cSHeiko Schocher.globl IRQ_STACK_START_IN
1245347f68cSHeiko SchocherIRQ_STACK_START_IN:
1255347f68cSHeiko Schocher	.word	0x0badc0de
1265347f68cSHeiko Schocher
1275347f68cSHeiko Schocher/*
1285347f68cSHeiko Schocher * the actual reset code
1295347f68cSHeiko Schocher */
1305347f68cSHeiko Schocher
1315347f68cSHeiko Schocherreset:
1325347f68cSHeiko Schocher	/*
1335347f68cSHeiko Schocher	 * set the cpu to SVC32 mode
1345347f68cSHeiko Schocher	 */
1355347f68cSHeiko Schocher	mrs	r0,cpsr
1365347f68cSHeiko Schocher	bic	r0,r0,#0x1f
1375347f68cSHeiko Schocher	orr	r0,r0,#0xd3
1385347f68cSHeiko Schocher	msr	cpsr,r0
1395347f68cSHeiko Schocher
1405347f68cSHeiko Schocher	/*
1412cad92fdSMarek Vasut	 * Enable MMU to use DCache as DRAM
1425347f68cSHeiko Schocher	 */
1432cad92fdSMarek Vasut	/* Domain access -- enable for all CPs */
1442cad92fdSMarek Vasut	ldr	r0, =0x0000ffff
1452cad92fdSMarek Vasut	mcr	p15, 0, r0, c3, c0, 0
1462cad92fdSMarek Vasut
1472cad92fdSMarek Vasut	/* Point TTBR to MMU table */
1482cad92fdSMarek Vasut	ldr	r0, =mmu_table
1492cad92fdSMarek Vasut	adr	r2, _start
1502cad92fdSMarek Vasut	orr	r0, r2
1512cad92fdSMarek Vasut	mcr	p15, 0, r0, c2, c0, 0
1522cad92fdSMarek Vasut
1532cad92fdSMarek Vasut/* !!! Hereby, check if the code is running from SRAM !!! */
1542cad92fdSMarek Vasut/* If the code is running from SRAM, alias SRAM to 0x0 to simulate NOR. The code
1552cad92fdSMarek Vasut * is linked to 0x0 too, so this makes things easier. */
1562cad92fdSMarek Vasut	cmp	r2, #0x5c000000
1572cad92fdSMarek Vasut
1582cad92fdSMarek Vasut	ldreq	r1, [r0]
1592cad92fdSMarek Vasut	orreq	r1, r2
1602cad92fdSMarek Vasut	streq	r1, [r0]
1612cad92fdSMarek Vasut
1622cad92fdSMarek Vasut	/* Kick in MMU, ICache, DCache, BTB */
1632cad92fdSMarek Vasut	mrc	p15, 0, r0, c1, c0, 0
1642cad92fdSMarek Vasut	bic	r0, #0x1b00
1652cad92fdSMarek Vasut	bic	r0, #0x0087
1662cad92fdSMarek Vasut	orr	r0, #0x1800
1672cad92fdSMarek Vasut	orr	r0, #0x0005
1682cad92fdSMarek Vasut	mcr	p15, 0, r0, c1, c0, 0
1692cad92fdSMarek Vasut	CPWAIT	r0
1702cad92fdSMarek Vasut
1712cad92fdSMarek Vasut	/* Unlock Icache, Dcache */
1722cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c1, 1
1732cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c2, 1
1742cad92fdSMarek Vasut
1752cad92fdSMarek Vasut	/* Flush Icache, Dcache, BTB */
1762cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c7, 0
1772cad92fdSMarek Vasut
1782cad92fdSMarek Vasut	/* Unlock I-TLB, D-TLB */
1792cad92fdSMarek Vasut	mcr	p15, 0, r0, c10, c4, 1
1802cad92fdSMarek Vasut	mcr	p15, 0, r0, c10, c8, 1
1812cad92fdSMarek Vasut
1822cad92fdSMarek Vasut	/* Flush TLB */
1832cad92fdSMarek Vasut	mcr	p15, 0, r0, c8, c7, 0
1842cad92fdSMarek Vasut	/* Allocate 4096 bytes of Dcache as RAM */
1852cad92fdSMarek Vasut
1862cad92fdSMarek Vasut	/* Drain pending loads and stores */
1872cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
1882cad92fdSMarek Vasut
1892cad92fdSMarek Vasut	mov	r4, #0x00
1902cad92fdSMarek Vasut	mov	r5, #0x00
1912cad92fdSMarek Vasut	mov	r2, #0x01
1922cad92fdSMarek Vasut	mcr	p15, 0, r0, c9, c2, 0
1932cad92fdSMarek Vasut	CPWAIT	r0
1942cad92fdSMarek Vasut
1952cad92fdSMarek Vasut	/* 128 lines reserved (128 x 32bytes = 4096 bytes total) */
1962cad92fdSMarek Vasut	mov	r0, #128
1972cad92fdSMarek Vasut	mov	r1, #0xa0000000
1982cad92fdSMarek Vasutalloc:
1992cad92fdSMarek Vasut	mcr	p15, 0, r1, c7, c2, 5
2002cad92fdSMarek Vasut	/* Drain pending loads and stores */
2012cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
2022cad92fdSMarek Vasut	strd	r4, [r1], #8
2032cad92fdSMarek Vasut	strd	r4, [r1], #8
2042cad92fdSMarek Vasut	strd	r4, [r1], #8
2052cad92fdSMarek Vasut	strd	r4, [r1], #8
2062cad92fdSMarek Vasut	subs	r0, #0x01
2072cad92fdSMarek Vasut	bne	alloc
2082cad92fdSMarek Vasut	/* Drain pending loads and stores */
2092cad92fdSMarek Vasut	mcr	p15, 0, r0, c7, c10, 4
2102cad92fdSMarek Vasut	mov	r2, #0x00
2112cad92fdSMarek Vasut	mcr	p15, 0, r2, c9, c2, 0
2122cad92fdSMarek Vasut	CPWAIT	r0
2132cad92fdSMarek Vasut
2142cad92fdSMarek Vasut	/* Jump to 0x0 ( + offset) if running from SRAM */
2152cad92fdSMarek Vasut	adr	r0, zerojmp
2162cad92fdSMarek Vasut	bic	r0, #0x5c000000
2172cad92fdSMarek Vasut	mov	pc, r0
2182cad92fdSMarek Vasutzerojmp:
2195347f68cSHeiko Schocher
2205347f68cSHeiko Schocher/* Set stackpointer in internal RAM to call board_init_f */
2215347f68cSHeiko Schochercall_board_init_f:
2225347f68cSHeiko Schocher	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
2235347f68cSHeiko Schocher	ldr	r0,=0x00000000
2245347f68cSHeiko Schocher	bl	board_init_f
2255347f68cSHeiko Schocher
2265347f68cSHeiko Schocher/*------------------------------------------------------------------------------*/
2275347f68cSHeiko Schocher
2285347f68cSHeiko Schocher/*
2295347f68cSHeiko Schocher * void relocate_code (addr_sp, gd, addr_moni)
2305347f68cSHeiko Schocher *
2315347f68cSHeiko Schocher * This "function" does not return, instead it continues in RAM
2325347f68cSHeiko Schocher * after relocating the monitor code.
2335347f68cSHeiko Schocher *
2345347f68cSHeiko Schocher */
2355347f68cSHeiko Schocher	.globl	relocate_code
2365347f68cSHeiko Schocherrelocate_code:
2375347f68cSHeiko Schocher	mov	r4, r0	/* save addr_sp */
2385347f68cSHeiko Schocher	mov	r5, r1	/* save addr of gd */
2395347f68cSHeiko Schocher	mov	r6, r2	/* save addr of destination */
2405347f68cSHeiko Schocher	mov	r7, r2	/* save addr of destination */
2415347f68cSHeiko Schocher
2425347f68cSHeiko Schocher	/* Set up the stack						    */
2435347f68cSHeiko Schocherstack_setup:
2445347f68cSHeiko Schocher	mov	sp, r4
2455347f68cSHeiko Schocher
2465347f68cSHeiko Schocher	adr	r0, _start
2475347f68cSHeiko Schocher	ldr	r2, _TEXT_BASE
2486e96cf9aSMarek Vasut	ldr	r3, _bss_start_ofs
2496e96cf9aSMarek Vasut	add	r2, r0, r3		/* r2 <- source end address	    */
2505347f68cSHeiko Schocher	cmp	r0, r6
2515347f68cSHeiko Schocher	beq	clear_bss
2525347f68cSHeiko Schocher
2535347f68cSHeiko Schocher#ifndef CONFIG_SKIP_RELOCATE_UBOOT
2542cad92fdSMarek Vasut	stmfd sp!, {r0-r12}
2555347f68cSHeiko Schochercopy_loop:
2562cad92fdSMarek Vasut	ldmia	r0!, {r3-r5, r7-r11}	/* copy from source address [r0]    */
2572cad92fdSMarek Vasut	stmia	r6!, {r3-r5, r7-r11}	/* copy to   target address [r1]    */
258da90d4ceSAlbert Aribaud	cmp	r0, r2			/* until source end address [r2]    */
259da90d4ceSAlbert Aribaud	blo	copy_loop
2602cad92fdSMarek Vasut	ldmfd sp!, {r0-r12}
2615347f68cSHeiko Schocher
2625347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
2636e96cf9aSMarek Vasut	/*
2646e96cf9aSMarek Vasut	 * fix .rel.dyn relocations
2656e96cf9aSMarek Vasut	 */
2666e96cf9aSMarek Vasut	ldr	r0, _TEXT_BASE		/* r0 <- Text base */
2676e96cf9aSMarek Vasut	sub	r9, r7, r0		/* r9 <- relocation offset */
2686e96cf9aSMarek Vasut	ldr	r10, _dynsym_start_ofs	/* r10 <- sym table ofs */
2696e96cf9aSMarek Vasut	add	r10, r10, r0		/* r10 <- sym table in FLASH */
2706e96cf9aSMarek Vasut	ldr	r2, _rel_dyn_start_ofs	/* r2 <- rel dyn start ofs */
2716e96cf9aSMarek Vasut	add	r2, r2, r0		/* r2 <- rel dyn start in FLASH */
2726e96cf9aSMarek Vasut	ldr	r3, _rel_dyn_end_ofs	/* r3 <- rel dyn end ofs */
2736e96cf9aSMarek Vasut	add	r3, r3, r0		/* r3 <- rel dyn end in FLASH */
2745347f68cSHeiko Schocherfixloop:
2756e96cf9aSMarek Vasut	ldr	r0, [r2]	/* r0 <- location to fix up, IN FLASH! */
2766e96cf9aSMarek Vasut	add	r0, r9		/* r0 <- location to fix up in RAM */
2776e96cf9aSMarek Vasut	ldr	r1, [r2, #4]
2786e96cf9aSMarek Vasut	and	r8, r1, #0xff
2796e96cf9aSMarek Vasut	cmp	r8, #23		/* relative fixup? */
2806e96cf9aSMarek Vasut	beq	fixrel
2816e96cf9aSMarek Vasut	cmp	r8, #2		/* absolute fixup? */
2826e96cf9aSMarek Vasut	beq	fixabs
2836e96cf9aSMarek Vasut	/* ignore unknown type of fixup */
2846e96cf9aSMarek Vasut	b	fixnext
2856e96cf9aSMarek Vasutfixabs:
2866e96cf9aSMarek Vasut	/* absolute fix: set location to (offset) symbol value */
2876e96cf9aSMarek Vasut	mov	r1, r1, LSR #4		/* r1 <- symbol index in .dynsym */
2886e96cf9aSMarek Vasut	add	r1, r10, r1		/* r1 <- address of symbol in table */
2896e96cf9aSMarek Vasut	ldr	r1, [r1, #4]		/* r1 <- symbol value */
2906e96cf9aSMarek Vasut	add	r1, r9			/* r1 <- relocated sym addr */
2916e96cf9aSMarek Vasut	b	fixnext
2926e96cf9aSMarek Vasutfixrel:
2936e96cf9aSMarek Vasut	/* relative fix: increase location by offset */
2946e96cf9aSMarek Vasut	ldr	r1, [r0]
2956e96cf9aSMarek Vasut	add	r1, r1, r9
2966e96cf9aSMarek Vasutfixnext:
2976e96cf9aSMarek Vasut	str	r1, [r0]
2986e96cf9aSMarek Vasut	add	r2, r2, #8	/* each rel.dyn entry is 8 bytes */
2995347f68cSHeiko Schocher	cmp	r2, r3
3006e96cf9aSMarek Vasut	blo	fixloop
3015347f68cSHeiko Schocher#endif
3025347f68cSHeiko Schocher#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
3035347f68cSHeiko Schocher
3045347f68cSHeiko Schocherclear_bss:
3055347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
3066e96cf9aSMarek Vasut	ldr	r0, _bss_start_ofs
3076e96cf9aSMarek Vasut	ldr	r1, _bss_end_ofs
3085347f68cSHeiko Schocher	ldr	r3, _TEXT_BASE		/* Text base */
3095347f68cSHeiko Schocher	mov	r4, r7			/* reloc addr */
3105347f68cSHeiko Schocher	add	r0, r0, r4
3115347f68cSHeiko Schocher	add	r1, r1, r4
3125347f68cSHeiko Schocher	mov	r2, #0x00000000		/* clear			    */
3135347f68cSHeiko Schocher
3145347f68cSHeiko Schocherclbss_l:str	r2, [r0]		/* clear loop...		    */
3155347f68cSHeiko Schocher	add	r0, r0, #4
3165347f68cSHeiko Schocher	cmp	r0, r1
3175347f68cSHeiko Schocher	bne	clbss_l
3185347f68cSHeiko Schocher#endif
3195347f68cSHeiko Schocher
3205347f68cSHeiko Schocher/*
3215347f68cSHeiko Schocher * We are done. Do not return, instead branch to second part of board
3225347f68cSHeiko Schocher * initialization, now running from RAM.
3235347f68cSHeiko Schocher */
3245347f68cSHeiko Schocher#ifdef CONFIG_ONENAND_IPL
3256e96cf9aSMarek Vasut	ldr     r0, _start_oneboot_ofs
3266e96cf9aSMarek Vasut	mov	pc, r0
3275347f68cSHeiko Schocher
3286e96cf9aSMarek Vasut_start_oneboot_ofs
3296e96cf9aSMarek Vasut	: .word start_oneboot
3305347f68cSHeiko Schocher#else
3316e96cf9aSMarek Vasut	ldr	r0, _board_init_r_ofs
3326e96cf9aSMarek Vasut	adr	r1, _start
3336e96cf9aSMarek Vasut	add	r0, r0, r1
3346e96cf9aSMarek Vasut	add	lr, r0, r9
3355347f68cSHeiko Schocher	/* setup parameters for board_init_r */
3365347f68cSHeiko Schocher	mov	r0, r5		/* gd_t */
3375347f68cSHeiko Schocher	mov	r1, r7		/* dest_addr */
3385347f68cSHeiko Schocher	/* jump to it ... */
3395347f68cSHeiko Schocher	mov	pc, lr
3405347f68cSHeiko Schocher
3416e96cf9aSMarek Vasut_board_init_r_ofs:
3426e96cf9aSMarek Vasut	.word board_init_r - _start
3435347f68cSHeiko Schocher#endif
3445347f68cSHeiko Schocher
3456e96cf9aSMarek Vasut_rel_dyn_start_ofs:
3466e96cf9aSMarek Vasut	.word __rel_dyn_start - _start
3476e96cf9aSMarek Vasut_rel_dyn_end_ofs:
3486e96cf9aSMarek Vasut	.word __rel_dyn_end - _start
3496e96cf9aSMarek Vasut_dynsym_start_ofs:
3506e96cf9aSMarek Vasut	.word __dynsym_start - _start
3516e96cf9aSMarek Vasut
3525347f68cSHeiko Schocher#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
35384ad6884SPeter Tyser
35484ad6884SPeter Tyser/****************************************************************************/
35584ad6884SPeter Tyser/*									    */
3562cad92fdSMarek Vasut/* the actual reset code for OneNAND IPL				    */
35784ad6884SPeter Tyser/*									    */
35884ad6884SPeter Tyser/****************************************************************************/
35984ad6884SPeter Tyser
3602cad92fdSMarek Vasut#ifndef	CONFIG_PXA27X
3612cad92fdSMarek Vasut#error OneNAND IPL is not supported on PXA25x and 26x due to lack of SRAM
3622cad92fdSMarek Vasut#endif
3632cad92fdSMarek Vasut
36484ad6884SPeter Tyserreset:
3652cad92fdSMarek Vasut	/* Set CPU to SVC32 mode */
3662cad92fdSMarek Vasut	mrs	r0,cpsr
3672cad92fdSMarek Vasut	bic	r0,r0,#0x1f
36884ad6884SPeter Tyser	orr	r0,r0,#0x13
36984ad6884SPeter Tyser	msr	cpsr,r0
37084ad6884SPeter Tyser
3712cad92fdSMarek Vasut	/* Point stack at the end of SRAM and leave 32 words for abort-stack */
3722cad92fdSMarek Vasut	ldr	sp, =0x5c03ff80
37384ad6884SPeter Tyser
3742cad92fdSMarek Vasut	/* Start OneNAND IPL */
3752cad92fdSMarek Vasut	ldr	pc, =start_oneboot
37684ad6884SPeter Tyser
3772cad92fdSMarek Vasut#endif /* #if !defined(CONFIG_ONENAND_IPL) */
37884ad6884SPeter Tyser
3795ab877b6SMarek Vasut#ifndef CONFIG_PRELOADER
38084ad6884SPeter Tyser/****************************************************************************/
38184ad6884SPeter Tyser/*									    */
38284ad6884SPeter Tyser/* Interrupt handling							    */
38384ad6884SPeter Tyser/*									    */
38484ad6884SPeter Tyser/****************************************************************************/
38584ad6884SPeter Tyser
38684ad6884SPeter Tyser/* IRQ stack frame							    */
38784ad6884SPeter Tyser
38884ad6884SPeter Tyser#define S_FRAME_SIZE	72
38984ad6884SPeter Tyser
39084ad6884SPeter Tyser#define S_OLD_R0	68
39184ad6884SPeter Tyser#define S_PSR		64
39284ad6884SPeter Tyser#define S_PC		60
39384ad6884SPeter Tyser#define S_LR		56
39484ad6884SPeter Tyser#define S_SP		52
39584ad6884SPeter Tyser
39684ad6884SPeter Tyser#define S_IP		48
39784ad6884SPeter Tyser#define S_FP		44
39884ad6884SPeter Tyser#define S_R10		40
39984ad6884SPeter Tyser#define S_R9		36
40084ad6884SPeter Tyser#define S_R8		32
40184ad6884SPeter Tyser#define S_R7		28
40284ad6884SPeter Tyser#define S_R6		24
40384ad6884SPeter Tyser#define S_R5		20
40484ad6884SPeter Tyser#define S_R4		16
40584ad6884SPeter Tyser#define S_R3		12
40684ad6884SPeter Tyser#define S_R2		8
40784ad6884SPeter Tyser#define S_R1		4
40884ad6884SPeter Tyser#define S_R0		0
40984ad6884SPeter Tyser
41084ad6884SPeter Tyser#define MODE_SVC 0x13
41184ad6884SPeter Tyser
41284ad6884SPeter Tyser	/* use bad_save_user_regs for abort/prefetch/undef/swi ...	    */
41384ad6884SPeter Tyser
41484ad6884SPeter Tyser	.macro	bad_save_user_regs
41584ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
41684ad6884SPeter Tyser	stmia	sp, {r0 - r12}			/* Calling r0-r12	    */
41784ad6884SPeter Tyser	add	r8, sp, #S_PC
41884ad6884SPeter Tyser
4195347f68cSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
42084ad6884SPeter Tyser	ldr	r2, _armboot_start
42184ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
42284ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)	@ set base 2 words into abort stack
4235347f68cSHeiko Schocher#else
4245347f68cSHeiko Schocher	ldr	r2, IRQ_STACK_START_IN
4255347f68cSHeiko Schocher#endif
42684ad6884SPeter Tyser	ldmia	r2, {r2 - r4}			/* get pc, cpsr, old_r0	    */
42784ad6884SPeter Tyser	add	r0, sp, #S_FRAME_SIZE		/* restore sp_SVC	    */
42884ad6884SPeter Tyser
42984ad6884SPeter Tyser	add	r5, sp, #S_SP
43084ad6884SPeter Tyser	mov	r1, lr
43184ad6884SPeter Tyser	stmia	r5, {r0 - r4}			/* save sp_SVC, lr_SVC, pc, cpsr, old_r */
43284ad6884SPeter Tyser	mov	r0, sp
43384ad6884SPeter Tyser	.endm
43484ad6884SPeter Tyser
43584ad6884SPeter Tyser
43684ad6884SPeter Tyser	/* use irq_save_user_regs / irq_restore_user_regs for		     */
43784ad6884SPeter Tyser	/* IRQ/FIQ handling						     */
43884ad6884SPeter Tyser
43984ad6884SPeter Tyser	.macro	irq_save_user_regs
44084ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
44184ad6884SPeter Tyser	stmia	sp, {r0 - r12}			/* Calling r0-r12	     */
44284ad6884SPeter Tyser	add	r8, sp, #S_PC
44384ad6884SPeter Tyser	stmdb	r8, {sp, lr}^			/* Calling SP, LR	     */
44484ad6884SPeter Tyser	str	lr, [r8, #0]			/* Save calling PC	     */
44584ad6884SPeter Tyser	mrs	r6, spsr
44684ad6884SPeter Tyser	str	r6, [r8, #4]			/* Save CPSR		     */
44784ad6884SPeter Tyser	str	r0, [r8, #8]			/* Save OLD_R0		     */
44884ad6884SPeter Tyser	mov	r0, sp
44984ad6884SPeter Tyser	.endm
45084ad6884SPeter Tyser
45184ad6884SPeter Tyser	.macro	irq_restore_user_regs
45284ad6884SPeter Tyser	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
45384ad6884SPeter Tyser	mov	r0, r0
45484ad6884SPeter Tyser	ldr	lr, [sp, #S_PC]			@ Get PC
45584ad6884SPeter Tyser	add	sp, sp, #S_FRAME_SIZE
45684ad6884SPeter Tyser	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
45784ad6884SPeter Tyser	.endm
45884ad6884SPeter Tyser
45984ad6884SPeter Tyser	.macro get_bad_stack
4605347f68cSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
46184ad6884SPeter Tyser	ldr	r13, _armboot_start		@ setup our mode stack
46284ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
46384ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
4645347f68cSHeiko Schocher#else
4655347f68cSHeiko Schocher	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
4665347f68cSHeiko Schocher#endif
46784ad6884SPeter Tyser
46884ad6884SPeter Tyser	str	lr, [r13]			@ save caller lr / spsr
46984ad6884SPeter Tyser	mrs	lr, spsr
47084ad6884SPeter Tyser	str	lr, [r13, #4]
47184ad6884SPeter Tyser
47284ad6884SPeter Tyser	mov	r13, #MODE_SVC			@ prepare SVC-Mode
47384ad6884SPeter Tyser	msr	spsr_c, r13
47484ad6884SPeter Tyser	mov	lr, pc
47584ad6884SPeter Tyser	movs	pc, lr
47684ad6884SPeter Tyser	.endm
47784ad6884SPeter Tyser
47884ad6884SPeter Tyser	.macro get_irq_stack			@ setup IRQ stack
47984ad6884SPeter Tyser	ldr	sp, IRQ_STACK_START
48084ad6884SPeter Tyser	.endm
48184ad6884SPeter Tyser
48284ad6884SPeter Tyser	.macro get_fiq_stack			@ setup FIQ stack
48384ad6884SPeter Tyser	ldr	sp, FIQ_STACK_START
48484ad6884SPeter Tyser	.endm
4855ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
48684ad6884SPeter Tyser
48784ad6884SPeter Tyser
48884ad6884SPeter Tyser/****************************************************************************/
48984ad6884SPeter Tyser/*									    */
49084ad6884SPeter Tyser/* exception handlers							    */
49184ad6884SPeter Tyser/*									    */
49284ad6884SPeter Tyser/****************************************************************************/
49384ad6884SPeter Tyser
4945ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
4955ab877b6SMarek Vasut	.align	5
4965ab877b6SMarek Vasutdo_hang:
4975ab877b6SMarek Vasut	ldr	sp, _TEXT_BASE			/* use 32 words abort stack */
4985ab877b6SMarek Vasut	bl	hang				/* hang and never return */
4995ab877b6SMarek Vasut#else	/* !CONFIG_PRELOADER */
50084ad6884SPeter Tyser	.align	5
50184ad6884SPeter Tyserundefined_instruction:
50284ad6884SPeter Tyser	get_bad_stack
50384ad6884SPeter Tyser	bad_save_user_regs
50484ad6884SPeter Tyser	bl	do_undefined_instruction
50584ad6884SPeter Tyser
50684ad6884SPeter Tyser	.align	5
50784ad6884SPeter Tysersoftware_interrupt:
50884ad6884SPeter Tyser	get_bad_stack
50984ad6884SPeter Tyser	bad_save_user_regs
51084ad6884SPeter Tyser	bl	do_software_interrupt
51184ad6884SPeter Tyser
51284ad6884SPeter Tyser	.align	5
51384ad6884SPeter Tyserprefetch_abort:
51484ad6884SPeter Tyser	get_bad_stack
51584ad6884SPeter Tyser	bad_save_user_regs
51684ad6884SPeter Tyser	bl	do_prefetch_abort
51784ad6884SPeter Tyser
51884ad6884SPeter Tyser	.align	5
51984ad6884SPeter Tyserdata_abort:
52084ad6884SPeter Tyser	get_bad_stack
52184ad6884SPeter Tyser	bad_save_user_regs
52284ad6884SPeter Tyser	bl	do_data_abort
52384ad6884SPeter Tyser
52484ad6884SPeter Tyser	.align	5
52584ad6884SPeter Tysernot_used:
52684ad6884SPeter Tyser	get_bad_stack
52784ad6884SPeter Tyser	bad_save_user_regs
52884ad6884SPeter Tyser	bl	do_not_used
52984ad6884SPeter Tyser
53084ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
53184ad6884SPeter Tyser
53284ad6884SPeter Tyser	.align	5
53384ad6884SPeter Tyserirq:
53484ad6884SPeter Tyser	get_irq_stack
53584ad6884SPeter Tyser	irq_save_user_regs
53684ad6884SPeter Tyser	bl	do_irq
53784ad6884SPeter Tyser	irq_restore_user_regs
53884ad6884SPeter Tyser
53984ad6884SPeter Tyser	.align	5
54084ad6884SPeter Tyserfiq:
54184ad6884SPeter Tyser	get_fiq_stack
54284ad6884SPeter Tyser	irq_save_user_regs		/* someone ought to write a more    */
54384ad6884SPeter Tyser	bl	do_fiq			/* effiction fiq_save_user_regs	    */
54484ad6884SPeter Tyser	irq_restore_user_regs
54584ad6884SPeter Tyser
54684ad6884SPeter Tyser#else /* !CONFIG_USE_IRQ */
54784ad6884SPeter Tyser
54884ad6884SPeter Tyser	.align	5
54984ad6884SPeter Tyserirq:
55084ad6884SPeter Tyser	get_bad_stack
55184ad6884SPeter Tyser	bad_save_user_regs
55284ad6884SPeter Tyser	bl	do_irq
55384ad6884SPeter Tyser
55484ad6884SPeter Tyser	.align	5
55584ad6884SPeter Tyserfiq:
55684ad6884SPeter Tyser	get_bad_stack
55784ad6884SPeter Tyser	bad_save_user_regs
55884ad6884SPeter Tyser	bl	do_fiq
5595ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
56084ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
56184ad6884SPeter Tyser
56284ad6884SPeter Tyser/****************************************************************************/
56384ad6884SPeter Tyser/*									    */
56484ad6884SPeter Tyser/* Reset function: the PXA250 doesn't have a reset function, so we have to  */
56584ad6884SPeter Tyser/* perform a watchdog timeout for a soft reset.				    */
56684ad6884SPeter Tyser/*									    */
56784ad6884SPeter Tyser/****************************************************************************/
5682cad92fdSMarek Vasut/* Operating System Timer */
56984ad6884SPeter Tyser.align	5
57084ad6884SPeter Tyser.globl reset_cpu
57184ad6884SPeter Tyser
57284ad6884SPeter Tyser	/* FIXME: this code is PXA250 specific. How is this handled on	    */
57384ad6884SPeter Tyser	/*	  other XScale processors?				    */
57484ad6884SPeter Tyser
57584ad6884SPeter Tyserreset_cpu:
57684ad6884SPeter Tyser
57784ad6884SPeter Tyser	/* We set OWE:WME (watchdog enable) and wait until timeout happens  */
57884ad6884SPeter Tyser
579*4abf2f7aSMarek Vasut	ldr	r0, =OWER
580*4abf2f7aSMarek Vasut	ldr	r1, [r0]
58184ad6884SPeter Tyser	orr	r1, r1, #0x0001			/* bit0: WME		    */
582*4abf2f7aSMarek Vasut	str	r1, [r0]
58384ad6884SPeter Tyser
58484ad6884SPeter Tyser	/* OS timer does only wrap every 1165 seconds, so we have to set    */
58584ad6884SPeter Tyser	/* the match register as well.					    */
58684ad6884SPeter Tyser
587*4abf2f7aSMarek Vasut	ldr	r0, =OSCR
588*4abf2f7aSMarek Vasut	ldr	r1, [r0]			/* read OS timer	    */
58984ad6884SPeter Tyser	add	r1, r1, #0x800			/* let OSMR3 match after    */
59084ad6884SPeter Tyser	add	r1, r1, #0x800			/* 4096*(1/3.6864MHz)=1ms   */
591*4abf2f7aSMarek Vasut	ldr	r0, =OSMR3
592*4abf2f7aSMarek Vasut	str	r1, [r0]
59384ad6884SPeter Tyser
59484ad6884SPeter Tyserreset_endless:
59584ad6884SPeter Tyser
59684ad6884SPeter Tyser	b	reset_endless
5972cad92fdSMarek Vasut
5982cad92fdSMarek Vasut#ifndef CONFIG_PRELOADER
5992cad92fdSMarek Vasut.section .mmudata, "a"
6002cad92fdSMarek Vasut	.align	14
6012cad92fdSMarek Vasut	.globl	mmu_table
6022cad92fdSMarek Vasutmmu_table:
6032cad92fdSMarek Vasut	/* 0x00000000 - 0xa0000000 : 1:1, uncached mapping */
6042cad92fdSMarek Vasut	.set	__base, 0
6052cad92fdSMarek Vasut	.rept	0xa00
6062cad92fdSMarek Vasut	.word	(__base << 20) | 0xc12
6072cad92fdSMarek Vasut	.set	__base, __base + 1
6082cad92fdSMarek Vasut	.endr
6092cad92fdSMarek Vasut
6102cad92fdSMarek Vasut	/* 0xa0000000 - 0xa0100000 : 1:1, cached mapping */
6112cad92fdSMarek Vasut	.word	(0xa00 << 20) | 0x1c1e
6122cad92fdSMarek Vasut
6132cad92fdSMarek Vasut	.set	__base, 0xa01
6142cad92fdSMarek Vasut	.rept	0x1000 - 0xa01
6152cad92fdSMarek Vasut	.word	(__base << 20) | 0xc12
6162cad92fdSMarek Vasut	.set	__base, __base + 1
6172cad92fdSMarek Vasut	.endr
6182cad92fdSMarek Vasut#endif
619