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