xref: /openbmc/u-boot/arch/arm/cpu/pxa/start.S (revision da90d4ce)
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>
3484ad6884SPeter Tyser
3584ad6884SPeter Tyser.globl _start
3684ad6884SPeter Tyser_start: b	reset
375ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
385ab877b6SMarek Vasut	ldr	pc, _hang
395ab877b6SMarek Vasut	ldr	pc, _hang
405ab877b6SMarek Vasut	ldr	pc, _hang
415ab877b6SMarek Vasut	ldr	pc, _hang
425ab877b6SMarek Vasut	ldr	pc, _hang
435ab877b6SMarek Vasut	ldr	pc, _hang
445ab877b6SMarek Vasut	ldr	pc, _hang
455ab877b6SMarek Vasut
465ab877b6SMarek Vasut_hang:
475ab877b6SMarek Vasut	.word	do_hang
485ab877b6SMarek Vasut	.word	0x12345678
495ab877b6SMarek Vasut	.word	0x12345678
505ab877b6SMarek Vasut	.word	0x12345678
515ab877b6SMarek Vasut	.word	0x12345678
525ab877b6SMarek Vasut	.word	0x12345678
535ab877b6SMarek Vasut	.word	0x12345678
545ab877b6SMarek Vasut	.word	0x12345678	/* now 16*4=64 */
555ab877b6SMarek Vasut#else
5684ad6884SPeter Tyser	ldr	pc, _undefined_instruction
5784ad6884SPeter Tyser	ldr	pc, _software_interrupt
5884ad6884SPeter Tyser	ldr	pc, _prefetch_abort
5984ad6884SPeter Tyser	ldr	pc, _data_abort
6084ad6884SPeter Tyser	ldr	pc, _not_used
6184ad6884SPeter Tyser	ldr	pc, _irq
6284ad6884SPeter Tyser	ldr	pc, _fiq
6384ad6884SPeter Tyser
6484ad6884SPeter Tyser_undefined_instruction: .word undefined_instruction
6584ad6884SPeter Tyser_software_interrupt:	.word software_interrupt
6684ad6884SPeter Tyser_prefetch_abort:	.word prefetch_abort
6784ad6884SPeter Tyser_data_abort:		.word data_abort
6884ad6884SPeter Tyser_not_used:		.word not_used
6984ad6884SPeter Tyser_irq:			.word irq
7084ad6884SPeter Tyser_fiq:			.word fiq
715ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
7284ad6884SPeter Tyser
7384ad6884SPeter Tyser	.balignl 16,0xdeadbeef
7484ad6884SPeter Tyser
7584ad6884SPeter Tyser
7684ad6884SPeter Tyser/*
7784ad6884SPeter Tyser * Startup Code (reset vector)
7884ad6884SPeter Tyser *
7984ad6884SPeter Tyser * do important init only if we don't start from RAM!
8084ad6884SPeter Tyser * - relocate armboot to RAM
8184ad6884SPeter Tyser * - setup stack
8284ad6884SPeter Tyser * - jump to second stage
8384ad6884SPeter Tyser */
8484ad6884SPeter Tyser
855347f68cSHeiko Schocher.globl _TEXT_BASE
8684ad6884SPeter Tyser_TEXT_BASE:
8784ad6884SPeter Tyser	.word	TEXT_BASE
8884ad6884SPeter Tyser
895347f68cSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
9084ad6884SPeter Tyser.globl _armboot_start
9184ad6884SPeter Tyser_armboot_start:
9284ad6884SPeter Tyser	.word _start
935347f68cSHeiko Schocher#endif
9484ad6884SPeter Tyser
9584ad6884SPeter Tyser/*
9684ad6884SPeter Tyser * These are defined in the board-specific linker script.
9784ad6884SPeter Tyser */
9884ad6884SPeter Tyser.globl _bss_start
9984ad6884SPeter Tyser_bss_start:
10084ad6884SPeter Tyser	.word __bss_start
10184ad6884SPeter Tyser
10284ad6884SPeter Tyser.globl _bss_end
10384ad6884SPeter Tyser_bss_end:
10484ad6884SPeter Tyser	.word _end
10584ad6884SPeter Tyser
10684ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
10784ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
10884ad6884SPeter Tyser.globl IRQ_STACK_START
10984ad6884SPeter TyserIRQ_STACK_START:
11084ad6884SPeter Tyser	.word	0x0badc0de
11184ad6884SPeter Tyser
11284ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */
11384ad6884SPeter Tyser.globl FIQ_STACK_START
11484ad6884SPeter TyserFIQ_STACK_START:
11584ad6884SPeter Tyser	.word 0x0badc0de
11684ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
11784ad6884SPeter Tyser
1185347f68cSHeiko Schocher#if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
1195347f68cSHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */
1205347f68cSHeiko Schocher.globl IRQ_STACK_START_IN
1215347f68cSHeiko SchocherIRQ_STACK_START_IN:
1225347f68cSHeiko Schocher	.word	0x0badc0de
1235347f68cSHeiko Schocher
1245347f68cSHeiko Schocher.globl _datarel_start
1255347f68cSHeiko Schocher_datarel_start:
1265347f68cSHeiko Schocher	.word __datarel_start
1275347f68cSHeiko Schocher
1285347f68cSHeiko Schocher.globl _datarelrolocal_start
1295347f68cSHeiko Schocher_datarelrolocal_start:
1305347f68cSHeiko Schocher	.word __datarelrolocal_start
1315347f68cSHeiko Schocher
1325347f68cSHeiko Schocher.globl _datarellocal_start
1335347f68cSHeiko Schocher_datarellocal_start:
1345347f68cSHeiko Schocher	.word __datarellocal_start
1355347f68cSHeiko Schocher
1365347f68cSHeiko Schocher.globl _datarelro_start
1375347f68cSHeiko Schocher_datarelro_start:
1385347f68cSHeiko Schocher	.word __datarelro_start
1395347f68cSHeiko Schocher
1405347f68cSHeiko Schocher.globl _got_start
1415347f68cSHeiko Schocher_got_start:
1425347f68cSHeiko Schocher	.word __got_start
1435347f68cSHeiko Schocher
1445347f68cSHeiko Schocher.globl _got_end
1455347f68cSHeiko Schocher_got_end:
1465347f68cSHeiko Schocher	.word __got_end
1475347f68cSHeiko Schocher
1485347f68cSHeiko Schocher/*
1495347f68cSHeiko Schocher * the actual reset code
1505347f68cSHeiko Schocher */
1515347f68cSHeiko Schocher
1525347f68cSHeiko Schocherreset:
1535347f68cSHeiko Schocher	/*
1545347f68cSHeiko Schocher	 * set the cpu to SVC32 mode
1555347f68cSHeiko Schocher	 */
1565347f68cSHeiko Schocher	mrs	r0,cpsr
1575347f68cSHeiko Schocher	bic	r0,r0,#0x1f
1585347f68cSHeiko Schocher	orr	r0,r0,#0xd3
1595347f68cSHeiko Schocher	msr	cpsr,r0
1605347f68cSHeiko Schocher
1615347f68cSHeiko Schocher	/*
1625347f68cSHeiko Schocher	 * we do sys-critical inits only at reboot,
1635347f68cSHeiko Schocher	 * not when booting from ram!
1645347f68cSHeiko Schocher	 */
1655347f68cSHeiko Schocher#ifndef CONFIG_SKIP_LOWLEVEL_INIT
1665347f68cSHeiko Schocher	bl	cpu_init_crit
1675347f68cSHeiko Schocher#endif
1685347f68cSHeiko Schocher
1695347f68cSHeiko Schocher/* Set stackpointer in internal RAM to call board_init_f */
1705347f68cSHeiko Schochercall_board_init_f:
1715347f68cSHeiko Schocher	ldr	sp, =(CONFIG_SYS_INIT_SP_ADDR)
1725347f68cSHeiko Schocher	ldr	r0,=0x00000000
1735347f68cSHeiko Schocher	bl	board_init_f
1745347f68cSHeiko Schocher
1755347f68cSHeiko Schocher/*------------------------------------------------------------------------------*/
1765347f68cSHeiko Schocher
1775347f68cSHeiko Schocher/*
1785347f68cSHeiko Schocher * void relocate_code (addr_sp, gd, addr_moni)
1795347f68cSHeiko Schocher *
1805347f68cSHeiko Schocher * This "function" does not return, instead it continues in RAM
1815347f68cSHeiko Schocher * after relocating the monitor code.
1825347f68cSHeiko Schocher *
1835347f68cSHeiko Schocher */
1845347f68cSHeiko Schocher	.globl	relocate_code
1855347f68cSHeiko Schocherrelocate_code:
1865347f68cSHeiko Schocher	mov	r4, r0	/* save addr_sp */
1875347f68cSHeiko Schocher	mov	r5, r1	/* save addr of gd */
1885347f68cSHeiko Schocher	mov	r6, r2	/* save addr of destination */
1895347f68cSHeiko Schocher	mov	r7, r2	/* save addr of destination */
1905347f68cSHeiko Schocher
1915347f68cSHeiko Schocher	/* Set up the stack						    */
1925347f68cSHeiko Schocherstack_setup:
1935347f68cSHeiko Schocher	mov	sp, r4
1945347f68cSHeiko Schocher
1955347f68cSHeiko Schocher	adr	r0, _start
1965347f68cSHeiko Schocher	ldr	r2, _TEXT_BASE
1975347f68cSHeiko Schocher	ldr	r3, _bss_start
1985347f68cSHeiko Schocher	sub	r2, r3, r2		/* r2 <- size of armboot	    */
1995347f68cSHeiko Schocher	add	r2, r0, r2		/* r2 <- source end address	    */
2005347f68cSHeiko Schocher	cmp	r0, r6
2015347f68cSHeiko Schocher	beq	clear_bss
2025347f68cSHeiko Schocher
2035347f68cSHeiko Schocher#ifndef CONFIG_SKIP_RELOCATE_UBOOT
2045347f68cSHeiko Schochercopy_loop:
2055347f68cSHeiko Schocher	ldmia	r0!, {r9-r10}		/* copy from source address [r0]    */
2065347f68cSHeiko Schocher	stmia	r6!, {r9-r10}		/* copy to   target address [r1]    */
207*da90d4ceSAlbert Aribaud	cmp	r0, r2			/* until source end address [r2]    */
208*da90d4ceSAlbert Aribaud	blo	copy_loop
2095347f68cSHeiko Schocher
2105347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
2115347f68cSHeiko Schocher	/* fix got entries */
2125347f68cSHeiko Schocher	ldr	r1, _TEXT_BASE		/* Text base */
2135347f68cSHeiko Schocher	mov	r0, r7			/* reloc addr */
2145347f68cSHeiko Schocher	ldr	r2, _got_start		/* addr in Flash */
2155347f68cSHeiko Schocher	ldr	r3, _got_end		/* addr in Flash */
2165347f68cSHeiko Schocher	sub	r3, r3, r1
2175347f68cSHeiko Schocher	add	r3, r3, r0
2185347f68cSHeiko Schocher	sub	r2, r2, r1
2195347f68cSHeiko Schocher	add	r2, r2, r0
2205347f68cSHeiko Schocher
2215347f68cSHeiko Schocherfixloop:
2225347f68cSHeiko Schocher	ldr	r4, [r2]
2235347f68cSHeiko Schocher	sub	r4, r4, r1
2245347f68cSHeiko Schocher	add	r4, r4, r0
2255347f68cSHeiko Schocher	str	r4, [r2]
2265347f68cSHeiko Schocher	add	r2, r2, #4
2275347f68cSHeiko Schocher	cmp	r2, r3
2285347f68cSHeiko Schocher	bne	fixloop
2295347f68cSHeiko Schocher#endif
2305347f68cSHeiko Schocher#endif	/* #ifndef CONFIG_SKIP_RELOCATE_UBOOT */
2315347f68cSHeiko Schocher
2325347f68cSHeiko Schocherclear_bss:
2335347f68cSHeiko Schocher#ifndef CONFIG_PRELOADER
2345347f68cSHeiko Schocher	ldr	r0, _bss_start
2355347f68cSHeiko Schocher	ldr	r1, _bss_end
2365347f68cSHeiko Schocher	ldr	r3, _TEXT_BASE		/* Text base */
2375347f68cSHeiko Schocher	mov	r4, r7			/* reloc addr */
2385347f68cSHeiko Schocher	sub	r0, r0, r3
2395347f68cSHeiko Schocher	add	r0, r0, r4
2405347f68cSHeiko Schocher	sub	r1, r1, r3
2415347f68cSHeiko Schocher	add	r1, r1, r4
2425347f68cSHeiko Schocher	mov	r2, #0x00000000		/* clear			    */
2435347f68cSHeiko Schocher
2445347f68cSHeiko Schocherclbss_l:str	r2, [r0]		/* clear loop...		    */
2455347f68cSHeiko Schocher	add	r0, r0, #4
2465347f68cSHeiko Schocher	cmp	r0, r1
2475347f68cSHeiko Schocher	bne	clbss_l
2485347f68cSHeiko Schocher#endif
2495347f68cSHeiko Schocher
2505347f68cSHeiko Schocher/*
2515347f68cSHeiko Schocher * We are done. Do not return, instead branch to second part of board
2525347f68cSHeiko Schocher * initialization, now running from RAM.
2535347f68cSHeiko Schocher */
2545347f68cSHeiko Schocher#ifdef CONFIG_ONENAND_IPL
2555347f68cSHeiko Schocher	ldr     pc, _start_oneboot
2565347f68cSHeiko Schocher
2575347f68cSHeiko Schocher_start_oneboot: .word start_oneboot
2585347f68cSHeiko Schocher#else
2595347f68cSHeiko Schocher	ldr	r0, _TEXT_BASE
2605347f68cSHeiko Schocher	ldr	r2, _board_init_r
2615347f68cSHeiko Schocher	sub	r2, r2, r0
2625347f68cSHeiko Schocher	add	r2, r2, r7	/* position from board_init_r in RAM */
2635347f68cSHeiko Schocher	/* setup parameters for board_init_r */
2645347f68cSHeiko Schocher	mov	r0, r5		/* gd_t */
2655347f68cSHeiko Schocher	mov	r1, r7		/* dest_addr */
2665347f68cSHeiko Schocher	/* jump to it ... */
2675347f68cSHeiko Schocher	mov	lr, r2
2685347f68cSHeiko Schocher	mov	pc, lr
2695347f68cSHeiko Schocher
2705347f68cSHeiko Schocher_board_init_r: .word board_init_r
2715347f68cSHeiko Schocher#endif
2725347f68cSHeiko Schocher
2735347f68cSHeiko Schocher#else /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
27484ad6884SPeter Tyser
27584ad6884SPeter Tyser/****************************************************************************/
27684ad6884SPeter Tyser/*									    */
27784ad6884SPeter Tyser/* the actual reset code						    */
27884ad6884SPeter Tyser/*									    */
27984ad6884SPeter Tyser/****************************************************************************/
28084ad6884SPeter Tyser
28184ad6884SPeter Tyserreset:
28284ad6884SPeter Tyser	mrs	r0,cpsr			/* set the CPU to SVC32 mode	    */
28384ad6884SPeter Tyser	bic	r0,r0,#0x1f		/* (superviser mode, M=10011)	    */
28484ad6884SPeter Tyser	orr	r0,r0,#0x13
28584ad6884SPeter Tyser	msr	cpsr,r0
28684ad6884SPeter Tyser
28784ad6884SPeter Tyser	/*
28884ad6884SPeter Tyser	 * we do sys-critical inits only at reboot,
28984ad6884SPeter Tyser	 * not when booting from RAM!
29084ad6884SPeter Tyser	 */
29184ad6884SPeter Tyser#ifndef CONFIG_SKIP_LOWLEVEL_INIT
29284ad6884SPeter Tyser	bl	cpu_init_crit		/* we do sys-critical inits	    */
29384ad6884SPeter Tyser#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */
29484ad6884SPeter Tyser
29584ad6884SPeter Tyser#ifndef CONFIG_SKIP_RELOCATE_UBOOT
29684ad6884SPeter Tyserrelocate:				/* relocate U-Boot to RAM	    */
29784ad6884SPeter Tyser	adr	r0, _start		/* r0 <- current position of code   */
29884ad6884SPeter Tyser	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
2995ab877b6SMarek Vasut#ifndef	CONFIG_PRELOADER
30084ad6884SPeter Tyser	cmp	r0, r1			/* don't reloc during debug	    */
30184ad6884SPeter Tyser	beq	stack_setup
3025ab877b6SMarek Vasut#endif
30384ad6884SPeter Tyser
30484ad6884SPeter Tyser	ldr	r2, _armboot_start
30584ad6884SPeter Tyser	ldr	r3, _bss_start
30684ad6884SPeter Tyser	sub	r2, r3, r2		/* r2 <- size of armboot	    */
30784ad6884SPeter Tyser	add	r2, r0, r2		/* r2 <- source end address	    */
30884ad6884SPeter Tyser
30984ad6884SPeter Tysercopy_loop:
31084ad6884SPeter Tyser	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
31184ad6884SPeter Tyser	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
31284ad6884SPeter Tyser	cmp	r0, r2			/* until source end address [r2]    */
313*da90d4ceSAlbert Aribaud	blo	copy_loop
31484ad6884SPeter Tyser#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */
31584ad6884SPeter Tyser
31684ad6884SPeter Tyser	/* Set up the stack						    */
31784ad6884SPeter Tyserstack_setup:
31884ad6884SPeter Tyser	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
3195ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
3205ab877b6SMarek Vasut	sub	sp, r0, #128		/* leave 32 words for abort-stack   */
3215ab877b6SMarek Vasut#else
32284ad6884SPeter Tyser	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area		    */
32384ad6884SPeter Tyser	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo		    */
32484ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
32584ad6884SPeter Tyser	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
32684ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
3271a27f7d9SVitaly Kuzmichev	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
3281a27f7d9SVitaly Kuzmichev	bic	sp, sp, #7		/* 8-byte alignment for ABI compliance */
3295ab877b6SMarek Vasut#endif
33084ad6884SPeter Tyser
33184ad6884SPeter Tyserclear_bss:
33284ad6884SPeter Tyser	ldr	r0, _bss_start		/* find start of bss segment	    */
33384ad6884SPeter Tyser	ldr	r1, _bss_end		/* stop here			    */
33484ad6884SPeter Tyser	mov	r2, #0x00000000		/* clear			    */
33584ad6884SPeter Tyser
3365ab877b6SMarek Vasut#ifndef CONFIG_PRELOADER
33784ad6884SPeter Tyserclbss_l:str	r2, [r0]		/* clear loop...		    */
33884ad6884SPeter Tyser	add	r0, r0, #4
33984ad6884SPeter Tyser	cmp	r0, r1
340*da90d4ceSAlbert Aribaud	blo	clbss_l
3415ab877b6SMarek Vasut#endif
34284ad6884SPeter Tyser
34384ad6884SPeter Tyser	ldr	pc, _start_armboot
34484ad6884SPeter Tyser
3455ab877b6SMarek Vasut#ifdef CONFIG_ONENAND_IPL
3465ab877b6SMarek Vasut_start_armboot: .word start_oneboot
3475ab877b6SMarek Vasut#else
34884ad6884SPeter Tyser_start_armboot: .word start_armboot
3495ab877b6SMarek Vasut#endif
3505347f68cSHeiko Schocher#endif /* #if !defined(CONFIG_SYS_ARM_WITHOUT_RELOC) */
35184ad6884SPeter Tyser
35284ad6884SPeter Tyser/****************************************************************************/
35384ad6884SPeter Tyser/*									    */
35484ad6884SPeter Tyser/* CPU_init_critical registers						    */
35584ad6884SPeter Tyser/*									    */
35684ad6884SPeter Tyser/* - setup important registers						    */
35784ad6884SPeter Tyser/* - setup memory timing						    */
35884ad6884SPeter Tyser/*									    */
35984ad6884SPeter Tyser/****************************************************************************/
36084ad6884SPeter Tyser/* mk@tbd: Fix this! */
36184ad6884SPeter Tyser#undef RCSR
36284ad6884SPeter Tyser#undef ICMR
36384ad6884SPeter Tyser#undef OSMR3
36484ad6884SPeter Tyser#undef OSCR
36584ad6884SPeter Tyser#undef OWER
36684ad6884SPeter Tyser#undef OIER
36784ad6884SPeter Tyser#undef CCCR
36884ad6884SPeter Tyser
36984ad6884SPeter Tyser/* Interrupt-Controller base address					    */
37084ad6884SPeter TyserIC_BASE:	   .word	   0x40d00000
37184ad6884SPeter Tyser#define ICMR	0x04
37284ad6884SPeter Tyser
37384ad6884SPeter Tyser/* Reset-Controller */
37484ad6884SPeter TyserRST_BASE:	.word	0x40f00030
37584ad6884SPeter Tyser#define RCSR	0x00
37684ad6884SPeter Tyser
37784ad6884SPeter Tyser/* Operating System Timer */
37884ad6884SPeter TyserOSTIMER_BASE:	.word	0x40a00000
37984ad6884SPeter Tyser#define OSMR3	0x0C
38084ad6884SPeter Tyser#define OSCR	0x10
38184ad6884SPeter Tyser#define OWER	0x18
38284ad6884SPeter Tyser#define OIER	0x1C
38384ad6884SPeter Tyser
38484ad6884SPeter Tyser/* Clock Manager Registers						    */
38584ad6884SPeter Tyser#ifdef CONFIG_CPU_MONAHANS
38684ad6884SPeter Tyser# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO
38784ad6884SPeter Tyser#  error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!"
38884ad6884SPeter Tyser# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */
38984ad6884SPeter Tyser# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO
39084ad6884SPeter Tyser#  define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1
39184ad6884SPeter Tyser# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */
39284ad6884SPeter Tyser#else /* !CONFIG_CPU_MONAHANS */
39384ad6884SPeter Tyser#ifdef CONFIG_SYS_CPUSPEED
39484ad6884SPeter TyserCC_BASE:	.word	0x41300000
39584ad6884SPeter Tyser#define CCCR	0x00
39684ad6884SPeter Tysercpuspeed:	.word	CONFIG_SYS_CPUSPEED
39784ad6884SPeter Tyser#else /* !CONFIG_SYS_CPUSPEED */
39884ad6884SPeter Tyser#error "You have to define CONFIG_SYS_CPUSPEED!!"
39984ad6884SPeter Tyser#endif /* CONFIG_SYS_CPUSPEED */
40084ad6884SPeter Tyser#endif /* CONFIG_CPU_MONAHANS */
40184ad6884SPeter Tyser
40284ad6884SPeter Tyser	/* takes care the CP15 update has taken place */
40384ad6884SPeter Tyser	.macro CPWAIT reg
40484ad6884SPeter Tyser	mrc  p15,0,\reg,c2,c0,0
40584ad6884SPeter Tyser	mov  \reg,\reg
40684ad6884SPeter Tyser	sub  pc,pc,#4
40784ad6884SPeter Tyser	.endm
40884ad6884SPeter Tyser
40984ad6884SPeter Tysercpu_init_crit:
41084ad6884SPeter Tyser
41184ad6884SPeter Tyser	/* mask all IRQs						    */
41284ad6884SPeter Tyser#ifndef CONFIG_CPU_MONAHANS
41384ad6884SPeter Tyser	ldr	r0, IC_BASE
41484ad6884SPeter Tyser	mov	r1, #0x00
41584ad6884SPeter Tyser	str	r1, [r0, #ICMR]
41684ad6884SPeter Tyser#else /* CONFIG_CPU_MONAHANS */
41784ad6884SPeter Tyser	/* Step 1 - Enable CP6 permission */
41884ad6884SPeter Tyser	mrc	p15, 0, r1, c15, c1, 0	@ read CPAR
41984ad6884SPeter Tyser	orr	r1, r1, #0x40
42084ad6884SPeter Tyser		mcr	p15, 0, r1, c15, c1, 0
42184ad6884SPeter Tyser	CPWAIT	r1
42284ad6884SPeter Tyser
42384ad6884SPeter Tyser	/* Step 2 - Mask ICMR & ICMR2 */
42484ad6884SPeter Tyser	mov	r1, #0
42584ad6884SPeter Tyser	mcr	p6, 0, r1, c1, c0, 0	@ ICMR
42684ad6884SPeter Tyser	mcr	p6, 0, r1, c7, c0, 0	@ ICMR2
42784ad6884SPeter Tyser
42884ad6884SPeter Tyser	/* turn off all clocks but the ones we will definitly require */
42984ad6884SPeter Tyser	ldr	r1, =CKENA
43084ad6884SPeter Tyser	ldr	r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC)
43184ad6884SPeter Tyser	str	r2, [r1]
43284ad6884SPeter Tyser	ldr	r1, =CKENB
43384ad6884SPeter Tyser	ldr	r2, =(CKENB_6_IRQ)
43484ad6884SPeter Tyser	str	r2, [r1]
43584ad6884SPeter Tyser#endif /* !CONFIG_CPU_MONAHANS */
43684ad6884SPeter Tyser
43784ad6884SPeter Tyser	/* set clock speed */
43884ad6884SPeter Tyser#ifdef CONFIG_CPU_MONAHANS
43984ad6884SPeter Tyser	ldr	r0, =ACCR
44084ad6884SPeter Tyser	ldr	r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK))
44184ad6884SPeter Tyser	str	r1, [r0]
44284ad6884SPeter Tyser#else /* !CONFIG_CPU_MONAHANS */
44384ad6884SPeter Tyser#ifdef CONFIG_SYS_CPUSPEED
44484ad6884SPeter Tyser	ldr	r0, CC_BASE
44584ad6884SPeter Tyser	ldr	r1, cpuspeed
44684ad6884SPeter Tyser	str	r1, [r0, #CCCR]
44784ad6884SPeter Tyser	mov	r0, #2
44884ad6884SPeter Tyser	mcr	p14, 0, r0, c6, c0, 0
44984ad6884SPeter Tyser
45084ad6884SPeter Tysersetspeed_done:
45184ad6884SPeter Tyser
45284ad6884SPeter Tyser#endif /* CONFIG_SYS_CPUSPEED */
45384ad6884SPeter Tyser#endif /* CONFIG_CPU_MONAHANS */
45484ad6884SPeter Tyser
45584ad6884SPeter Tyser	/*
45684ad6884SPeter Tyser	 * before relocating, we have to setup RAM timing
45784ad6884SPeter Tyser	 * because memory timing is board-dependend, you will
45884ad6884SPeter Tyser	 * find a lowlevel_init.S in your board directory.
45984ad6884SPeter Tyser	 */
46084ad6884SPeter Tyser	mov	ip,	lr
46184ad6884SPeter Tyser	bl	lowlevel_init
46284ad6884SPeter Tyser	mov	lr,	ip
46384ad6884SPeter Tyser
46484ad6884SPeter Tyser	/* Memory interfaces are working. Disable MMU and enable I-cache.   */
46584ad6884SPeter Tyser	/* mk: hmm, this is not in the monahans docs, leave it now but
46684ad6884SPeter Tyser	 *     check here if it doesn't work :-) */
46784ad6884SPeter Tyser
46884ad6884SPeter Tyser	ldr	r0, =0x2001		/* enable access to all coproc.	    */
46984ad6884SPeter Tyser	mcr	p15, 0, r0, c15, c1, 0
47084ad6884SPeter Tyser	CPWAIT r0
47184ad6884SPeter Tyser
47284ad6884SPeter Tyser	mcr	p15, 0, r0, c7, c10, 4	/* drain the write & fill buffers   */
47384ad6884SPeter Tyser	CPWAIT r0
47484ad6884SPeter Tyser
47584ad6884SPeter Tyser	mcr	p15, 0, r0, c7, c7, 0	/* flush Icache, Dcache and BTB	    */
47684ad6884SPeter Tyser	CPWAIT r0
47784ad6884SPeter Tyser
47884ad6884SPeter Tyser	mcr	p15, 0, r0, c8, c7, 0	/* flush instuction and data TLBs   */
47984ad6884SPeter Tyser	CPWAIT r0
48084ad6884SPeter Tyser
48184ad6884SPeter Tyser	/* Enable the Icache						    */
48284ad6884SPeter Tyser/*
48384ad6884SPeter Tyser	mrc	p15, 0, r0, c1, c0, 0
48484ad6884SPeter Tyser	orr	r0, r0, #0x1800
48584ad6884SPeter Tyser	mcr	p15, 0, r0, c1, c0, 0
48684ad6884SPeter Tyser	CPWAIT
48784ad6884SPeter Tyser*/
48884ad6884SPeter Tyser	mov	pc, lr
48984ad6884SPeter Tyser
4905ab877b6SMarek Vasut#ifndef CONFIG_PRELOADER
49184ad6884SPeter Tyser/****************************************************************************/
49284ad6884SPeter Tyser/*									    */
49384ad6884SPeter Tyser/* Interrupt handling							    */
49484ad6884SPeter Tyser/*									    */
49584ad6884SPeter Tyser/****************************************************************************/
49684ad6884SPeter Tyser
49784ad6884SPeter Tyser/* IRQ stack frame							    */
49884ad6884SPeter Tyser
49984ad6884SPeter Tyser#define S_FRAME_SIZE	72
50084ad6884SPeter Tyser
50184ad6884SPeter Tyser#define S_OLD_R0	68
50284ad6884SPeter Tyser#define S_PSR		64
50384ad6884SPeter Tyser#define S_PC		60
50484ad6884SPeter Tyser#define S_LR		56
50584ad6884SPeter Tyser#define S_SP		52
50684ad6884SPeter Tyser
50784ad6884SPeter Tyser#define S_IP		48
50884ad6884SPeter Tyser#define S_FP		44
50984ad6884SPeter Tyser#define S_R10		40
51084ad6884SPeter Tyser#define S_R9		36
51184ad6884SPeter Tyser#define S_R8		32
51284ad6884SPeter Tyser#define S_R7		28
51384ad6884SPeter Tyser#define S_R6		24
51484ad6884SPeter Tyser#define S_R5		20
51584ad6884SPeter Tyser#define S_R4		16
51684ad6884SPeter Tyser#define S_R3		12
51784ad6884SPeter Tyser#define S_R2		8
51884ad6884SPeter Tyser#define S_R1		4
51984ad6884SPeter Tyser#define S_R0		0
52084ad6884SPeter Tyser
52184ad6884SPeter Tyser#define MODE_SVC 0x13
52284ad6884SPeter Tyser
52384ad6884SPeter Tyser	/* use bad_save_user_regs for abort/prefetch/undef/swi ...	    */
52484ad6884SPeter Tyser
52584ad6884SPeter Tyser	.macro	bad_save_user_regs
52684ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
52784ad6884SPeter Tyser	stmia	sp, {r0 - r12}			/* Calling r0-r12	    */
52884ad6884SPeter Tyser	add	r8, sp, #S_PC
52984ad6884SPeter Tyser
5305347f68cSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
53184ad6884SPeter Tyser	ldr	r2, _armboot_start
53284ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
53384ad6884SPeter Tyser	sub	r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8)	@ set base 2 words into abort stack
5345347f68cSHeiko Schocher#else
5355347f68cSHeiko Schocher	ldr	r2, IRQ_STACK_START_IN
5365347f68cSHeiko Schocher#endif
53784ad6884SPeter Tyser	ldmia	r2, {r2 - r4}			/* get pc, cpsr, old_r0	    */
53884ad6884SPeter Tyser	add	r0, sp, #S_FRAME_SIZE		/* restore sp_SVC	    */
53984ad6884SPeter Tyser
54084ad6884SPeter Tyser	add	r5, sp, #S_SP
54184ad6884SPeter Tyser	mov	r1, lr
54284ad6884SPeter Tyser	stmia	r5, {r0 - r4}			/* save sp_SVC, lr_SVC, pc, cpsr, old_r */
54384ad6884SPeter Tyser	mov	r0, sp
54484ad6884SPeter Tyser	.endm
54584ad6884SPeter Tyser
54684ad6884SPeter Tyser
54784ad6884SPeter Tyser	/* use irq_save_user_regs / irq_restore_user_regs for		     */
54884ad6884SPeter Tyser	/* IRQ/FIQ handling						     */
54984ad6884SPeter Tyser
55084ad6884SPeter Tyser	.macro	irq_save_user_regs
55184ad6884SPeter Tyser	sub	sp, sp, #S_FRAME_SIZE
55284ad6884SPeter Tyser	stmia	sp, {r0 - r12}			/* Calling r0-r12	     */
55384ad6884SPeter Tyser	add	r8, sp, #S_PC
55484ad6884SPeter Tyser	stmdb	r8, {sp, lr}^			/* Calling SP, LR	     */
55584ad6884SPeter Tyser	str	lr, [r8, #0]			/* Save calling PC	     */
55684ad6884SPeter Tyser	mrs	r6, spsr
55784ad6884SPeter Tyser	str	r6, [r8, #4]			/* Save CPSR		     */
55884ad6884SPeter Tyser	str	r0, [r8, #8]			/* Save OLD_R0		     */
55984ad6884SPeter Tyser	mov	r0, sp
56084ad6884SPeter Tyser	.endm
56184ad6884SPeter Tyser
56284ad6884SPeter Tyser	.macro	irq_restore_user_regs
56384ad6884SPeter Tyser	ldmia	sp, {r0 - lr}^			@ Calling r0 - lr
56484ad6884SPeter Tyser	mov	r0, r0
56584ad6884SPeter Tyser	ldr	lr, [sp, #S_PC]			@ Get PC
56684ad6884SPeter Tyser	add	sp, sp, #S_FRAME_SIZE
56784ad6884SPeter Tyser	subs	pc, lr, #4			@ return & move spsr_svc into cpsr
56884ad6884SPeter Tyser	.endm
56984ad6884SPeter Tyser
57084ad6884SPeter Tyser	.macro get_bad_stack
5715347f68cSHeiko Schocher#if defined(CONFIG_SYS_ARM_WITHOUT_RELOC)
57284ad6884SPeter Tyser	ldr	r13, _armboot_start		@ setup our mode stack
57384ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN)
57484ad6884SPeter Tyser	sub	r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack
5755347f68cSHeiko Schocher#else
5765347f68cSHeiko Schocher	ldr	r13, IRQ_STACK_START_IN		@ setup our mode stack
5775347f68cSHeiko Schocher#endif
57884ad6884SPeter Tyser
57984ad6884SPeter Tyser	str	lr, [r13]			@ save caller lr / spsr
58084ad6884SPeter Tyser	mrs	lr, spsr
58184ad6884SPeter Tyser	str	lr, [r13, #4]
58284ad6884SPeter Tyser
58384ad6884SPeter Tyser	mov	r13, #MODE_SVC			@ prepare SVC-Mode
58484ad6884SPeter Tyser	msr	spsr_c, r13
58584ad6884SPeter Tyser	mov	lr, pc
58684ad6884SPeter Tyser	movs	pc, lr
58784ad6884SPeter Tyser	.endm
58884ad6884SPeter Tyser
58984ad6884SPeter Tyser	.macro get_irq_stack			@ setup IRQ stack
59084ad6884SPeter Tyser	ldr	sp, IRQ_STACK_START
59184ad6884SPeter Tyser	.endm
59284ad6884SPeter Tyser
59384ad6884SPeter Tyser	.macro get_fiq_stack			@ setup FIQ stack
59484ad6884SPeter Tyser	ldr	sp, FIQ_STACK_START
59584ad6884SPeter Tyser	.endm
5965ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
59784ad6884SPeter Tyser
59884ad6884SPeter Tyser
59984ad6884SPeter Tyser/****************************************************************************/
60084ad6884SPeter Tyser/*									    */
60184ad6884SPeter Tyser/* exception handlers							    */
60284ad6884SPeter Tyser/*									    */
60384ad6884SPeter Tyser/****************************************************************************/
60484ad6884SPeter Tyser
6055ab877b6SMarek Vasut#ifdef CONFIG_PRELOADER
6065ab877b6SMarek Vasut	.align	5
6075ab877b6SMarek Vasutdo_hang:
6085ab877b6SMarek Vasut	ldr	sp, _TEXT_BASE			/* use 32 words abort stack */
6095ab877b6SMarek Vasut	bl	hang				/* hang and never return */
6105ab877b6SMarek Vasut#else	/* !CONFIG_PRELOADER */
61184ad6884SPeter Tyser	.align	5
61284ad6884SPeter Tyserundefined_instruction:
61384ad6884SPeter Tyser	get_bad_stack
61484ad6884SPeter Tyser	bad_save_user_regs
61584ad6884SPeter Tyser	bl	do_undefined_instruction
61684ad6884SPeter Tyser
61784ad6884SPeter Tyser	.align	5
61884ad6884SPeter Tysersoftware_interrupt:
61984ad6884SPeter Tyser	get_bad_stack
62084ad6884SPeter Tyser	bad_save_user_regs
62184ad6884SPeter Tyser	bl	do_software_interrupt
62284ad6884SPeter Tyser
62384ad6884SPeter Tyser	.align	5
62484ad6884SPeter Tyserprefetch_abort:
62584ad6884SPeter Tyser	get_bad_stack
62684ad6884SPeter Tyser	bad_save_user_regs
62784ad6884SPeter Tyser	bl	do_prefetch_abort
62884ad6884SPeter Tyser
62984ad6884SPeter Tyser	.align	5
63084ad6884SPeter Tyserdata_abort:
63184ad6884SPeter Tyser	get_bad_stack
63284ad6884SPeter Tyser	bad_save_user_regs
63384ad6884SPeter Tyser	bl	do_data_abort
63484ad6884SPeter Tyser
63584ad6884SPeter Tyser	.align	5
63684ad6884SPeter Tysernot_used:
63784ad6884SPeter Tyser	get_bad_stack
63884ad6884SPeter Tyser	bad_save_user_regs
63984ad6884SPeter Tyser	bl	do_not_used
64084ad6884SPeter Tyser
64184ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ
64284ad6884SPeter Tyser
64384ad6884SPeter Tyser	.align	5
64484ad6884SPeter Tyserirq:
64584ad6884SPeter Tyser	get_irq_stack
64684ad6884SPeter Tyser	irq_save_user_regs
64784ad6884SPeter Tyser	bl	do_irq
64884ad6884SPeter Tyser	irq_restore_user_regs
64984ad6884SPeter Tyser
65084ad6884SPeter Tyser	.align	5
65184ad6884SPeter Tyserfiq:
65284ad6884SPeter Tyser	get_fiq_stack
65384ad6884SPeter Tyser	irq_save_user_regs		/* someone ought to write a more    */
65484ad6884SPeter Tyser	bl	do_fiq			/* effiction fiq_save_user_regs	    */
65584ad6884SPeter Tyser	irq_restore_user_regs
65684ad6884SPeter Tyser
65784ad6884SPeter Tyser#else /* !CONFIG_USE_IRQ */
65884ad6884SPeter Tyser
65984ad6884SPeter Tyser	.align	5
66084ad6884SPeter Tyserirq:
66184ad6884SPeter Tyser	get_bad_stack
66284ad6884SPeter Tyser	bad_save_user_regs
66384ad6884SPeter Tyser	bl	do_irq
66484ad6884SPeter Tyser
66584ad6884SPeter Tyser	.align	5
66684ad6884SPeter Tyserfiq:
66784ad6884SPeter Tyser	get_bad_stack
66884ad6884SPeter Tyser	bad_save_user_regs
66984ad6884SPeter Tyser	bl	do_fiq
6705ab877b6SMarek Vasut#endif	/* CONFIG_PRELOADER */
67184ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */
67284ad6884SPeter Tyser
67384ad6884SPeter Tyser/****************************************************************************/
67484ad6884SPeter Tyser/*									    */
67584ad6884SPeter Tyser/* Reset function: the PXA250 doesn't have a reset function, so we have to  */
67684ad6884SPeter Tyser/* perform a watchdog timeout for a soft reset.				    */
67784ad6884SPeter Tyser/*									    */
67884ad6884SPeter Tyser/****************************************************************************/
67984ad6884SPeter Tyser
68084ad6884SPeter Tyser	.align	5
68184ad6884SPeter Tyser.globl reset_cpu
68284ad6884SPeter Tyser
68384ad6884SPeter Tyser	/* FIXME: this code is PXA250 specific. How is this handled on	    */
68484ad6884SPeter Tyser	/*	  other XScale processors?				    */
68584ad6884SPeter Tyser
68684ad6884SPeter Tyserreset_cpu:
68784ad6884SPeter Tyser
68884ad6884SPeter Tyser	/* We set OWE:WME (watchdog enable) and wait until timeout happens  */
68984ad6884SPeter Tyser
69084ad6884SPeter Tyser	ldr	r0, OSTIMER_BASE
69184ad6884SPeter Tyser	ldr	r1, [r0, #OWER]
69284ad6884SPeter Tyser	orr	r1, r1, #0x0001			/* bit0: WME		    */
69384ad6884SPeter Tyser	str	r1, [r0, #OWER]
69484ad6884SPeter Tyser
69584ad6884SPeter Tyser	/* OS timer does only wrap every 1165 seconds, so we have to set    */
69684ad6884SPeter Tyser	/* the match register as well.					    */
69784ad6884SPeter Tyser
69884ad6884SPeter Tyser	ldr	r1, [r0, #OSCR]			/* read OS timer	    */
69984ad6884SPeter Tyser	add	r1, r1, #0x800			/* let OSMR3 match after    */
70084ad6884SPeter Tyser	add	r1, r1, #0x800			/* 4096*(1/3.6864MHz)=1ms   */
70184ad6884SPeter Tyser	str	r1, [r0, #OSMR3]
70284ad6884SPeter Tyser
70384ad6884SPeter Tyserreset_endless:
70484ad6884SPeter Tyser
70584ad6884SPeter Tyser	b	reset_endless
706