184ad6884SPeter Tyser/* 284ad6884SPeter Tyser * armboot - Startup Code for SA1100 CPU 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> 7*fa82f871SAlbert ARIBAUD * Copyright (c) 2001 Alex Züpke <azu@sysgo.de> 884ad6884SPeter Tyser * 984ad6884SPeter Tyser * See file CREDITS for list of people who contributed to this 1084ad6884SPeter Tyser * project. 1184ad6884SPeter Tyser * 1284ad6884SPeter Tyser * This program is free software; you can redistribute it and/or 1384ad6884SPeter Tyser * modify it under the terms of the GNU General Public License as 1484ad6884SPeter Tyser * published by the Free Software Foundation; either version 2 of 1584ad6884SPeter Tyser * the License, or (at your option) any later version. 1684ad6884SPeter Tyser * 1784ad6884SPeter Tyser * This program is distributed in the hope that it will be useful, 1884ad6884SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 1984ad6884SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 2084ad6884SPeter Tyser * GNU General Public License for more details. 2184ad6884SPeter Tyser * 2284ad6884SPeter Tyser * You should have received a copy of the GNU General Public License 2384ad6884SPeter Tyser * along with this program; if not, write to the Free Software 2484ad6884SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 2584ad6884SPeter Tyser * MA 02111-1307 USA 2684ad6884SPeter Tyser */ 2784ad6884SPeter Tyser 2825ddd1fbSWolfgang Denk#include <asm-offsets.h> 2984ad6884SPeter Tyser#include <config.h> 3084ad6884SPeter Tyser#include <version.h> 3184ad6884SPeter Tyser 3284ad6884SPeter Tyser/* 3384ad6884SPeter Tyser ************************************************************************* 3484ad6884SPeter Tyser * 3584ad6884SPeter Tyser * Jump vector table as in table 3.1 in [1] 3684ad6884SPeter Tyser * 3784ad6884SPeter Tyser ************************************************************************* 3884ad6884SPeter Tyser */ 3984ad6884SPeter Tyser 4084ad6884SPeter Tyser 4184ad6884SPeter Tyser.globl _start 4284ad6884SPeter Tyser_start: b reset 4384ad6884SPeter Tyser ldr pc, _undefined_instruction 4484ad6884SPeter Tyser ldr pc, _software_interrupt 4584ad6884SPeter Tyser ldr pc, _prefetch_abort 4684ad6884SPeter Tyser ldr pc, _data_abort 4784ad6884SPeter Tyser ldr pc, _not_used 4884ad6884SPeter Tyser ldr pc, _irq 4984ad6884SPeter Tyser ldr pc, _fiq 5084ad6884SPeter Tyser 5184ad6884SPeter Tyser_undefined_instruction: .word undefined_instruction 5284ad6884SPeter Tyser_software_interrupt: .word software_interrupt 5384ad6884SPeter Tyser_prefetch_abort: .word prefetch_abort 5484ad6884SPeter Tyser_data_abort: .word data_abort 5584ad6884SPeter Tyser_not_used: .word not_used 5684ad6884SPeter Tyser_irq: .word irq 5784ad6884SPeter Tyser_fiq: .word fiq 5884ad6884SPeter Tyser 5984ad6884SPeter Tyser .balignl 16,0xdeadbeef 6084ad6884SPeter Tyser 6184ad6884SPeter Tyser 6284ad6884SPeter Tyser/* 6384ad6884SPeter Tyser ************************************************************************* 6484ad6884SPeter Tyser * 6584ad6884SPeter Tyser * Startup Code (reset vector) 6684ad6884SPeter Tyser * 6784ad6884SPeter Tyser * do important init only if we don't start from memory! 6884ad6884SPeter Tyser * relocate armboot to ram 6984ad6884SPeter Tyser * setup stack 7084ad6884SPeter Tyser * jump to second stage 7184ad6884SPeter Tyser * 7284ad6884SPeter Tyser ************************************************************************* 7384ad6884SPeter Tyser */ 7484ad6884SPeter Tyser 75e30ceca2SHeiko Schocher.globl _TEXT_BASE 7684ad6884SPeter Tyser_TEXT_BASE: 7714d0a02aSWolfgang Denk .word CONFIG_SYS_TEXT_BASE 7884ad6884SPeter Tyser 7984ad6884SPeter Tyser/* 8084ad6884SPeter Tyser * These are defined in the board-specific linker script. 813336ca60SAlbert Aribaud * Subtracting _start from them lets the linker put their 823336ca60SAlbert Aribaud * relative position in the executable instead of leaving 833336ca60SAlbert Aribaud * them null. 8484ad6884SPeter Tyser */ 853336ca60SAlbert Aribaud.globl _bss_start_ofs 863336ca60SAlbert Aribaud_bss_start_ofs: 873336ca60SAlbert Aribaud .word __bss_start - _start 8884ad6884SPeter Tyser 893336ca60SAlbert Aribaud.globl _bss_end_ofs 903336ca60SAlbert Aribaud_bss_end_ofs: 9144c6e659SPo-Yu Chuang .word __bss_end__ - _start 9284ad6884SPeter Tyser 93f326cbbaSPo-Yu Chuang.globl _end_ofs 94f326cbbaSPo-Yu Chuang_end_ofs: 95f326cbbaSPo-Yu Chuang .word _end - _start 96f326cbbaSPo-Yu Chuang 9784ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ 9884ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */ 9984ad6884SPeter Tyser.globl IRQ_STACK_START 10084ad6884SPeter TyserIRQ_STACK_START: 10184ad6884SPeter Tyser .word 0x0badc0de 10284ad6884SPeter Tyser 10384ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */ 10484ad6884SPeter Tyser.globl FIQ_STACK_START 10584ad6884SPeter TyserFIQ_STACK_START: 10684ad6884SPeter Tyser .word 0x0badc0de 10784ad6884SPeter Tyser#endif 10884ad6884SPeter Tyser 109e30ceca2SHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */ 110e30ceca2SHeiko Schocher.globl IRQ_STACK_START_IN 111e30ceca2SHeiko SchocherIRQ_STACK_START_IN: 112e30ceca2SHeiko Schocher .word 0x0badc0de 113e30ceca2SHeiko Schocher 114e30ceca2SHeiko Schocher/* 115e30ceca2SHeiko Schocher * the actual reset code 116e30ceca2SHeiko Schocher */ 117e30ceca2SHeiko Schocher 118e30ceca2SHeiko Schocherreset: 119e30ceca2SHeiko Schocher /* 120e30ceca2SHeiko Schocher * set the cpu to SVC32 mode 121e30ceca2SHeiko Schocher */ 122e30ceca2SHeiko Schocher mrs r0,cpsr 123e30ceca2SHeiko Schocher bic r0,r0,#0x1f 124e30ceca2SHeiko Schocher orr r0,r0,#0xd3 125e30ceca2SHeiko Schocher msr cpsr,r0 126e30ceca2SHeiko Schocher 127e30ceca2SHeiko Schocher /* 128e30ceca2SHeiko Schocher * we do sys-critical inits only at reboot, 129e30ceca2SHeiko Schocher * not when booting from ram! 130e30ceca2SHeiko Schocher */ 131e30ceca2SHeiko Schocher#ifndef CONFIG_SKIP_LOWLEVEL_INIT 132e30ceca2SHeiko Schocher bl cpu_init_crit 133e30ceca2SHeiko Schocher#endif 134e30ceca2SHeiko Schocher 135e30ceca2SHeiko Schocher/* Set stackpointer in internal RAM to call board_init_f */ 136e30ceca2SHeiko Schochercall_board_init_f: 137e30ceca2SHeiko Schocher ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) 138296cae73SHeiko Schocher bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ 139e30ceca2SHeiko Schocher ldr r0,=0x00000000 140e30ceca2SHeiko Schocher bl board_init_f 141e30ceca2SHeiko Schocher 142e30ceca2SHeiko Schocher/*------------------------------------------------------------------------------*/ 143e30ceca2SHeiko Schocher 144e30ceca2SHeiko Schocher/* 145e30ceca2SHeiko Schocher * void relocate_code (addr_sp, gd, addr_moni) 146e30ceca2SHeiko Schocher * 147e30ceca2SHeiko Schocher * This "function" does not return, instead it continues in RAM 148e30ceca2SHeiko Schocher * after relocating the monitor code. 149e30ceca2SHeiko Schocher * 150e30ceca2SHeiko Schocher */ 151e30ceca2SHeiko Schocher .globl relocate_code 152e30ceca2SHeiko Schocherrelocate_code: 153e30ceca2SHeiko Schocher mov r4, r0 /* save addr_sp */ 154e30ceca2SHeiko Schocher mov r5, r1 /* save addr of gd */ 155e30ceca2SHeiko Schocher mov r6, r2 /* save addr of destination */ 156e30ceca2SHeiko Schocher 157e30ceca2SHeiko Schocher /* Set up the stack */ 158e30ceca2SHeiko Schocherstack_setup: 159e30ceca2SHeiko Schocher mov sp, r4 160e30ceca2SHeiko Schocher 161e30ceca2SHeiko Schocher adr r0, _start 162a1a47d3cSAndreas Bießmann cmp r0, r6 163a1a47d3cSAndreas Bießmann beq clear_bss /* skip relocation */ 164a78fb68fSAndreas Bießmann mov r1, r6 /* r1 <- scratch for copy_loop */ 1653336ca60SAlbert Aribaud ldr r3, _bss_start_ofs 1663336ca60SAlbert Aribaud add r2, r0, r3 /* r2 <- source end address */ 167e30ceca2SHeiko Schocher 168e30ceca2SHeiko Schochercopy_loop: 169e30ceca2SHeiko Schocher ldmia r0!, {r9-r10} /* copy from source address [r0] */ 170a78fb68fSAndreas Bießmann stmia r1!, {r9-r10} /* copy to target address [r1] */ 171da90d4ceSAlbert Aribaud cmp r0, r2 /* until source end address [r2] */ 172da90d4ceSAlbert Aribaud blo copy_loop 173e30ceca2SHeiko Schocher 174401bb30bSAneesh V#ifndef CONFIG_SPL_BUILD 1753336ca60SAlbert Aribaud /* 1763336ca60SAlbert Aribaud * fix .rel.dyn relocations 1773336ca60SAlbert Aribaud */ 1783336ca60SAlbert Aribaud ldr r0, _TEXT_BASE /* r0 <- Text base */ 179a78fb68fSAndreas Bießmann sub r9, r6, r0 /* r9 <- relocation offset */ 1803336ca60SAlbert Aribaud ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ 1813336ca60SAlbert Aribaud add r10, r10, r0 /* r10 <- sym table in FLASH */ 1823336ca60SAlbert Aribaud ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ 1833336ca60SAlbert Aribaud add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ 1843336ca60SAlbert Aribaud ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ 1853336ca60SAlbert Aribaud add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ 186e30ceca2SHeiko Schocherfixloop: 1873336ca60SAlbert Aribaud ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ 1883336ca60SAlbert Aribaud add r0, r0, r9 /* r0 <- location to fix up in RAM */ 1893336ca60SAlbert Aribaud ldr r1, [r2, #4] 1901f52d89fSAndreas Bießmann and r7, r1, #0xff 1911f52d89fSAndreas Bießmann cmp r7, #23 /* relative fixup? */ 1923336ca60SAlbert Aribaud beq fixrel 1931f52d89fSAndreas Bießmann cmp r7, #2 /* absolute fixup? */ 1943336ca60SAlbert Aribaud beq fixabs 1953336ca60SAlbert Aribaud /* ignore unknown type of fixup */ 1963336ca60SAlbert Aribaud b fixnext 1973336ca60SAlbert Aribaudfixabs: 1983336ca60SAlbert Aribaud /* absolute fix: set location to (offset) symbol value */ 1993336ca60SAlbert Aribaud mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ 2003336ca60SAlbert Aribaud add r1, r10, r1 /* r1 <- address of symbol in table */ 2013336ca60SAlbert Aribaud ldr r1, [r1, #4] /* r1 <- symbol value */ 2023600945bSWolfgang Denk add r1, r1, r9 /* r1 <- relocated sym addr */ 2033336ca60SAlbert Aribaud b fixnext 2043336ca60SAlbert Aribaudfixrel: 2053336ca60SAlbert Aribaud /* relative fix: increase location by offset */ 2063336ca60SAlbert Aribaud ldr r1, [r0] 2073336ca60SAlbert Aribaud add r1, r1, r9 2083336ca60SAlbert Aribaudfixnext: 2093336ca60SAlbert Aribaud str r1, [r0] 2103336ca60SAlbert Aribaud add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ 211e30ceca2SHeiko Schocher cmp r2, r3 21279e63139SWolfgang Denk blo fixloop 213e30ceca2SHeiko Schocher#endif 214e30ceca2SHeiko Schocher 215e30ceca2SHeiko Schocherclear_bss: 216401bb30bSAneesh V#ifndef CONFIG_SPL_BUILD 2173336ca60SAlbert Aribaud ldr r0, _bss_start_ofs 2183336ca60SAlbert Aribaud ldr r1, _bss_end_ofs 219a78fb68fSAndreas Bießmann mov r4, r6 /* reloc addr */ 220e30ceca2SHeiko Schocher add r0, r0, r4 221e30ceca2SHeiko Schocher add r1, r1, r4 222e30ceca2SHeiko Schocher mov r2, #0x00000000 /* clear */ 223e30ceca2SHeiko Schocher 224e30ceca2SHeiko Schocherclbss_l:str r2, [r0] /* clear loop... */ 225e30ceca2SHeiko Schocher add r0, r0, #4 226e30ceca2SHeiko Schocher cmp r0, r1 227e30ceca2SHeiko Schocher bne clbss_l 228e30ceca2SHeiko Schocher#endif 229e30ceca2SHeiko Schocher 230e30ceca2SHeiko Schocher/* 231e30ceca2SHeiko Schocher * We are done. Do not return, instead branch to second part of board 232e30ceca2SHeiko Schocher * initialization, now running from RAM. 233e30ceca2SHeiko Schocher */ 2343336ca60SAlbert Aribaud ldr r0, _board_init_r_ofs 2353336ca60SAlbert Aribaud adr r1, _start 2363336ca60SAlbert Aribaud add lr, r0, r1 2373336ca60SAlbert Aribaud add lr, lr, r9 238e30ceca2SHeiko Schocher /* setup parameters for board_init_r */ 239e30ceca2SHeiko Schocher mov r0, r5 /* gd_t */ 240a78fb68fSAndreas Bießmann mov r1, r6 /* dest_addr */ 241e30ceca2SHeiko Schocher /* jump to it ... */ 242e30ceca2SHeiko Schocher mov pc, lr 243e30ceca2SHeiko Schocher 2443336ca60SAlbert Aribaud_board_init_r_ofs: 2453336ca60SAlbert Aribaud .word board_init_r - _start 2463336ca60SAlbert Aribaud 2473336ca60SAlbert Aribaud_rel_dyn_start_ofs: 2483336ca60SAlbert Aribaud .word __rel_dyn_start - _start 2493336ca60SAlbert Aribaud_rel_dyn_end_ofs: 2503336ca60SAlbert Aribaud .word __rel_dyn_end - _start 2513336ca60SAlbert Aribaud_dynsym_start_ofs: 2523336ca60SAlbert Aribaud .word __dynsym_start - _start 253e30ceca2SHeiko Schocher 25484ad6884SPeter Tyser/* 25584ad6884SPeter Tyser ************************************************************************* 25684ad6884SPeter Tyser * 25784ad6884SPeter Tyser * CPU_init_critical registers 25884ad6884SPeter Tyser * 25984ad6884SPeter Tyser * setup important registers 26084ad6884SPeter Tyser * setup memory timing 26184ad6884SPeter Tyser * 26284ad6884SPeter Tyser ************************************************************************* 26384ad6884SPeter Tyser */ 26484ad6884SPeter Tyser 26584ad6884SPeter Tyser 26616263087SMike Williams/* Interrupt-Controller base address */ 26784ad6884SPeter TyserIC_BASE: .word 0x90050000 26884ad6884SPeter Tyser#define ICMR 0x04 26984ad6884SPeter Tyser 27084ad6884SPeter Tyser 27184ad6884SPeter Tyser/* Reset-Controller */ 27284ad6884SPeter TyserRST_BASE: .word 0x90030000 27384ad6884SPeter Tyser#define RSRR 0x00 27484ad6884SPeter Tyser#define RCSR 0x04 27584ad6884SPeter Tyser 27684ad6884SPeter Tyser 27784ad6884SPeter Tyser/* PWR */ 27884ad6884SPeter TyserPWR_BASE: .word 0x90020000 27984ad6884SPeter Tyser#define PSPR 0x08 28084ad6884SPeter Tyser#define PPCR 0x14 28184ad6884SPeter Tysercpuspeed: .word CONFIG_SYS_CPUSPEED 28284ad6884SPeter Tyser 28384ad6884SPeter Tyser 28484ad6884SPeter Tysercpu_init_crit: 28584ad6884SPeter Tyser /* 28684ad6884SPeter Tyser * mask all IRQs 28784ad6884SPeter Tyser */ 28884ad6884SPeter Tyser ldr r0, IC_BASE 28984ad6884SPeter Tyser mov r1, #0x00 29084ad6884SPeter Tyser str r1, [r0, #ICMR] 29184ad6884SPeter Tyser 29284ad6884SPeter Tyser /* set clock speed */ 29384ad6884SPeter Tyser ldr r0, PWR_BASE 29484ad6884SPeter Tyser ldr r1, cpuspeed 29584ad6884SPeter Tyser str r1, [r0, #PPCR] 29684ad6884SPeter Tyser 29784ad6884SPeter Tyser /* 29884ad6884SPeter Tyser * before relocating, we have to setup RAM timing 29984ad6884SPeter Tyser * because memory timing is board-dependend, you will 30084ad6884SPeter Tyser * find a lowlevel_init.S in your board directory. 30184ad6884SPeter Tyser */ 30284ad6884SPeter Tyser mov ip, lr 30384ad6884SPeter Tyser bl lowlevel_init 30484ad6884SPeter Tyser mov lr, ip 30584ad6884SPeter Tyser 30684ad6884SPeter Tyser /* 30784ad6884SPeter Tyser * disable MMU stuff and enable I-cache 30884ad6884SPeter Tyser */ 30984ad6884SPeter Tyser mrc p15,0,r0,c1,c0 31084ad6884SPeter Tyser bic r0, r0, #0x00002000 @ clear bit 13 (X) 31184ad6884SPeter Tyser bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM) 31284ad6884SPeter Tyser orr r0, r0, #0x00001000 @ set bit 12 (I) Icache 31384ad6884SPeter Tyser orr r0, r0, #0x00000002 @ set bit 2 (A) Align 31484ad6884SPeter Tyser mcr p15,0,r0,c1,c0 31584ad6884SPeter Tyser 31684ad6884SPeter Tyser /* 31784ad6884SPeter Tyser * flush v4 I/D caches 31884ad6884SPeter Tyser */ 31984ad6884SPeter Tyser mov r0, #0 32084ad6884SPeter Tyser mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ 32184ad6884SPeter Tyser mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ 32284ad6884SPeter Tyser 32384ad6884SPeter Tyser mov pc, lr 32484ad6884SPeter Tyser 32584ad6884SPeter Tyser 32684ad6884SPeter Tyser/* 32784ad6884SPeter Tyser ************************************************************************* 32884ad6884SPeter Tyser * 32984ad6884SPeter Tyser * Interrupt handling 33084ad6884SPeter Tyser * 33184ad6884SPeter Tyser ************************************************************************* 33284ad6884SPeter Tyser */ 33384ad6884SPeter Tyser 33484ad6884SPeter Tyser@ 33584ad6884SPeter Tyser@ IRQ stack frame. 33684ad6884SPeter Tyser@ 33784ad6884SPeter Tyser#define S_FRAME_SIZE 72 33884ad6884SPeter Tyser 33984ad6884SPeter Tyser#define S_OLD_R0 68 34084ad6884SPeter Tyser#define S_PSR 64 34184ad6884SPeter Tyser#define S_PC 60 34284ad6884SPeter Tyser#define S_LR 56 34384ad6884SPeter Tyser#define S_SP 52 34484ad6884SPeter Tyser 34584ad6884SPeter Tyser#define S_IP 48 34684ad6884SPeter Tyser#define S_FP 44 34784ad6884SPeter Tyser#define S_R10 40 34884ad6884SPeter Tyser#define S_R9 36 34984ad6884SPeter Tyser#define S_R8 32 35084ad6884SPeter Tyser#define S_R7 28 35184ad6884SPeter Tyser#define S_R6 24 35284ad6884SPeter Tyser#define S_R5 20 35384ad6884SPeter Tyser#define S_R4 16 35484ad6884SPeter Tyser#define S_R3 12 35584ad6884SPeter Tyser#define S_R2 8 35684ad6884SPeter Tyser#define S_R1 4 35784ad6884SPeter Tyser#define S_R0 0 35884ad6884SPeter Tyser 35984ad6884SPeter Tyser#define MODE_SVC 0x13 36084ad6884SPeter Tyser#define I_BIT 0x80 36184ad6884SPeter Tyser 36284ad6884SPeter Tyser/* 36384ad6884SPeter Tyser * use bad_save_user_regs for abort/prefetch/undef/swi ... 36484ad6884SPeter Tyser * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling 36584ad6884SPeter Tyser */ 36684ad6884SPeter Tyser 36784ad6884SPeter Tyser .macro bad_save_user_regs 36884ad6884SPeter Tyser sub sp, sp, #S_FRAME_SIZE 36984ad6884SPeter Tyser stmia sp, {r0 - r12} @ Calling r0-r12 37084ad6884SPeter Tyser add r8, sp, #S_PC 37184ad6884SPeter Tyser 372e30ceca2SHeiko Schocher ldr r2, IRQ_STACK_START_IN 37384ad6884SPeter Tyser ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 37484ad6884SPeter Tyser add r0, sp, #S_FRAME_SIZE @ restore sp_SVC 37584ad6884SPeter Tyser 37684ad6884SPeter Tyser add r5, sp, #S_SP 37784ad6884SPeter Tyser mov r1, lr 37884ad6884SPeter Tyser stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r 37984ad6884SPeter Tyser mov r0, sp 38084ad6884SPeter Tyser .endm 38184ad6884SPeter Tyser 38284ad6884SPeter Tyser .macro irq_save_user_regs 38384ad6884SPeter Tyser sub sp, sp, #S_FRAME_SIZE 38484ad6884SPeter Tyser stmia sp, {r0 - r12} @ Calling r0-r12 38584ad6884SPeter Tyser add r8, sp, #S_PC 38684ad6884SPeter Tyser stmdb r8, {sp, lr}^ @ Calling SP, LR 38784ad6884SPeter Tyser str lr, [r8, #0] @ Save calling PC 38884ad6884SPeter Tyser mrs r6, spsr 38984ad6884SPeter Tyser str r6, [r8, #4] @ Save CPSR 39084ad6884SPeter Tyser str r0, [r8, #8] @ Save OLD_R0 39184ad6884SPeter Tyser mov r0, sp 39284ad6884SPeter Tyser .endm 39384ad6884SPeter Tyser 39484ad6884SPeter Tyser .macro irq_restore_user_regs 39584ad6884SPeter Tyser ldmia sp, {r0 - lr}^ @ Calling r0 - lr 39684ad6884SPeter Tyser mov r0, r0 39784ad6884SPeter Tyser ldr lr, [sp, #S_PC] @ Get PC 39884ad6884SPeter Tyser add sp, sp, #S_FRAME_SIZE 39984ad6884SPeter Tyser subs pc, lr, #4 @ return & move spsr_svc into cpsr 40084ad6884SPeter Tyser .endm 40184ad6884SPeter Tyser 40284ad6884SPeter Tyser .macro get_bad_stack 403e30ceca2SHeiko Schocher ldr r13, IRQ_STACK_START_IN @ setup our mode stack 40484ad6884SPeter Tyser 40584ad6884SPeter Tyser str lr, [r13] @ save caller lr / spsr 40684ad6884SPeter Tyser mrs lr, spsr 40784ad6884SPeter Tyser str lr, [r13, #4] 40884ad6884SPeter Tyser 40984ad6884SPeter Tyser mov r13, #MODE_SVC @ prepare SVC-Mode 41084ad6884SPeter Tyser msr spsr_c, r13 41184ad6884SPeter Tyser mov lr, pc 41284ad6884SPeter Tyser movs pc, lr 41384ad6884SPeter Tyser .endm 41484ad6884SPeter Tyser 41584ad6884SPeter Tyser .macro get_irq_stack @ setup IRQ stack 41684ad6884SPeter Tyser ldr sp, IRQ_STACK_START 41784ad6884SPeter Tyser .endm 41884ad6884SPeter Tyser 41984ad6884SPeter Tyser .macro get_fiq_stack @ setup FIQ stack 42084ad6884SPeter Tyser ldr sp, FIQ_STACK_START 42184ad6884SPeter Tyser .endm 42284ad6884SPeter Tyser 42384ad6884SPeter Tyser/* 42484ad6884SPeter Tyser * exception handlers 42584ad6884SPeter Tyser */ 42684ad6884SPeter Tyser .align 5 42784ad6884SPeter Tyserundefined_instruction: 42884ad6884SPeter Tyser get_bad_stack 42984ad6884SPeter Tyser bad_save_user_regs 43084ad6884SPeter Tyser bl do_undefined_instruction 43184ad6884SPeter Tyser 43284ad6884SPeter Tyser .align 5 43384ad6884SPeter Tysersoftware_interrupt: 43484ad6884SPeter Tyser get_bad_stack 43584ad6884SPeter Tyser bad_save_user_regs 43684ad6884SPeter Tyser bl do_software_interrupt 43784ad6884SPeter Tyser 43884ad6884SPeter Tyser .align 5 43984ad6884SPeter Tyserprefetch_abort: 44084ad6884SPeter Tyser get_bad_stack 44184ad6884SPeter Tyser bad_save_user_regs 44284ad6884SPeter Tyser bl do_prefetch_abort 44384ad6884SPeter Tyser 44484ad6884SPeter Tyser .align 5 44584ad6884SPeter Tyserdata_abort: 44684ad6884SPeter Tyser get_bad_stack 44784ad6884SPeter Tyser bad_save_user_regs 44884ad6884SPeter Tyser bl do_data_abort 44984ad6884SPeter Tyser 45084ad6884SPeter Tyser .align 5 45184ad6884SPeter Tysernot_used: 45284ad6884SPeter Tyser get_bad_stack 45384ad6884SPeter Tyser bad_save_user_regs 45484ad6884SPeter Tyser bl do_not_used 45584ad6884SPeter Tyser 45684ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ 45784ad6884SPeter Tyser 45884ad6884SPeter Tyser .align 5 45984ad6884SPeter Tyserirq: 46084ad6884SPeter Tyser get_irq_stack 46184ad6884SPeter Tyser irq_save_user_regs 46284ad6884SPeter Tyser bl do_irq 46384ad6884SPeter Tyser irq_restore_user_regs 46484ad6884SPeter Tyser 46584ad6884SPeter Tyser .align 5 46684ad6884SPeter Tyserfiq: 46784ad6884SPeter Tyser get_fiq_stack 46884ad6884SPeter Tyser /* someone ought to write a more effiction fiq_save_user_regs */ 46984ad6884SPeter Tyser irq_save_user_regs 47084ad6884SPeter Tyser bl do_fiq 47184ad6884SPeter Tyser irq_restore_user_regs 47284ad6884SPeter Tyser 47384ad6884SPeter Tyser#else 47484ad6884SPeter Tyser 47584ad6884SPeter Tyser .align 5 47684ad6884SPeter Tyserirq: 47784ad6884SPeter Tyser get_bad_stack 47884ad6884SPeter Tyser bad_save_user_regs 47984ad6884SPeter Tyser bl do_irq 48084ad6884SPeter Tyser 48184ad6884SPeter Tyser .align 5 48284ad6884SPeter Tyserfiq: 48384ad6884SPeter Tyser get_bad_stack 48484ad6884SPeter Tyser bad_save_user_regs 48584ad6884SPeter Tyser bl do_fiq 48684ad6884SPeter Tyser 48784ad6884SPeter Tyser#endif 48884ad6884SPeter Tyser 48984ad6884SPeter Tyser .align 5 49084ad6884SPeter Tyser.globl reset_cpu 49184ad6884SPeter Tyserreset_cpu: 49284ad6884SPeter Tyser ldr r0, RST_BASE 49384ad6884SPeter Tyser mov r1, #0x0 @ set bit 3-0 ... 49484ad6884SPeter Tyser str r1, [r0, #RCSR] @ ... to clear in RCSR 49584ad6884SPeter Tyser mov r1, #0x1 49684ad6884SPeter Tyser str r1, [r0, #RSRR] @ and perform reset 49784ad6884SPeter Tyser b reset_cpu @ silly, but repeat endlessly 498