184ad6884SPeter Tyser/* 2*678e008cSCyril Chemparathy * armboot - Startup Code for ARM1176 CPU-core 384ad6884SPeter Tyser * 484ad6884SPeter Tyser * Copyright (c) 2007 Samsung Electronics 584ad6884SPeter Tyser * 684ad6884SPeter Tyser * Copyright (C) 2008 784ad6884SPeter Tyser * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.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 * 2007-09-21 - Restructured codes by jsgood (jsgood.yang@samsung.com) 2884ad6884SPeter Tyser * 2007-09-21 - Added MoviNAND and OneNAND boot codes by 2984ad6884SPeter Tyser * jsgood (jsgood.yang@samsung.com) 3084ad6884SPeter Tyser * Base codes by scsuh (sc.suh) 3184ad6884SPeter Tyser */ 3284ad6884SPeter Tyser 3384ad6884SPeter Tyser#include <config.h> 3484ad6884SPeter Tyser#include <version.h> 3584ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU 3684ad6884SPeter Tyser#include <asm/proc/domain.h> 3784ad6884SPeter Tyser#endif 3884ad6884SPeter Tyser 3984ad6884SPeter Tyser#if !defined(CONFIG_ENABLE_MMU) && !defined(CONFIG_SYS_PHY_UBOOT_BASE) 4084ad6884SPeter Tyser#define CONFIG_SYS_PHY_UBOOT_BASE CONFIG_SYS_UBOOT_BASE 4184ad6884SPeter Tyser#endif 4284ad6884SPeter Tyser 4384ad6884SPeter Tyser/* 4484ad6884SPeter Tyser ************************************************************************* 4584ad6884SPeter Tyser * 4684ad6884SPeter Tyser * Jump vector table as in table 3.1 in [1] 4784ad6884SPeter Tyser * 4884ad6884SPeter Tyser ************************************************************************* 4984ad6884SPeter Tyser */ 5084ad6884SPeter Tyser 5184ad6884SPeter Tyser.globl _start 5284ad6884SPeter Tyser_start: b reset 5384ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL 5484ad6884SPeter Tyser ldr pc, _undefined_instruction 5584ad6884SPeter Tyser ldr pc, _software_interrupt 5684ad6884SPeter Tyser ldr pc, _prefetch_abort 5784ad6884SPeter Tyser ldr pc, _data_abort 5884ad6884SPeter Tyser ldr pc, _not_used 5984ad6884SPeter Tyser ldr pc, _irq 6084ad6884SPeter Tyser ldr pc, _fiq 6184ad6884SPeter Tyser 6284ad6884SPeter Tyser_undefined_instruction: 6384ad6884SPeter Tyser .word undefined_instruction 6484ad6884SPeter Tyser_software_interrupt: 6584ad6884SPeter Tyser .word software_interrupt 6684ad6884SPeter Tyser_prefetch_abort: 6784ad6884SPeter Tyser .word prefetch_abort 6884ad6884SPeter Tyser_data_abort: 6984ad6884SPeter Tyser .word data_abort 7084ad6884SPeter Tyser_not_used: 7184ad6884SPeter Tyser .word not_used 7284ad6884SPeter Tyser_irq: 7384ad6884SPeter Tyser .word irq 7484ad6884SPeter Tyser_fiq: 7584ad6884SPeter Tyser .word fiq 7684ad6884SPeter Tyser_pad: 7784ad6884SPeter Tyser .word 0x12345678 /* now 16*4=64 */ 7884ad6884SPeter Tyser#else 7984ad6884SPeter Tyser . = _start + 64 8084ad6884SPeter Tyser#endif 8184ad6884SPeter Tyser 8284ad6884SPeter Tyser.global _end_vect 8384ad6884SPeter Tyser_end_vect: 8484ad6884SPeter Tyser .balignl 16,0xdeadbeef 8584ad6884SPeter Tyser/* 8684ad6884SPeter Tyser ************************************************************************* 8784ad6884SPeter Tyser * 8884ad6884SPeter Tyser * Startup Code (reset vector) 8984ad6884SPeter Tyser * 9084ad6884SPeter Tyser * do important init only if we don't start from memory! 9184ad6884SPeter Tyser * setup Memory and board specific bits prior to relocation. 9284ad6884SPeter Tyser * relocate armboot to ram 9384ad6884SPeter Tyser * setup stack 9484ad6884SPeter Tyser * 9584ad6884SPeter Tyser ************************************************************************* 9684ad6884SPeter Tyser */ 9784ad6884SPeter Tyser 9884ad6884SPeter Tyser_TEXT_BASE: 9984ad6884SPeter Tyser .word TEXT_BASE 10084ad6884SPeter Tyser 10184ad6884SPeter Tyser/* 10284ad6884SPeter Tyser * Below variable is very important because we use MMU in U-Boot. 10384ad6884SPeter Tyser * Without it, we cannot run code correctly before MMU is ON. 10484ad6884SPeter Tyser * by scsuh. 10584ad6884SPeter Tyser */ 10684ad6884SPeter Tyser_TEXT_PHY_BASE: 10784ad6884SPeter Tyser .word CONFIG_SYS_PHY_UBOOT_BASE 10884ad6884SPeter Tyser 10984ad6884SPeter Tyser.globl _armboot_start 11084ad6884SPeter Tyser_armboot_start: 11184ad6884SPeter Tyser .word _start 11284ad6884SPeter Tyser 11384ad6884SPeter Tyser/* 11484ad6884SPeter Tyser * These are defined in the board-specific linker script. 11584ad6884SPeter Tyser */ 11684ad6884SPeter Tyser.globl _bss_start 11784ad6884SPeter Tyser_bss_start: 11884ad6884SPeter Tyser .word __bss_start 11984ad6884SPeter Tyser 12084ad6884SPeter Tyser.globl _bss_end 12184ad6884SPeter Tyser_bss_end: 12284ad6884SPeter Tyser .word _end 12384ad6884SPeter Tyser 12484ad6884SPeter Tyser/* 12584ad6884SPeter Tyser * the actual reset code 12684ad6884SPeter Tyser */ 12784ad6884SPeter Tyser 12884ad6884SPeter Tyserreset: 12984ad6884SPeter Tyser /* 13084ad6884SPeter Tyser * set the cpu to SVC32 mode 13184ad6884SPeter Tyser */ 13284ad6884SPeter Tyser mrs r0, cpsr 13384ad6884SPeter Tyser bic r0, r0, #0x3f 13484ad6884SPeter Tyser orr r0, r0, #0xd3 13584ad6884SPeter Tyser msr cpsr, r0 13684ad6884SPeter Tyser 13784ad6884SPeter Tyser/* 13884ad6884SPeter Tyser ************************************************************************* 13984ad6884SPeter Tyser * 14084ad6884SPeter Tyser * CPU_init_critical registers 14184ad6884SPeter Tyser * 14284ad6884SPeter Tyser * setup important registers 14384ad6884SPeter Tyser * setup memory timing 14484ad6884SPeter Tyser * 14584ad6884SPeter Tyser ************************************************************************* 14684ad6884SPeter Tyser */ 14784ad6884SPeter Tyser /* 14884ad6884SPeter Tyser * we do sys-critical inits only at reboot, 14984ad6884SPeter Tyser * not when booting from ram! 15084ad6884SPeter Tyser */ 15184ad6884SPeter Tysercpu_init_crit: 15284ad6884SPeter Tyser /* 15384ad6884SPeter Tyser * When booting from NAND - it has definitely been a reset, so, no need 15484ad6884SPeter Tyser * to flush caches and disable the MMU 15584ad6884SPeter Tyser */ 15684ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL 15784ad6884SPeter Tyser /* 15884ad6884SPeter Tyser * flush v4 I/D caches 15984ad6884SPeter Tyser */ 16084ad6884SPeter Tyser mov r0, #0 16184ad6884SPeter Tyser mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */ 16284ad6884SPeter Tyser mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ 16384ad6884SPeter Tyser 16484ad6884SPeter Tyser /* 16584ad6884SPeter Tyser * disable MMU stuff and caches 16684ad6884SPeter Tyser */ 16784ad6884SPeter Tyser mrc p15, 0, r0, c1, c0, 0 16884ad6884SPeter Tyser bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) 16984ad6884SPeter Tyser bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) 17084ad6884SPeter Tyser orr r0, r0, #0x00000002 @ set bit 2 (A) Align 17184ad6884SPeter Tyser orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache 172*678e008cSCyril Chemparathy 17384ad6884SPeter Tyser /* Prepare to disable the MMU */ 174*678e008cSCyril Chemparathy adr r2, mmu_disable_phys 175*678e008cSCyril Chemparathy sub r2, r2, #(CONFIG_SYS_PHY_UBOOT_BASE - TEXT_BASE) 17684ad6884SPeter Tyser b mmu_disable 17784ad6884SPeter Tyser 17884ad6884SPeter Tyser .align 5 17984ad6884SPeter Tyser /* Run in a single cache-line */ 18084ad6884SPeter Tysermmu_disable: 18184ad6884SPeter Tyser mcr p15, 0, r0, c1, c0, 0 18284ad6884SPeter Tyser nop 18384ad6884SPeter Tyser nop 18484ad6884SPeter Tyser mov pc, r2 185*678e008cSCyril Chemparathymmu_disable_phys: 186*678e008cSCyril Chemparathy 187*678e008cSCyril Chemparathy#ifdef CONFIG_DISABLE_TCM 188*678e008cSCyril Chemparathy /* 189*678e008cSCyril Chemparathy * Disable the TCMs 190*678e008cSCyril Chemparathy */ 191*678e008cSCyril Chemparathy mrc p15, 0, r0, c0, c0, 2 /* Return TCM details */ 192*678e008cSCyril Chemparathy cmp r0, #0 193*678e008cSCyril Chemparathy beq skip_tcmdisable 194*678e008cSCyril Chemparathy mov r1, #0 195*678e008cSCyril Chemparathy mov r2, #1 196*678e008cSCyril Chemparathy tst r0, r2 197*678e008cSCyril Chemparathy mcrne p15, 0, r1, c9, c1, 1 /* Disable Instruction TCM if present*/ 198*678e008cSCyril Chemparathy tst r0, r2, LSL #16 199*678e008cSCyril Chemparathy mcrne p15, 0, r1, c9, c1, 0 /* Disable Data TCM if present*/ 200*678e008cSCyril Chemparathyskip_tcmdisable: 201*678e008cSCyril Chemparathy#endif 20284ad6884SPeter Tyser#endif 20384ad6884SPeter Tyser 204*678e008cSCyril Chemparathy#ifdef CONFIG_PERIPORT_REMAP 20584ad6884SPeter Tyser /* Peri port setup */ 206*678e008cSCyril Chemparathy ldr r0, =CONFIG_PERIPORT_BASE 207*678e008cSCyril Chemparathy orr r0, r0, #CONFIG_PERIPORT_SIZE 208*678e008cSCyril Chemparathy mcr p15,0,r0,c15,c2,4 20984ad6884SPeter Tyser#endif 21084ad6884SPeter Tyser 21184ad6884SPeter Tyser /* 21284ad6884SPeter Tyser * Go setup Memory and board specific bits prior to relocation. 21384ad6884SPeter Tyser */ 21484ad6884SPeter Tyser bl lowlevel_init /* go setup pll,mux,memory */ 21584ad6884SPeter Tyser 216*678e008cSCyril Chemparathy#ifndef CONFIG_SKIP_RELOCATE_UBOOT 217*678e008cSCyril Chemparathyrelocate: /* relocate U-Boot to RAM */ 218*678e008cSCyril Chemparathy adr r0, _start /* r0 <- current position of code */ 219*678e008cSCyril Chemparathy ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ 220*678e008cSCyril Chemparathy cmp r0, r1 /* don't reloc during debug */ 221*678e008cSCyril Chemparathy beq stack_setup 222*678e008cSCyril Chemparathy 223*678e008cSCyril Chemparathy ldr r2, _armboot_start 224*678e008cSCyril Chemparathy ldr r3, _bss_start 225*678e008cSCyril Chemparathy sub r2, r3, r2 /* r2 <- size of armboot */ 226*678e008cSCyril Chemparathy add r2, r0, r2 /* r2 <- source end address */ 227*678e008cSCyril Chemparathy 228*678e008cSCyril Chemparathycopy_loop: 229*678e008cSCyril Chemparathy ldmia r0!, {r3-r10} /* copy from source address [r0] */ 230*678e008cSCyril Chemparathy stmia r1!, {r3-r10} /* copy to target address [r1] */ 231*678e008cSCyril Chemparathy cmp r0, r2 /* until source end addreee [r2] */ 232*678e008cSCyril Chemparathy ble copy_loop 233*678e008cSCyril Chemparathy#endif /* CONFIG_SKIP_RELOCATE_UBOOT */ 234*678e008cSCyril Chemparathy 23584ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU 23684ad6884SPeter Tyserenable_mmu: 23784ad6884SPeter Tyser /* enable domain access */ 23884ad6884SPeter Tyser ldr r5, =0x0000ffff 23984ad6884SPeter Tyser mcr p15, 0, r5, c3, c0, 0 /* load domain access register */ 24084ad6884SPeter Tyser 24184ad6884SPeter Tyser /* Set the TTB register */ 24284ad6884SPeter Tyser ldr r0, _mmu_table_base 24384ad6884SPeter Tyser ldr r1, =CONFIG_SYS_PHY_UBOOT_BASE 24484ad6884SPeter Tyser ldr r2, =0xfff00000 24584ad6884SPeter Tyser bic r0, r0, r2 24684ad6884SPeter Tyser orr r1, r0, r1 24784ad6884SPeter Tyser mcr p15, 0, r1, c2, c0, 0 24884ad6884SPeter Tyser 24984ad6884SPeter Tyser /* Enable the MMU */ 25084ad6884SPeter Tyser mrc p15, 0, r0, c1, c0, 0 25184ad6884SPeter Tyser orr r0, r0, #1 /* Set CR_M to enable MMU */ 25284ad6884SPeter Tyser 25384ad6884SPeter Tyser /* Prepare to enable the MMU */ 25484ad6884SPeter Tyser adr r1, skip_hw_init 25584ad6884SPeter Tyser and r1, r1, #0x3fc 25684ad6884SPeter Tyser ldr r2, _TEXT_BASE 25784ad6884SPeter Tyser ldr r3, =0xfff00000 25884ad6884SPeter Tyser and r2, r2, r3 25984ad6884SPeter Tyser orr r2, r2, r1 26084ad6884SPeter Tyser b mmu_enable 26184ad6884SPeter Tyser 26284ad6884SPeter Tyser .align 5 26384ad6884SPeter Tyser /* Run in a single cache-line */ 26484ad6884SPeter Tysermmu_enable: 26584ad6884SPeter Tyser 26684ad6884SPeter Tyser mcr p15, 0, r0, c1, c0, 0 26784ad6884SPeter Tyser nop 26884ad6884SPeter Tyser nop 26984ad6884SPeter Tyser mov pc, r2 270*678e008cSCyril Chemparathyskip_hw_init: 27184ad6884SPeter Tyser#endif 27284ad6884SPeter Tyser 27384ad6884SPeter Tyser /* Set up the stack */ 27484ad6884SPeter Tyserstack_setup: 27584ad6884SPeter Tyser ldr r0, =CONFIG_SYS_UBOOT_BASE /* base of copy in DRAM */ 27684ad6884SPeter Tyser sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ 27784ad6884SPeter Tyser sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ 27884ad6884SPeter Tyser sub sp, r0, #12 /* leave 3 words for abort-stack */ 27984ad6884SPeter Tyser 28084ad6884SPeter Tyserclear_bss: 28184ad6884SPeter Tyser ldr r0, _bss_start /* find start of bss segment */ 28284ad6884SPeter Tyser ldr r1, _bss_end /* stop here */ 28384ad6884SPeter Tyser mov r2, #0 /* clear */ 28484ad6884SPeter Tyser 28584ad6884SPeter Tyserclbss_l: 28684ad6884SPeter Tyser str r2, [r0] /* clear loop... */ 28784ad6884SPeter Tyser add r0, r0, #4 28884ad6884SPeter Tyser cmp r0, r1 28984ad6884SPeter Tyser ble clbss_l 29084ad6884SPeter Tyser 29184ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL 29284ad6884SPeter Tyser ldr pc, _start_armboot 29384ad6884SPeter Tyser 29484ad6884SPeter Tyser_start_armboot: 29584ad6884SPeter Tyser .word start_armboot 29684ad6884SPeter Tyser#else 29784ad6884SPeter Tyser b nand_boot 29884ad6884SPeter Tyser/* .word nand_boot*/ 29984ad6884SPeter Tyser#endif 30084ad6884SPeter Tyser 30184ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU 30284ad6884SPeter Tyser_mmu_table_base: 30384ad6884SPeter Tyser .word mmu_table 30484ad6884SPeter Tyser#endif 30584ad6884SPeter Tyser 30684ad6884SPeter Tyser#ifndef CONFIG_NAND_SPL 30784ad6884SPeter Tyser/* 30884ad6884SPeter Tyser * we assume that cache operation is done before. (eg. cleanup_before_linux()) 30984ad6884SPeter Tyser * actually, we don't need to do anything about cache if not use d-cache in 31084ad6884SPeter Tyser * U-Boot. So, in this function we clean only MMU. by scsuh 31184ad6884SPeter Tyser * 31284ad6884SPeter Tyser * void theLastJump(void *kernel, int arch_num, uint boot_params); 31384ad6884SPeter Tyser */ 31484ad6884SPeter Tyser#ifdef CONFIG_ENABLE_MMU 31584ad6884SPeter Tyser .globl theLastJump 31684ad6884SPeter TysertheLastJump: 31784ad6884SPeter Tyser mov r9, r0 31884ad6884SPeter Tyser ldr r3, =0xfff00000 31984ad6884SPeter Tyser ldr r4, _TEXT_PHY_BASE 32084ad6884SPeter Tyser adr r5, phy_last_jump 32184ad6884SPeter Tyser bic r5, r5, r3 32284ad6884SPeter Tyser orr r5, r5, r4 32384ad6884SPeter Tyser mov pc, r5 32484ad6884SPeter Tyserphy_last_jump: 32584ad6884SPeter Tyser /* 32684ad6884SPeter Tyser * disable MMU stuff 32784ad6884SPeter Tyser */ 32884ad6884SPeter Tyser mrc p15, 0, r0, c1, c0, 0 32984ad6884SPeter Tyser bic r0, r0, #0x00002300 /* clear bits 13, 9:8 (--V- --RS) */ 33084ad6884SPeter Tyser bic r0, r0, #0x00000087 /* clear bits 7, 2:0 (B--- -CAM) */ 33184ad6884SPeter Tyser orr r0, r0, #0x00000002 /* set bit 2 (A) Align */ 33284ad6884SPeter Tyser orr r0, r0, #0x00001000 /* set bit 12 (I) I-Cache */ 33384ad6884SPeter Tyser mcr p15, 0, r0, c1, c0, 0 33484ad6884SPeter Tyser 33584ad6884SPeter Tyser mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */ 33684ad6884SPeter Tyser 33784ad6884SPeter Tyser mov r0, #0 33884ad6884SPeter Tyser mov pc, r9 33984ad6884SPeter Tyser#endif 340*678e008cSCyril Chemparathy 341*678e008cSCyril Chemparathy 34284ad6884SPeter Tyser/* 34384ad6884SPeter Tyser ************************************************************************* 34484ad6884SPeter Tyser * 34584ad6884SPeter Tyser * Interrupt handling 34684ad6884SPeter Tyser * 34784ad6884SPeter Tyser ************************************************************************* 34884ad6884SPeter Tyser */ 34984ad6884SPeter Tyser@ 35084ad6884SPeter Tyser@ IRQ stack frame. 35184ad6884SPeter Tyser@ 35284ad6884SPeter Tyser#define S_FRAME_SIZE 72 35384ad6884SPeter Tyser 35484ad6884SPeter Tyser#define S_OLD_R0 68 35584ad6884SPeter Tyser#define S_PSR 64 35684ad6884SPeter Tyser#define S_PC 60 35784ad6884SPeter Tyser#define S_LR 56 35884ad6884SPeter Tyser#define S_SP 52 35984ad6884SPeter Tyser 36084ad6884SPeter Tyser#define S_IP 48 36184ad6884SPeter Tyser#define S_FP 44 36284ad6884SPeter Tyser#define S_R10 40 36384ad6884SPeter Tyser#define S_R9 36 36484ad6884SPeter Tyser#define S_R8 32 36584ad6884SPeter Tyser#define S_R7 28 36684ad6884SPeter Tyser#define S_R6 24 36784ad6884SPeter Tyser#define S_R5 20 36884ad6884SPeter Tyser#define S_R4 16 36984ad6884SPeter Tyser#define S_R3 12 37084ad6884SPeter Tyser#define S_R2 8 37184ad6884SPeter Tyser#define S_R1 4 37284ad6884SPeter Tyser#define S_R0 0 37384ad6884SPeter Tyser 37484ad6884SPeter Tyser#define MODE_SVC 0x13 37584ad6884SPeter Tyser#define I_BIT 0x80 37684ad6884SPeter Tyser 37784ad6884SPeter Tyser/* 37884ad6884SPeter Tyser * use bad_save_user_regs for abort/prefetch/undef/swi ... 37984ad6884SPeter Tyser */ 38084ad6884SPeter Tyser 38184ad6884SPeter Tyser .macro bad_save_user_regs 38284ad6884SPeter Tyser /* carve out a frame on current user stack */ 38384ad6884SPeter Tyser sub sp, sp, #S_FRAME_SIZE 38484ad6884SPeter Tyser /* Save user registers (now in svc mode) r0-r12 */ 38584ad6884SPeter Tyser stmia sp, {r0 - r12} 38684ad6884SPeter Tyser 38784ad6884SPeter Tyser ldr r2, _armboot_start 38884ad6884SPeter Tyser sub r2, r2, #(CONFIG_SYS_MALLOC_LEN) 38984ad6884SPeter Tyser /* set base 2 words into abort stack */ 39084ad6884SPeter Tyser sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) 39184ad6884SPeter Tyser /* get values for "aborted" pc and cpsr (into parm regs) */ 39284ad6884SPeter Tyser ldmia r2, {r2 - r3} 39384ad6884SPeter Tyser /* grab pointer to old stack */ 39484ad6884SPeter Tyser add r0, sp, #S_FRAME_SIZE 39584ad6884SPeter Tyser 39684ad6884SPeter Tyser add r5, sp, #S_SP 39784ad6884SPeter Tyser mov r1, lr 39884ad6884SPeter Tyser /* save sp_SVC, lr_SVC, pc, cpsr */ 39984ad6884SPeter Tyser stmia r5, {r0 - r3} 40084ad6884SPeter Tyser /* save current stack into r0 (param register) */ 40184ad6884SPeter Tyser mov r0, sp 40284ad6884SPeter Tyser .endm 40384ad6884SPeter Tyser 40484ad6884SPeter Tyser .macro get_bad_stack 40584ad6884SPeter Tyser /* setup our mode stack (enter in banked mode) */ 40684ad6884SPeter Tyser ldr r13, _armboot_start 40784ad6884SPeter Tyser /* move past malloc pool */ 40884ad6884SPeter Tyser sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) 40984ad6884SPeter Tyser /* move to reserved a couple spots for abort stack */ 41084ad6884SPeter Tyser sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE + 8) 41184ad6884SPeter Tyser 41284ad6884SPeter Tyser /* save caller lr in position 0 of saved stack */ 41384ad6884SPeter Tyser str lr, [r13] 41484ad6884SPeter Tyser /* get the spsr */ 41584ad6884SPeter Tyser mrs lr, spsr 41684ad6884SPeter Tyser /* save spsr in position 1 of saved stack */ 41784ad6884SPeter Tyser str lr, [r13, #4] 41884ad6884SPeter Tyser 41984ad6884SPeter Tyser /* prepare SVC-Mode */ 42084ad6884SPeter Tyser mov r13, #MODE_SVC 42184ad6884SPeter Tyser @ msr spsr_c, r13 42284ad6884SPeter Tyser /* switch modes, make sure moves will execute */ 42384ad6884SPeter Tyser msr spsr, r13 42484ad6884SPeter Tyser /* capture return pc */ 42584ad6884SPeter Tyser mov lr, pc 42684ad6884SPeter Tyser /* jump to next instruction & switch modes. */ 42784ad6884SPeter Tyser movs pc, lr 42884ad6884SPeter Tyser .endm 42984ad6884SPeter Tyser 43084ad6884SPeter Tyser .macro get_bad_stack_swi 43184ad6884SPeter Tyser /* space on current stack for scratch reg. */ 43284ad6884SPeter Tyser sub r13, r13, #4 43384ad6884SPeter Tyser /* save R0's value. */ 43484ad6884SPeter Tyser str r0, [r13] 43584ad6884SPeter Tyser /* get data regions start */ 43684ad6884SPeter Tyser ldr r0, _armboot_start 43784ad6884SPeter Tyser /* move past malloc pool */ 43884ad6884SPeter Tyser sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) 43984ad6884SPeter Tyser /* move past gbl and a couple spots for abort stack */ 44084ad6884SPeter Tyser sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE + 8) 44184ad6884SPeter Tyser /* save caller lr in position 0 of saved stack */ 44284ad6884SPeter Tyser str lr, [r0] 44384ad6884SPeter Tyser /* get the spsr */ 44484ad6884SPeter Tyser mrs r0, spsr 44584ad6884SPeter Tyser /* save spsr in position 1 of saved stack */ 44684ad6884SPeter Tyser str lr, [r0, #4] 44784ad6884SPeter Tyser /* restore r0 */ 44884ad6884SPeter Tyser ldr r0, [r13] 44984ad6884SPeter Tyser /* pop stack entry */ 45084ad6884SPeter Tyser add r13, r13, #4 45184ad6884SPeter Tyser .endm 45284ad6884SPeter Tyser 45384ad6884SPeter Tyser/* 45484ad6884SPeter Tyser * exception handlers 45584ad6884SPeter Tyser */ 45684ad6884SPeter Tyser .align 5 45784ad6884SPeter Tyserundefined_instruction: 45884ad6884SPeter Tyser get_bad_stack 45984ad6884SPeter Tyser bad_save_user_regs 46084ad6884SPeter Tyser bl do_undefined_instruction 46184ad6884SPeter Tyser 46284ad6884SPeter Tyser .align 5 46384ad6884SPeter Tysersoftware_interrupt: 46484ad6884SPeter Tyser get_bad_stack_swi 46584ad6884SPeter Tyser bad_save_user_regs 46684ad6884SPeter Tyser bl do_software_interrupt 46784ad6884SPeter Tyser 46884ad6884SPeter Tyser .align 5 46984ad6884SPeter Tyserprefetch_abort: 47084ad6884SPeter Tyser get_bad_stack 47184ad6884SPeter Tyser bad_save_user_regs 47284ad6884SPeter Tyser bl do_prefetch_abort 47384ad6884SPeter Tyser 47484ad6884SPeter Tyser .align 5 47584ad6884SPeter Tyserdata_abort: 47684ad6884SPeter Tyser get_bad_stack 47784ad6884SPeter Tyser bad_save_user_regs 47884ad6884SPeter Tyser bl do_data_abort 47984ad6884SPeter Tyser 48084ad6884SPeter Tyser .align 5 48184ad6884SPeter Tysernot_used: 48284ad6884SPeter Tyser get_bad_stack 48384ad6884SPeter Tyser bad_save_user_regs 48484ad6884SPeter Tyser bl do_not_used 48584ad6884SPeter Tyser 48684ad6884SPeter Tyser .align 5 48784ad6884SPeter Tyserirq: 48884ad6884SPeter Tyser get_bad_stack 48984ad6884SPeter Tyser bad_save_user_regs 49084ad6884SPeter Tyser bl do_irq 49184ad6884SPeter Tyser 49284ad6884SPeter Tyser .align 5 49384ad6884SPeter Tyserfiq: 49484ad6884SPeter Tyser get_bad_stack 49584ad6884SPeter Tyser bad_save_user_regs 49684ad6884SPeter Tyser bl do_fiq 49784ad6884SPeter Tyser#endif /* CONFIG_NAND_SPL */ 498