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> 784ad6884SPeter Tyser * 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. 81*3336ca60SAlbert Aribaud * Subtracting _start from them lets the linker put their 82*3336ca60SAlbert Aribaud * relative position in the executable instead of leaving 83*3336ca60SAlbert Aribaud * them null. 8484ad6884SPeter Tyser */ 85*3336ca60SAlbert Aribaud.globl _bss_start_ofs 86*3336ca60SAlbert Aribaud_bss_start_ofs: 87*3336ca60SAlbert Aribaud .word __bss_start - _start 8884ad6884SPeter Tyser 89*3336ca60SAlbert Aribaud.globl _bss_end_ofs 90*3336ca60SAlbert Aribaud_bss_end_ofs: 91*3336ca60SAlbert Aribaud .word _end - _start 9284ad6884SPeter Tyser 9384ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ 9484ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */ 9584ad6884SPeter Tyser.globl IRQ_STACK_START 9684ad6884SPeter TyserIRQ_STACK_START: 9784ad6884SPeter Tyser .word 0x0badc0de 9884ad6884SPeter Tyser 9984ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */ 10084ad6884SPeter Tyser.globl FIQ_STACK_START 10184ad6884SPeter TyserFIQ_STACK_START: 10284ad6884SPeter Tyser .word 0x0badc0de 10384ad6884SPeter Tyser#endif 10484ad6884SPeter Tyser 105e30ceca2SHeiko Schocher/* IRQ stack memory (calculated at run-time) + 8 bytes */ 106e30ceca2SHeiko Schocher.globl IRQ_STACK_START_IN 107e30ceca2SHeiko SchocherIRQ_STACK_START_IN: 108e30ceca2SHeiko Schocher .word 0x0badc0de 109e30ceca2SHeiko Schocher 110e30ceca2SHeiko Schocher/* 111e30ceca2SHeiko Schocher * the actual reset code 112e30ceca2SHeiko Schocher */ 113e30ceca2SHeiko Schocher 114e30ceca2SHeiko Schocherreset: 115e30ceca2SHeiko Schocher /* 116e30ceca2SHeiko Schocher * set the cpu to SVC32 mode 117e30ceca2SHeiko Schocher */ 118e30ceca2SHeiko Schocher mrs r0,cpsr 119e30ceca2SHeiko Schocher bic r0,r0,#0x1f 120e30ceca2SHeiko Schocher orr r0,r0,#0xd3 121e30ceca2SHeiko Schocher msr cpsr,r0 122e30ceca2SHeiko Schocher 123e30ceca2SHeiko Schocher /* 124e30ceca2SHeiko Schocher * we do sys-critical inits only at reboot, 125e30ceca2SHeiko Schocher * not when booting from ram! 126e30ceca2SHeiko Schocher */ 127e30ceca2SHeiko Schocher#ifndef CONFIG_SKIP_LOWLEVEL_INIT 128e30ceca2SHeiko Schocher bl cpu_init_crit 129e30ceca2SHeiko Schocher#endif 130e30ceca2SHeiko Schocher 131e30ceca2SHeiko Schocher/* Set stackpointer in internal RAM to call board_init_f */ 132e30ceca2SHeiko Schochercall_board_init_f: 133e30ceca2SHeiko Schocher ldr sp, =(CONFIG_SYS_INIT_SP_ADDR) 134e30ceca2SHeiko Schocher ldr r0,=0x00000000 135e30ceca2SHeiko Schocher bl board_init_f 136e30ceca2SHeiko Schocher 137e30ceca2SHeiko Schocher/*------------------------------------------------------------------------------*/ 138e30ceca2SHeiko Schocher 139e30ceca2SHeiko Schocher/* 140e30ceca2SHeiko Schocher * void relocate_code (addr_sp, gd, addr_moni) 141e30ceca2SHeiko Schocher * 142e30ceca2SHeiko Schocher * This "function" does not return, instead it continues in RAM 143e30ceca2SHeiko Schocher * after relocating the monitor code. 144e30ceca2SHeiko Schocher * 145e30ceca2SHeiko Schocher */ 146e30ceca2SHeiko Schocher .globl relocate_code 147e30ceca2SHeiko Schocherrelocate_code: 148e30ceca2SHeiko Schocher mov r4, r0 /* save addr_sp */ 149e30ceca2SHeiko Schocher mov r5, r1 /* save addr of gd */ 150e30ceca2SHeiko Schocher mov r6, r2 /* save addr of destination */ 151e30ceca2SHeiko Schocher mov r7, r2 /* save addr of destination */ 152e30ceca2SHeiko Schocher 153e30ceca2SHeiko Schocher /* Set up the stack */ 154e30ceca2SHeiko Schocherstack_setup: 155e30ceca2SHeiko Schocher mov sp, r4 156e30ceca2SHeiko Schocher 157e30ceca2SHeiko Schocher adr r0, _start 158e30ceca2SHeiko Schocher ldr r2, _TEXT_BASE 159*3336ca60SAlbert Aribaud ldr r3, _bss_start_ofs 160*3336ca60SAlbert Aribaud add r2, r0, r3 /* r2 <- source end address */ 161e30ceca2SHeiko Schocher cmp r0, r6 162e30ceca2SHeiko Schocher beq clear_bss 163e30ceca2SHeiko Schocher 164e30ceca2SHeiko Schochercopy_loop: 165e30ceca2SHeiko Schocher ldmia r0!, {r9-r10} /* copy from source address [r0] */ 166e30ceca2SHeiko Schocher stmia r6!, {r9-r10} /* copy to target address [r1] */ 167da90d4ceSAlbert Aribaud cmp r0, r2 /* until source end address [r2] */ 168da90d4ceSAlbert Aribaud blo copy_loop 169e30ceca2SHeiko Schocher 170e30ceca2SHeiko Schocher#ifndef CONFIG_PRELOADER 171*3336ca60SAlbert Aribaud /* 172*3336ca60SAlbert Aribaud * fix .rel.dyn relocations 173*3336ca60SAlbert Aribaud */ 174*3336ca60SAlbert Aribaud ldr r0, _TEXT_BASE /* r0 <- Text base */ 175*3336ca60SAlbert Aribaud sub r9, r7, r0 /* r9 <- relocation offset */ 176*3336ca60SAlbert Aribaud ldr r10, _dynsym_start_ofs /* r10 <- sym table ofs */ 177*3336ca60SAlbert Aribaud add r10, r10, r0 /* r10 <- sym table in FLASH */ 178*3336ca60SAlbert Aribaud ldr r2, _rel_dyn_start_ofs /* r2 <- rel dyn start ofs */ 179*3336ca60SAlbert Aribaud add r2, r2, r0 /* r2 <- rel dyn start in FLASH */ 180*3336ca60SAlbert Aribaud ldr r3, _rel_dyn_end_ofs /* r3 <- rel dyn end ofs */ 181*3336ca60SAlbert Aribaud add r3, r3, r0 /* r3 <- rel dyn end in FLASH */ 182e30ceca2SHeiko Schocherfixloop: 183*3336ca60SAlbert Aribaud ldr r0, [r2] /* r0 <- location to fix up, IN FLASH! */ 184*3336ca60SAlbert Aribaud add r0, r0, r9 /* r0 <- location to fix up in RAM */ 185*3336ca60SAlbert Aribaud ldr r1, [r2, #4] 186*3336ca60SAlbert Aribaud and r8, r1, #0xff 187*3336ca60SAlbert Aribaud cmp r8, #23 /* relative fixup? */ 188*3336ca60SAlbert Aribaud beq fixrel 189*3336ca60SAlbert Aribaud cmp r8, #2 /* absolute fixup? */ 190*3336ca60SAlbert Aribaud beq fixabs 191*3336ca60SAlbert Aribaud /* ignore unknown type of fixup */ 192*3336ca60SAlbert Aribaud b fixnext 193*3336ca60SAlbert Aribaudfixabs: 194*3336ca60SAlbert Aribaud /* absolute fix: set location to (offset) symbol value */ 195*3336ca60SAlbert Aribaud mov r1, r1, LSR #4 /* r1 <- symbol index in .dynsym */ 196*3336ca60SAlbert Aribaud add r1, r10, r1 /* r1 <- address of symbol in table */ 197*3336ca60SAlbert Aribaud ldr r1, [r1, #4] /* r1 <- symbol value */ 198*3336ca60SAlbert Aribaud add r1, r9 /* r1 <- relocated sym addr */ 199*3336ca60SAlbert Aribaud b fixnext 200*3336ca60SAlbert Aribaudfixrel: 201*3336ca60SAlbert Aribaud /* relative fix: increase location by offset */ 202*3336ca60SAlbert Aribaud ldr r1, [r0] 203*3336ca60SAlbert Aribaud add r1, r1, r9 204*3336ca60SAlbert Aribaudfixnext: 205*3336ca60SAlbert Aribaud str r1, [r0] 206*3336ca60SAlbert Aribaud add r2, r2, #8 /* each rel.dyn entry is 8 bytes */ 207e30ceca2SHeiko Schocher cmp r2, r3 20879e63139SWolfgang Denk blo fixloop 209e30ceca2SHeiko Schocher#endif 210e30ceca2SHeiko Schocher 211e30ceca2SHeiko Schocherclear_bss: 212e30ceca2SHeiko Schocher#ifndef CONFIG_PRELOADER 213*3336ca60SAlbert Aribaud ldr r0, _bss_start_ofs 214*3336ca60SAlbert Aribaud ldr r1, _bss_end_ofs 215e30ceca2SHeiko Schocher ldr r3, _TEXT_BASE /* Text base */ 216e30ceca2SHeiko Schocher mov r4, r7 /* reloc addr */ 217e30ceca2SHeiko Schocher add r0, r0, r4 218e30ceca2SHeiko Schocher add r1, r1, r4 219e30ceca2SHeiko Schocher mov r2, #0x00000000 /* clear */ 220e30ceca2SHeiko Schocher 221e30ceca2SHeiko Schocherclbss_l:str r2, [r0] /* clear loop... */ 222e30ceca2SHeiko Schocher add r0, r0, #4 223e30ceca2SHeiko Schocher cmp r0, r1 224e30ceca2SHeiko Schocher bne clbss_l 225e30ceca2SHeiko Schocher#endif 226e30ceca2SHeiko Schocher 227e30ceca2SHeiko Schocher/* 228e30ceca2SHeiko Schocher * We are done. Do not return, instead branch to second part of board 229e30ceca2SHeiko Schocher * initialization, now running from RAM. 230e30ceca2SHeiko Schocher */ 231*3336ca60SAlbert Aribaud ldr r0, _board_init_r_ofs 232*3336ca60SAlbert Aribaud adr r1, _start 233*3336ca60SAlbert Aribaud add lr, r0, r1 234*3336ca60SAlbert Aribaud add lr, lr, r9 235e30ceca2SHeiko Schocher /* setup parameters for board_init_r */ 236e30ceca2SHeiko Schocher mov r0, r5 /* gd_t */ 237e30ceca2SHeiko Schocher mov r1, r7 /* dest_addr */ 238e30ceca2SHeiko Schocher /* jump to it ... */ 239e30ceca2SHeiko Schocher mov pc, lr 240e30ceca2SHeiko Schocher 241*3336ca60SAlbert Aribaud_board_init_r_ofs: 242*3336ca60SAlbert Aribaud .word board_init_r - _start 243*3336ca60SAlbert Aribaud 244*3336ca60SAlbert Aribaud_rel_dyn_start_ofs: 245*3336ca60SAlbert Aribaud .word __rel_dyn_start - _start 246*3336ca60SAlbert Aribaud_rel_dyn_end_ofs: 247*3336ca60SAlbert Aribaud .word __rel_dyn_end - _start 248*3336ca60SAlbert Aribaud_dynsym_start_ofs: 249*3336ca60SAlbert Aribaud .word __dynsym_start - _start 250e30ceca2SHeiko Schocher 25184ad6884SPeter Tyser/* 25284ad6884SPeter Tyser ************************************************************************* 25384ad6884SPeter Tyser * 25484ad6884SPeter Tyser * CPU_init_critical registers 25584ad6884SPeter Tyser * 25684ad6884SPeter Tyser * setup important registers 25784ad6884SPeter Tyser * setup memory timing 25884ad6884SPeter Tyser * 25984ad6884SPeter Tyser ************************************************************************* 26084ad6884SPeter Tyser */ 26184ad6884SPeter Tyser 26284ad6884SPeter Tyser 26384ad6884SPeter Tyser/* Interupt-Controller base address */ 26484ad6884SPeter TyserIC_BASE: .word 0x90050000 26584ad6884SPeter Tyser#define ICMR 0x04 26684ad6884SPeter Tyser 26784ad6884SPeter Tyser 26884ad6884SPeter Tyser/* Reset-Controller */ 26984ad6884SPeter TyserRST_BASE: .word 0x90030000 27084ad6884SPeter Tyser#define RSRR 0x00 27184ad6884SPeter Tyser#define RCSR 0x04 27284ad6884SPeter Tyser 27384ad6884SPeter Tyser 27484ad6884SPeter Tyser/* PWR */ 27584ad6884SPeter TyserPWR_BASE: .word 0x90020000 27684ad6884SPeter Tyser#define PSPR 0x08 27784ad6884SPeter Tyser#define PPCR 0x14 27884ad6884SPeter Tysercpuspeed: .word CONFIG_SYS_CPUSPEED 27984ad6884SPeter Tyser 28084ad6884SPeter Tyser 28184ad6884SPeter Tysercpu_init_crit: 28284ad6884SPeter Tyser /* 28384ad6884SPeter Tyser * mask all IRQs 28484ad6884SPeter Tyser */ 28584ad6884SPeter Tyser ldr r0, IC_BASE 28684ad6884SPeter Tyser mov r1, #0x00 28784ad6884SPeter Tyser str r1, [r0, #ICMR] 28884ad6884SPeter Tyser 28984ad6884SPeter Tyser /* set clock speed */ 29084ad6884SPeter Tyser ldr r0, PWR_BASE 29184ad6884SPeter Tyser ldr r1, cpuspeed 29284ad6884SPeter Tyser str r1, [r0, #PPCR] 29384ad6884SPeter Tyser 29484ad6884SPeter Tyser /* 29584ad6884SPeter Tyser * before relocating, we have to setup RAM timing 29684ad6884SPeter Tyser * because memory timing is board-dependend, you will 29784ad6884SPeter Tyser * find a lowlevel_init.S in your board directory. 29884ad6884SPeter Tyser */ 29984ad6884SPeter Tyser mov ip, lr 30084ad6884SPeter Tyser bl lowlevel_init 30184ad6884SPeter Tyser mov lr, ip 30284ad6884SPeter Tyser 30384ad6884SPeter Tyser /* 30484ad6884SPeter Tyser * disable MMU stuff and enable I-cache 30584ad6884SPeter Tyser */ 30684ad6884SPeter Tyser mrc p15,0,r0,c1,c0 30784ad6884SPeter Tyser bic r0, r0, #0x00002000 @ clear bit 13 (X) 30884ad6884SPeter Tyser bic r0, r0, #0x0000000f @ clear bits 3-0 (WCAM) 30984ad6884SPeter Tyser orr r0, r0, #0x00001000 @ set bit 12 (I) Icache 31084ad6884SPeter Tyser orr r0, r0, #0x00000002 @ set bit 2 (A) Align 31184ad6884SPeter Tyser mcr p15,0,r0,c1,c0 31284ad6884SPeter Tyser 31384ad6884SPeter Tyser /* 31484ad6884SPeter Tyser * flush v4 I/D caches 31584ad6884SPeter Tyser */ 31684ad6884SPeter Tyser mov r0, #0 31784ad6884SPeter Tyser mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ 31884ad6884SPeter Tyser mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ 31984ad6884SPeter Tyser 32084ad6884SPeter Tyser mov pc, lr 32184ad6884SPeter Tyser 32284ad6884SPeter Tyser 32384ad6884SPeter Tyser/* 32484ad6884SPeter Tyser ************************************************************************* 32584ad6884SPeter Tyser * 32684ad6884SPeter Tyser * Interrupt handling 32784ad6884SPeter Tyser * 32884ad6884SPeter Tyser ************************************************************************* 32984ad6884SPeter Tyser */ 33084ad6884SPeter Tyser 33184ad6884SPeter Tyser@ 33284ad6884SPeter Tyser@ IRQ stack frame. 33384ad6884SPeter Tyser@ 33484ad6884SPeter Tyser#define S_FRAME_SIZE 72 33584ad6884SPeter Tyser 33684ad6884SPeter Tyser#define S_OLD_R0 68 33784ad6884SPeter Tyser#define S_PSR 64 33884ad6884SPeter Tyser#define S_PC 60 33984ad6884SPeter Tyser#define S_LR 56 34084ad6884SPeter Tyser#define S_SP 52 34184ad6884SPeter Tyser 34284ad6884SPeter Tyser#define S_IP 48 34384ad6884SPeter Tyser#define S_FP 44 34484ad6884SPeter Tyser#define S_R10 40 34584ad6884SPeter Tyser#define S_R9 36 34684ad6884SPeter Tyser#define S_R8 32 34784ad6884SPeter Tyser#define S_R7 28 34884ad6884SPeter Tyser#define S_R6 24 34984ad6884SPeter Tyser#define S_R5 20 35084ad6884SPeter Tyser#define S_R4 16 35184ad6884SPeter Tyser#define S_R3 12 35284ad6884SPeter Tyser#define S_R2 8 35384ad6884SPeter Tyser#define S_R1 4 35484ad6884SPeter Tyser#define S_R0 0 35584ad6884SPeter Tyser 35684ad6884SPeter Tyser#define MODE_SVC 0x13 35784ad6884SPeter Tyser#define I_BIT 0x80 35884ad6884SPeter Tyser 35984ad6884SPeter Tyser/* 36084ad6884SPeter Tyser * use bad_save_user_regs for abort/prefetch/undef/swi ... 36184ad6884SPeter Tyser * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling 36284ad6884SPeter Tyser */ 36384ad6884SPeter Tyser 36484ad6884SPeter Tyser .macro bad_save_user_regs 36584ad6884SPeter Tyser sub sp, sp, #S_FRAME_SIZE 36684ad6884SPeter Tyser stmia sp, {r0 - r12} @ Calling r0-r12 36784ad6884SPeter Tyser add r8, sp, #S_PC 36884ad6884SPeter Tyser 369e30ceca2SHeiko Schocher ldr r2, IRQ_STACK_START_IN 37084ad6884SPeter Tyser ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 37184ad6884SPeter Tyser add r0, sp, #S_FRAME_SIZE @ restore sp_SVC 37284ad6884SPeter Tyser 37384ad6884SPeter Tyser add r5, sp, #S_SP 37484ad6884SPeter Tyser mov r1, lr 37584ad6884SPeter Tyser stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r 37684ad6884SPeter Tyser mov r0, sp 37784ad6884SPeter Tyser .endm 37884ad6884SPeter Tyser 37984ad6884SPeter Tyser .macro irq_save_user_regs 38084ad6884SPeter Tyser sub sp, sp, #S_FRAME_SIZE 38184ad6884SPeter Tyser stmia sp, {r0 - r12} @ Calling r0-r12 38284ad6884SPeter Tyser add r8, sp, #S_PC 38384ad6884SPeter Tyser stmdb r8, {sp, lr}^ @ Calling SP, LR 38484ad6884SPeter Tyser str lr, [r8, #0] @ Save calling PC 38584ad6884SPeter Tyser mrs r6, spsr 38684ad6884SPeter Tyser str r6, [r8, #4] @ Save CPSR 38784ad6884SPeter Tyser str r0, [r8, #8] @ Save OLD_R0 38884ad6884SPeter Tyser mov r0, sp 38984ad6884SPeter Tyser .endm 39084ad6884SPeter Tyser 39184ad6884SPeter Tyser .macro irq_restore_user_regs 39284ad6884SPeter Tyser ldmia sp, {r0 - lr}^ @ Calling r0 - lr 39384ad6884SPeter Tyser mov r0, r0 39484ad6884SPeter Tyser ldr lr, [sp, #S_PC] @ Get PC 39584ad6884SPeter Tyser add sp, sp, #S_FRAME_SIZE 39684ad6884SPeter Tyser subs pc, lr, #4 @ return & move spsr_svc into cpsr 39784ad6884SPeter Tyser .endm 39884ad6884SPeter Tyser 39984ad6884SPeter Tyser .macro get_bad_stack 400e30ceca2SHeiko Schocher ldr r13, IRQ_STACK_START_IN @ setup our mode stack 40184ad6884SPeter Tyser 40284ad6884SPeter Tyser str lr, [r13] @ save caller lr / spsr 40384ad6884SPeter Tyser mrs lr, spsr 40484ad6884SPeter Tyser str lr, [r13, #4] 40584ad6884SPeter Tyser 40684ad6884SPeter Tyser mov r13, #MODE_SVC @ prepare SVC-Mode 40784ad6884SPeter Tyser msr spsr_c, r13 40884ad6884SPeter Tyser mov lr, pc 40984ad6884SPeter Tyser movs pc, lr 41084ad6884SPeter Tyser .endm 41184ad6884SPeter Tyser 41284ad6884SPeter Tyser .macro get_irq_stack @ setup IRQ stack 41384ad6884SPeter Tyser ldr sp, IRQ_STACK_START 41484ad6884SPeter Tyser .endm 41584ad6884SPeter Tyser 41684ad6884SPeter Tyser .macro get_fiq_stack @ setup FIQ stack 41784ad6884SPeter Tyser ldr sp, FIQ_STACK_START 41884ad6884SPeter Tyser .endm 41984ad6884SPeter Tyser 42084ad6884SPeter Tyser/* 42184ad6884SPeter Tyser * exception handlers 42284ad6884SPeter Tyser */ 42384ad6884SPeter Tyser .align 5 42484ad6884SPeter Tyserundefined_instruction: 42584ad6884SPeter Tyser get_bad_stack 42684ad6884SPeter Tyser bad_save_user_regs 42784ad6884SPeter Tyser bl do_undefined_instruction 42884ad6884SPeter Tyser 42984ad6884SPeter Tyser .align 5 43084ad6884SPeter Tysersoftware_interrupt: 43184ad6884SPeter Tyser get_bad_stack 43284ad6884SPeter Tyser bad_save_user_regs 43384ad6884SPeter Tyser bl do_software_interrupt 43484ad6884SPeter Tyser 43584ad6884SPeter Tyser .align 5 43684ad6884SPeter Tyserprefetch_abort: 43784ad6884SPeter Tyser get_bad_stack 43884ad6884SPeter Tyser bad_save_user_regs 43984ad6884SPeter Tyser bl do_prefetch_abort 44084ad6884SPeter Tyser 44184ad6884SPeter Tyser .align 5 44284ad6884SPeter Tyserdata_abort: 44384ad6884SPeter Tyser get_bad_stack 44484ad6884SPeter Tyser bad_save_user_regs 44584ad6884SPeter Tyser bl do_data_abort 44684ad6884SPeter Tyser 44784ad6884SPeter Tyser .align 5 44884ad6884SPeter Tysernot_used: 44984ad6884SPeter Tyser get_bad_stack 45084ad6884SPeter Tyser bad_save_user_regs 45184ad6884SPeter Tyser bl do_not_used 45284ad6884SPeter Tyser 45384ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ 45484ad6884SPeter Tyser 45584ad6884SPeter Tyser .align 5 45684ad6884SPeter Tyserirq: 45784ad6884SPeter Tyser get_irq_stack 45884ad6884SPeter Tyser irq_save_user_regs 45984ad6884SPeter Tyser bl do_irq 46084ad6884SPeter Tyser irq_restore_user_regs 46184ad6884SPeter Tyser 46284ad6884SPeter Tyser .align 5 46384ad6884SPeter Tyserfiq: 46484ad6884SPeter Tyser get_fiq_stack 46584ad6884SPeter Tyser /* someone ought to write a more effiction fiq_save_user_regs */ 46684ad6884SPeter Tyser irq_save_user_regs 46784ad6884SPeter Tyser bl do_fiq 46884ad6884SPeter Tyser irq_restore_user_regs 46984ad6884SPeter Tyser 47084ad6884SPeter Tyser#else 47184ad6884SPeter Tyser 47284ad6884SPeter Tyser .align 5 47384ad6884SPeter Tyserirq: 47484ad6884SPeter Tyser get_bad_stack 47584ad6884SPeter Tyser bad_save_user_regs 47684ad6884SPeter Tyser bl do_irq 47784ad6884SPeter Tyser 47884ad6884SPeter Tyser .align 5 47984ad6884SPeter Tyserfiq: 48084ad6884SPeter Tyser get_bad_stack 48184ad6884SPeter Tyser bad_save_user_regs 48284ad6884SPeter Tyser bl do_fiq 48384ad6884SPeter Tyser 48484ad6884SPeter Tyser#endif 48584ad6884SPeter Tyser 48684ad6884SPeter Tyser .align 5 48784ad6884SPeter Tyser.globl reset_cpu 48884ad6884SPeter Tyserreset_cpu: 48984ad6884SPeter Tyser ldr r0, RST_BASE 49084ad6884SPeter Tyser mov r1, #0x0 @ set bit 3-0 ... 49184ad6884SPeter Tyser str r1, [r0, #RCSR] @ ... to clear in RCSR 49284ad6884SPeter Tyser mov r1, #0x1 49384ad6884SPeter Tyser str r1, [r0, #RSRR] @ and perform reset 49484ad6884SPeter Tyser b reset_cpu @ silly, but repeat endlessly 495