1*84ad6884SPeter Tyser/* 2*84ad6884SPeter Tyser * armboot - Startup Code for XScale 3*84ad6884SPeter Tyser * 4*84ad6884SPeter Tyser * Copyright (C) 1998 Dan Malek <dmalek@jlc.net> 5*84ad6884SPeter Tyser * Copyright (C) 1999 Magnus Damm <kieraypc01.p.y.kie.era.ericsson.se> 6*84ad6884SPeter Tyser * Copyright (C) 2000 Wolfgang Denk <wd@denx.de> 7*84ad6884SPeter Tyser * Copyright (C) 2001 Alex Zuepke <azu@sysgo.de> 8*84ad6884SPeter Tyser * Copyright (C) 2002 Kyle Harris <kharris@nexus-tech.net> 9*84ad6884SPeter Tyser * Copyright (C) 2003 Robert Schwebel <r.schwebel@pengutronix.de> 10*84ad6884SPeter Tyser * Copyright (C) 2003 Kai-Uwe Bloem <kai-uwe.bloem@auerswald.de> 11*84ad6884SPeter Tyser * 12*84ad6884SPeter Tyser * See file CREDITS for list of people who contributed to this 13*84ad6884SPeter Tyser * project. 14*84ad6884SPeter Tyser * 15*84ad6884SPeter Tyser * This program is free software; you can redistribute it and/or 16*84ad6884SPeter Tyser * modify it under the terms of the GNU General Public License as 17*84ad6884SPeter Tyser * published by the Free Software Foundation; either version 2 of 18*84ad6884SPeter Tyser * the License, or (at your option) any later version. 19*84ad6884SPeter Tyser * 20*84ad6884SPeter Tyser * This program is distributed in the hope that it will be useful, 21*84ad6884SPeter Tyser * but WITHOUT ANY WARRANTY; without even the implied warranty of 22*84ad6884SPeter Tyser * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23*84ad6884SPeter Tyser * GNU General Public License for more details. 24*84ad6884SPeter Tyser * 25*84ad6884SPeter Tyser * You should have received a copy of the GNU General Public License 26*84ad6884SPeter Tyser * along with this program; if not, write to the Free Software 27*84ad6884SPeter Tyser * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 28*84ad6884SPeter Tyser * MA 02111-1307 USA 29*84ad6884SPeter Tyser */ 30*84ad6884SPeter Tyser 31*84ad6884SPeter Tyser#include <config.h> 32*84ad6884SPeter Tyser#include <version.h> 33*84ad6884SPeter Tyser#include <asm/arch/pxa-regs.h> 34*84ad6884SPeter Tyser 35*84ad6884SPeter Tyser.globl _start 36*84ad6884SPeter Tyser_start: b reset 37*84ad6884SPeter Tyser ldr pc, _undefined_instruction 38*84ad6884SPeter Tyser ldr pc, _software_interrupt 39*84ad6884SPeter Tyser ldr pc, _prefetch_abort 40*84ad6884SPeter Tyser ldr pc, _data_abort 41*84ad6884SPeter Tyser ldr pc, _not_used 42*84ad6884SPeter Tyser ldr pc, _irq 43*84ad6884SPeter Tyser ldr pc, _fiq 44*84ad6884SPeter Tyser 45*84ad6884SPeter Tyser_undefined_instruction: .word undefined_instruction 46*84ad6884SPeter Tyser_software_interrupt: .word software_interrupt 47*84ad6884SPeter Tyser_prefetch_abort: .word prefetch_abort 48*84ad6884SPeter Tyser_data_abort: .word data_abort 49*84ad6884SPeter Tyser_not_used: .word not_used 50*84ad6884SPeter Tyser_irq: .word irq 51*84ad6884SPeter Tyser_fiq: .word fiq 52*84ad6884SPeter Tyser 53*84ad6884SPeter Tyser .balignl 16,0xdeadbeef 54*84ad6884SPeter Tyser 55*84ad6884SPeter Tyser 56*84ad6884SPeter Tyser/* 57*84ad6884SPeter Tyser * Startup Code (reset vector) 58*84ad6884SPeter Tyser * 59*84ad6884SPeter Tyser * do important init only if we don't start from RAM! 60*84ad6884SPeter Tyser * - relocate armboot to RAM 61*84ad6884SPeter Tyser * - setup stack 62*84ad6884SPeter Tyser * - jump to second stage 63*84ad6884SPeter Tyser */ 64*84ad6884SPeter Tyser 65*84ad6884SPeter Tyser_TEXT_BASE: 66*84ad6884SPeter Tyser .word TEXT_BASE 67*84ad6884SPeter Tyser 68*84ad6884SPeter Tyser.globl _armboot_start 69*84ad6884SPeter Tyser_armboot_start: 70*84ad6884SPeter Tyser .word _start 71*84ad6884SPeter Tyser 72*84ad6884SPeter Tyser/* 73*84ad6884SPeter Tyser * These are defined in the board-specific linker script. 74*84ad6884SPeter Tyser */ 75*84ad6884SPeter Tyser.globl _bss_start 76*84ad6884SPeter Tyser_bss_start: 77*84ad6884SPeter Tyser .word __bss_start 78*84ad6884SPeter Tyser 79*84ad6884SPeter Tyser.globl _bss_end 80*84ad6884SPeter Tyser_bss_end: 81*84ad6884SPeter Tyser .word _end 82*84ad6884SPeter Tyser 83*84ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ 84*84ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */ 85*84ad6884SPeter Tyser.globl IRQ_STACK_START 86*84ad6884SPeter TyserIRQ_STACK_START: 87*84ad6884SPeter Tyser .word 0x0badc0de 88*84ad6884SPeter Tyser 89*84ad6884SPeter Tyser/* IRQ stack memory (calculated at run-time) */ 90*84ad6884SPeter Tyser.globl FIQ_STACK_START 91*84ad6884SPeter TyserFIQ_STACK_START: 92*84ad6884SPeter Tyser .word 0x0badc0de 93*84ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */ 94*84ad6884SPeter Tyser 95*84ad6884SPeter Tyser 96*84ad6884SPeter Tyser/****************************************************************************/ 97*84ad6884SPeter Tyser/* */ 98*84ad6884SPeter Tyser/* the actual reset code */ 99*84ad6884SPeter Tyser/* */ 100*84ad6884SPeter Tyser/****************************************************************************/ 101*84ad6884SPeter Tyser 102*84ad6884SPeter Tyserreset: 103*84ad6884SPeter Tyser mrs r0,cpsr /* set the CPU to SVC32 mode */ 104*84ad6884SPeter Tyser bic r0,r0,#0x1f /* (superviser mode, M=10011) */ 105*84ad6884SPeter Tyser orr r0,r0,#0x13 106*84ad6884SPeter Tyser msr cpsr,r0 107*84ad6884SPeter Tyser 108*84ad6884SPeter Tyser /* 109*84ad6884SPeter Tyser * we do sys-critical inits only at reboot, 110*84ad6884SPeter Tyser * not when booting from RAM! 111*84ad6884SPeter Tyser */ 112*84ad6884SPeter Tyser#ifndef CONFIG_SKIP_LOWLEVEL_INIT 113*84ad6884SPeter Tyser bl cpu_init_crit /* we do sys-critical inits */ 114*84ad6884SPeter Tyser#endif /* !CONFIG_SKIP_LOWLEVEL_INIT */ 115*84ad6884SPeter Tyser 116*84ad6884SPeter Tyser#ifndef CONFIG_SKIP_RELOCATE_UBOOT 117*84ad6884SPeter Tyserrelocate: /* relocate U-Boot to RAM */ 118*84ad6884SPeter Tyser adr r0, _start /* r0 <- current position of code */ 119*84ad6884SPeter Tyser ldr r1, _TEXT_BASE /* test if we run from flash or RAM */ 120*84ad6884SPeter Tyser cmp r0, r1 /* don't reloc during debug */ 121*84ad6884SPeter Tyser beq stack_setup 122*84ad6884SPeter Tyser 123*84ad6884SPeter Tyser ldr r2, _armboot_start 124*84ad6884SPeter Tyser ldr r3, _bss_start 125*84ad6884SPeter Tyser sub r2, r3, r2 /* r2 <- size of armboot */ 126*84ad6884SPeter Tyser add r2, r0, r2 /* r2 <- source end address */ 127*84ad6884SPeter Tyser 128*84ad6884SPeter Tysercopy_loop: 129*84ad6884SPeter Tyser ldmia r0!, {r3-r10} /* copy from source address [r0] */ 130*84ad6884SPeter Tyser stmia r1!, {r3-r10} /* copy to target address [r1] */ 131*84ad6884SPeter Tyser cmp r0, r2 /* until source end address [r2] */ 132*84ad6884SPeter Tyser ble copy_loop 133*84ad6884SPeter Tyser#endif /* !CONFIG_SKIP_RELOCATE_UBOOT */ 134*84ad6884SPeter Tyser 135*84ad6884SPeter Tyser /* Set up the stack */ 136*84ad6884SPeter Tyserstack_setup: 137*84ad6884SPeter Tyser ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */ 138*84ad6884SPeter Tyser sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */ 139*84ad6884SPeter Tyser sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */ 140*84ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ 141*84ad6884SPeter Tyser sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ) 142*84ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */ 1431a27f7d9SVitaly Kuzmichev sub sp, r0, #12 /* leave 3 words for abort-stack */ 1441a27f7d9SVitaly Kuzmichev bic sp, sp, #7 /* 8-byte alignment for ABI compliance */ 145*84ad6884SPeter Tyser 146*84ad6884SPeter Tyserclear_bss: 147*84ad6884SPeter Tyser ldr r0, _bss_start /* find start of bss segment */ 148*84ad6884SPeter Tyser ldr r1, _bss_end /* stop here */ 149*84ad6884SPeter Tyser mov r2, #0x00000000 /* clear */ 150*84ad6884SPeter Tyser 151*84ad6884SPeter Tyserclbss_l:str r2, [r0] /* clear loop... */ 152*84ad6884SPeter Tyser add r0, r0, #4 153*84ad6884SPeter Tyser cmp r0, r1 154*84ad6884SPeter Tyser ble clbss_l 155*84ad6884SPeter Tyser 156*84ad6884SPeter Tyser ldr pc, _start_armboot 157*84ad6884SPeter Tyser 158*84ad6884SPeter Tyser_start_armboot: .word start_armboot 159*84ad6884SPeter Tyser 160*84ad6884SPeter Tyser 161*84ad6884SPeter Tyser/****************************************************************************/ 162*84ad6884SPeter Tyser/* */ 163*84ad6884SPeter Tyser/* CPU_init_critical registers */ 164*84ad6884SPeter Tyser/* */ 165*84ad6884SPeter Tyser/* - setup important registers */ 166*84ad6884SPeter Tyser/* - setup memory timing */ 167*84ad6884SPeter Tyser/* */ 168*84ad6884SPeter Tyser/****************************************************************************/ 169*84ad6884SPeter Tyser/* mk@tbd: Fix this! */ 170*84ad6884SPeter Tyser#undef RCSR 171*84ad6884SPeter Tyser#undef ICMR 172*84ad6884SPeter Tyser#undef OSMR3 173*84ad6884SPeter Tyser#undef OSCR 174*84ad6884SPeter Tyser#undef OWER 175*84ad6884SPeter Tyser#undef OIER 176*84ad6884SPeter Tyser#undef CCCR 177*84ad6884SPeter Tyser 178*84ad6884SPeter Tyser/* Interrupt-Controller base address */ 179*84ad6884SPeter TyserIC_BASE: .word 0x40d00000 180*84ad6884SPeter Tyser#define ICMR 0x04 181*84ad6884SPeter Tyser 182*84ad6884SPeter Tyser/* Reset-Controller */ 183*84ad6884SPeter TyserRST_BASE: .word 0x40f00030 184*84ad6884SPeter Tyser#define RCSR 0x00 185*84ad6884SPeter Tyser 186*84ad6884SPeter Tyser/* Operating System Timer */ 187*84ad6884SPeter TyserOSTIMER_BASE: .word 0x40a00000 188*84ad6884SPeter Tyser#define OSMR3 0x0C 189*84ad6884SPeter Tyser#define OSCR 0x10 190*84ad6884SPeter Tyser#define OWER 0x18 191*84ad6884SPeter Tyser#define OIER 0x1C 192*84ad6884SPeter Tyser 193*84ad6884SPeter Tyser/* Clock Manager Registers */ 194*84ad6884SPeter Tyser#ifdef CONFIG_CPU_MONAHANS 195*84ad6884SPeter Tyser# ifndef CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO 196*84ad6884SPeter Tyser# error "You have to define CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO!!" 197*84ad6884SPeter Tyser# endif /* !CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO */ 198*84ad6884SPeter Tyser# ifndef CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 199*84ad6884SPeter Tyser# define CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO 0x1 200*84ad6884SPeter Tyser# endif /* !CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO */ 201*84ad6884SPeter Tyser#else /* !CONFIG_CPU_MONAHANS */ 202*84ad6884SPeter Tyser#ifdef CONFIG_SYS_CPUSPEED 203*84ad6884SPeter TyserCC_BASE: .word 0x41300000 204*84ad6884SPeter Tyser#define CCCR 0x00 205*84ad6884SPeter Tysercpuspeed: .word CONFIG_SYS_CPUSPEED 206*84ad6884SPeter Tyser#else /* !CONFIG_SYS_CPUSPEED */ 207*84ad6884SPeter Tyser#error "You have to define CONFIG_SYS_CPUSPEED!!" 208*84ad6884SPeter Tyser#endif /* CONFIG_SYS_CPUSPEED */ 209*84ad6884SPeter Tyser#endif /* CONFIG_CPU_MONAHANS */ 210*84ad6884SPeter Tyser 211*84ad6884SPeter Tyser /* takes care the CP15 update has taken place */ 212*84ad6884SPeter Tyser .macro CPWAIT reg 213*84ad6884SPeter Tyser mrc p15,0,\reg,c2,c0,0 214*84ad6884SPeter Tyser mov \reg,\reg 215*84ad6884SPeter Tyser sub pc,pc,#4 216*84ad6884SPeter Tyser .endm 217*84ad6884SPeter Tyser 218*84ad6884SPeter Tysercpu_init_crit: 219*84ad6884SPeter Tyser 220*84ad6884SPeter Tyser /* mask all IRQs */ 221*84ad6884SPeter Tyser#ifndef CONFIG_CPU_MONAHANS 222*84ad6884SPeter Tyser ldr r0, IC_BASE 223*84ad6884SPeter Tyser mov r1, #0x00 224*84ad6884SPeter Tyser str r1, [r0, #ICMR] 225*84ad6884SPeter Tyser#else /* CONFIG_CPU_MONAHANS */ 226*84ad6884SPeter Tyser /* Step 1 - Enable CP6 permission */ 227*84ad6884SPeter Tyser mrc p15, 0, r1, c15, c1, 0 @ read CPAR 228*84ad6884SPeter Tyser orr r1, r1, #0x40 229*84ad6884SPeter Tyser mcr p15, 0, r1, c15, c1, 0 230*84ad6884SPeter Tyser CPWAIT r1 231*84ad6884SPeter Tyser 232*84ad6884SPeter Tyser /* Step 2 - Mask ICMR & ICMR2 */ 233*84ad6884SPeter Tyser mov r1, #0 234*84ad6884SPeter Tyser mcr p6, 0, r1, c1, c0, 0 @ ICMR 235*84ad6884SPeter Tyser mcr p6, 0, r1, c7, c0, 0 @ ICMR2 236*84ad6884SPeter Tyser 237*84ad6884SPeter Tyser /* turn off all clocks but the ones we will definitly require */ 238*84ad6884SPeter Tyser ldr r1, =CKENA 239*84ad6884SPeter Tyser ldr r2, =(CKENA_22_FFUART | CKENA_10_SRAM | CKENA_9_SMC | CKENA_8_DMC) 240*84ad6884SPeter Tyser str r2, [r1] 241*84ad6884SPeter Tyser ldr r1, =CKENB 242*84ad6884SPeter Tyser ldr r2, =(CKENB_6_IRQ) 243*84ad6884SPeter Tyser str r2, [r1] 244*84ad6884SPeter Tyser#endif /* !CONFIG_CPU_MONAHANS */ 245*84ad6884SPeter Tyser 246*84ad6884SPeter Tyser /* set clock speed */ 247*84ad6884SPeter Tyser#ifdef CONFIG_CPU_MONAHANS 248*84ad6884SPeter Tyser ldr r0, =ACCR 249*84ad6884SPeter Tyser ldr r1, =(((CONFIG_SYS_MONAHANS_TURBO_RUN_MODE_RATIO<<8) & ACCR_XN_MASK) | (CONFIG_SYS_MONAHANS_RUN_MODE_OSC_RATIO & ACCR_XL_MASK)) 250*84ad6884SPeter Tyser str r1, [r0] 251*84ad6884SPeter Tyser#else /* !CONFIG_CPU_MONAHANS */ 252*84ad6884SPeter Tyser#ifdef CONFIG_SYS_CPUSPEED 253*84ad6884SPeter Tyser ldr r0, CC_BASE 254*84ad6884SPeter Tyser ldr r1, cpuspeed 255*84ad6884SPeter Tyser str r1, [r0, #CCCR] 256*84ad6884SPeter Tyser mov r0, #2 257*84ad6884SPeter Tyser mcr p14, 0, r0, c6, c0, 0 258*84ad6884SPeter Tyser 259*84ad6884SPeter Tysersetspeed_done: 260*84ad6884SPeter Tyser 261*84ad6884SPeter Tyser#endif /* CONFIG_SYS_CPUSPEED */ 262*84ad6884SPeter Tyser#endif /* CONFIG_CPU_MONAHANS */ 263*84ad6884SPeter Tyser 264*84ad6884SPeter Tyser /* 265*84ad6884SPeter Tyser * before relocating, we have to setup RAM timing 266*84ad6884SPeter Tyser * because memory timing is board-dependend, you will 267*84ad6884SPeter Tyser * find a lowlevel_init.S in your board directory. 268*84ad6884SPeter Tyser */ 269*84ad6884SPeter Tyser mov ip, lr 270*84ad6884SPeter Tyser bl lowlevel_init 271*84ad6884SPeter Tyser mov lr, ip 272*84ad6884SPeter Tyser 273*84ad6884SPeter Tyser /* Memory interfaces are working. Disable MMU and enable I-cache. */ 274*84ad6884SPeter Tyser /* mk: hmm, this is not in the monahans docs, leave it now but 275*84ad6884SPeter Tyser * check here if it doesn't work :-) */ 276*84ad6884SPeter Tyser 277*84ad6884SPeter Tyser ldr r0, =0x2001 /* enable access to all coproc. */ 278*84ad6884SPeter Tyser mcr p15, 0, r0, c15, c1, 0 279*84ad6884SPeter Tyser CPWAIT r0 280*84ad6884SPeter Tyser 281*84ad6884SPeter Tyser mcr p15, 0, r0, c7, c10, 4 /* drain the write & fill buffers */ 282*84ad6884SPeter Tyser CPWAIT r0 283*84ad6884SPeter Tyser 284*84ad6884SPeter Tyser mcr p15, 0, r0, c7, c7, 0 /* flush Icache, Dcache and BTB */ 285*84ad6884SPeter Tyser CPWAIT r0 286*84ad6884SPeter Tyser 287*84ad6884SPeter Tyser mcr p15, 0, r0, c8, c7, 0 /* flush instuction and data TLBs */ 288*84ad6884SPeter Tyser CPWAIT r0 289*84ad6884SPeter Tyser 290*84ad6884SPeter Tyser /* Enable the Icache */ 291*84ad6884SPeter Tyser/* 292*84ad6884SPeter Tyser mrc p15, 0, r0, c1, c0, 0 293*84ad6884SPeter Tyser orr r0, r0, #0x1800 294*84ad6884SPeter Tyser mcr p15, 0, r0, c1, c0, 0 295*84ad6884SPeter Tyser CPWAIT 296*84ad6884SPeter Tyser*/ 297*84ad6884SPeter Tyser mov pc, lr 298*84ad6884SPeter Tyser 299*84ad6884SPeter Tyser 300*84ad6884SPeter Tyser/****************************************************************************/ 301*84ad6884SPeter Tyser/* */ 302*84ad6884SPeter Tyser/* Interrupt handling */ 303*84ad6884SPeter Tyser/* */ 304*84ad6884SPeter Tyser/****************************************************************************/ 305*84ad6884SPeter Tyser 306*84ad6884SPeter Tyser/* IRQ stack frame */ 307*84ad6884SPeter Tyser 308*84ad6884SPeter Tyser#define S_FRAME_SIZE 72 309*84ad6884SPeter Tyser 310*84ad6884SPeter Tyser#define S_OLD_R0 68 311*84ad6884SPeter Tyser#define S_PSR 64 312*84ad6884SPeter Tyser#define S_PC 60 313*84ad6884SPeter Tyser#define S_LR 56 314*84ad6884SPeter Tyser#define S_SP 52 315*84ad6884SPeter Tyser 316*84ad6884SPeter Tyser#define S_IP 48 317*84ad6884SPeter Tyser#define S_FP 44 318*84ad6884SPeter Tyser#define S_R10 40 319*84ad6884SPeter Tyser#define S_R9 36 320*84ad6884SPeter Tyser#define S_R8 32 321*84ad6884SPeter Tyser#define S_R7 28 322*84ad6884SPeter Tyser#define S_R6 24 323*84ad6884SPeter Tyser#define S_R5 20 324*84ad6884SPeter Tyser#define S_R4 16 325*84ad6884SPeter Tyser#define S_R3 12 326*84ad6884SPeter Tyser#define S_R2 8 327*84ad6884SPeter Tyser#define S_R1 4 328*84ad6884SPeter Tyser#define S_R0 0 329*84ad6884SPeter Tyser 330*84ad6884SPeter Tyser#define MODE_SVC 0x13 331*84ad6884SPeter Tyser 332*84ad6884SPeter Tyser /* use bad_save_user_regs for abort/prefetch/undef/swi ... */ 333*84ad6884SPeter Tyser 334*84ad6884SPeter Tyser .macro bad_save_user_regs 335*84ad6884SPeter Tyser sub sp, sp, #S_FRAME_SIZE 336*84ad6884SPeter Tyser stmia sp, {r0 - r12} /* Calling r0-r12 */ 337*84ad6884SPeter Tyser add r8, sp, #S_PC 338*84ad6884SPeter Tyser 339*84ad6884SPeter Tyser ldr r2, _armboot_start 340*84ad6884SPeter Tyser sub r2, r2, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) 341*84ad6884SPeter Tyser sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack 342*84ad6884SPeter Tyser ldmia r2, {r2 - r4} /* get pc, cpsr, old_r0 */ 343*84ad6884SPeter Tyser add r0, sp, #S_FRAME_SIZE /* restore sp_SVC */ 344*84ad6884SPeter Tyser 345*84ad6884SPeter Tyser add r5, sp, #S_SP 346*84ad6884SPeter Tyser mov r1, lr 347*84ad6884SPeter Tyser stmia r5, {r0 - r4} /* save sp_SVC, lr_SVC, pc, cpsr, old_r */ 348*84ad6884SPeter Tyser mov r0, sp 349*84ad6884SPeter Tyser .endm 350*84ad6884SPeter Tyser 351*84ad6884SPeter Tyser 352*84ad6884SPeter Tyser /* use irq_save_user_regs / irq_restore_user_regs for */ 353*84ad6884SPeter Tyser /* IRQ/FIQ handling */ 354*84ad6884SPeter Tyser 355*84ad6884SPeter Tyser .macro irq_save_user_regs 356*84ad6884SPeter Tyser sub sp, sp, #S_FRAME_SIZE 357*84ad6884SPeter Tyser stmia sp, {r0 - r12} /* Calling r0-r12 */ 358*84ad6884SPeter Tyser add r8, sp, #S_PC 359*84ad6884SPeter Tyser stmdb r8, {sp, lr}^ /* Calling SP, LR */ 360*84ad6884SPeter Tyser str lr, [r8, #0] /* Save calling PC */ 361*84ad6884SPeter Tyser mrs r6, spsr 362*84ad6884SPeter Tyser str r6, [r8, #4] /* Save CPSR */ 363*84ad6884SPeter Tyser str r0, [r8, #8] /* Save OLD_R0 */ 364*84ad6884SPeter Tyser mov r0, sp 365*84ad6884SPeter Tyser .endm 366*84ad6884SPeter Tyser 367*84ad6884SPeter Tyser .macro irq_restore_user_regs 368*84ad6884SPeter Tyser ldmia sp, {r0 - lr}^ @ Calling r0 - lr 369*84ad6884SPeter Tyser mov r0, r0 370*84ad6884SPeter Tyser ldr lr, [sp, #S_PC] @ Get PC 371*84ad6884SPeter Tyser add sp, sp, #S_FRAME_SIZE 372*84ad6884SPeter Tyser subs pc, lr, #4 @ return & move spsr_svc into cpsr 373*84ad6884SPeter Tyser .endm 374*84ad6884SPeter Tyser 375*84ad6884SPeter Tyser .macro get_bad_stack 376*84ad6884SPeter Tyser ldr r13, _armboot_start @ setup our mode stack 377*84ad6884SPeter Tyser sub r13, r13, #(CONFIG_STACKSIZE+CONFIG_SYS_MALLOC_LEN) 378*84ad6884SPeter Tyser sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ reserved a couple spots in abort stack 379*84ad6884SPeter Tyser 380*84ad6884SPeter Tyser str lr, [r13] @ save caller lr / spsr 381*84ad6884SPeter Tyser mrs lr, spsr 382*84ad6884SPeter Tyser str lr, [r13, #4] 383*84ad6884SPeter Tyser 384*84ad6884SPeter Tyser mov r13, #MODE_SVC @ prepare SVC-Mode 385*84ad6884SPeter Tyser msr spsr_c, r13 386*84ad6884SPeter Tyser mov lr, pc 387*84ad6884SPeter Tyser movs pc, lr 388*84ad6884SPeter Tyser .endm 389*84ad6884SPeter Tyser 390*84ad6884SPeter Tyser .macro get_irq_stack @ setup IRQ stack 391*84ad6884SPeter Tyser ldr sp, IRQ_STACK_START 392*84ad6884SPeter Tyser .endm 393*84ad6884SPeter Tyser 394*84ad6884SPeter Tyser .macro get_fiq_stack @ setup FIQ stack 395*84ad6884SPeter Tyser ldr sp, FIQ_STACK_START 396*84ad6884SPeter Tyser .endm 397*84ad6884SPeter Tyser 398*84ad6884SPeter Tyser 399*84ad6884SPeter Tyser/****************************************************************************/ 400*84ad6884SPeter Tyser/* */ 401*84ad6884SPeter Tyser/* exception handlers */ 402*84ad6884SPeter Tyser/* */ 403*84ad6884SPeter Tyser/****************************************************************************/ 404*84ad6884SPeter Tyser 405*84ad6884SPeter Tyser .align 5 406*84ad6884SPeter Tyserundefined_instruction: 407*84ad6884SPeter Tyser get_bad_stack 408*84ad6884SPeter Tyser bad_save_user_regs 409*84ad6884SPeter Tyser bl do_undefined_instruction 410*84ad6884SPeter Tyser 411*84ad6884SPeter Tyser .align 5 412*84ad6884SPeter Tysersoftware_interrupt: 413*84ad6884SPeter Tyser get_bad_stack 414*84ad6884SPeter Tyser bad_save_user_regs 415*84ad6884SPeter Tyser bl do_software_interrupt 416*84ad6884SPeter Tyser 417*84ad6884SPeter Tyser .align 5 418*84ad6884SPeter Tyserprefetch_abort: 419*84ad6884SPeter Tyser get_bad_stack 420*84ad6884SPeter Tyser bad_save_user_regs 421*84ad6884SPeter Tyser bl do_prefetch_abort 422*84ad6884SPeter Tyser 423*84ad6884SPeter Tyser .align 5 424*84ad6884SPeter Tyserdata_abort: 425*84ad6884SPeter Tyser get_bad_stack 426*84ad6884SPeter Tyser bad_save_user_regs 427*84ad6884SPeter Tyser bl do_data_abort 428*84ad6884SPeter Tyser 429*84ad6884SPeter Tyser .align 5 430*84ad6884SPeter Tysernot_used: 431*84ad6884SPeter Tyser get_bad_stack 432*84ad6884SPeter Tyser bad_save_user_regs 433*84ad6884SPeter Tyser bl do_not_used 434*84ad6884SPeter Tyser 435*84ad6884SPeter Tyser#ifdef CONFIG_USE_IRQ 436*84ad6884SPeter Tyser 437*84ad6884SPeter Tyser .align 5 438*84ad6884SPeter Tyserirq: 439*84ad6884SPeter Tyser get_irq_stack 440*84ad6884SPeter Tyser irq_save_user_regs 441*84ad6884SPeter Tyser bl do_irq 442*84ad6884SPeter Tyser irq_restore_user_regs 443*84ad6884SPeter Tyser 444*84ad6884SPeter Tyser .align 5 445*84ad6884SPeter Tyserfiq: 446*84ad6884SPeter Tyser get_fiq_stack 447*84ad6884SPeter Tyser irq_save_user_regs /* someone ought to write a more */ 448*84ad6884SPeter Tyser bl do_fiq /* effiction fiq_save_user_regs */ 449*84ad6884SPeter Tyser irq_restore_user_regs 450*84ad6884SPeter Tyser 451*84ad6884SPeter Tyser#else /* !CONFIG_USE_IRQ */ 452*84ad6884SPeter Tyser 453*84ad6884SPeter Tyser .align 5 454*84ad6884SPeter Tyserirq: 455*84ad6884SPeter Tyser get_bad_stack 456*84ad6884SPeter Tyser bad_save_user_regs 457*84ad6884SPeter Tyser bl do_irq 458*84ad6884SPeter Tyser 459*84ad6884SPeter Tyser .align 5 460*84ad6884SPeter Tyserfiq: 461*84ad6884SPeter Tyser get_bad_stack 462*84ad6884SPeter Tyser bad_save_user_regs 463*84ad6884SPeter Tyser bl do_fiq 464*84ad6884SPeter Tyser 465*84ad6884SPeter Tyser#endif /* CONFIG_USE_IRQ */ 466*84ad6884SPeter Tyser 467*84ad6884SPeter Tyser/****************************************************************************/ 468*84ad6884SPeter Tyser/* */ 469*84ad6884SPeter Tyser/* Reset function: the PXA250 doesn't have a reset function, so we have to */ 470*84ad6884SPeter Tyser/* perform a watchdog timeout for a soft reset. */ 471*84ad6884SPeter Tyser/* */ 472*84ad6884SPeter Tyser/****************************************************************************/ 473*84ad6884SPeter Tyser 474*84ad6884SPeter Tyser .align 5 475*84ad6884SPeter Tyser.globl reset_cpu 476*84ad6884SPeter Tyser 477*84ad6884SPeter Tyser /* FIXME: this code is PXA250 specific. How is this handled on */ 478*84ad6884SPeter Tyser /* other XScale processors? */ 479*84ad6884SPeter Tyser 480*84ad6884SPeter Tyserreset_cpu: 481*84ad6884SPeter Tyser 482*84ad6884SPeter Tyser /* We set OWE:WME (watchdog enable) and wait until timeout happens */ 483*84ad6884SPeter Tyser 484*84ad6884SPeter Tyser ldr r0, OSTIMER_BASE 485*84ad6884SPeter Tyser ldr r1, [r0, #OWER] 486*84ad6884SPeter Tyser orr r1, r1, #0x0001 /* bit0: WME */ 487*84ad6884SPeter Tyser str r1, [r0, #OWER] 488*84ad6884SPeter Tyser 489*84ad6884SPeter Tyser /* OS timer does only wrap every 1165 seconds, so we have to set */ 490*84ad6884SPeter Tyser /* the match register as well. */ 491*84ad6884SPeter Tyser 492*84ad6884SPeter Tyser ldr r1, [r0, #OSCR] /* read OS timer */ 493*84ad6884SPeter Tyser add r1, r1, #0x800 /* let OSMR3 match after */ 494*84ad6884SPeter Tyser add r1, r1, #0x800 /* 4096*(1/3.6864MHz)=1ms */ 495*84ad6884SPeter Tyser str r1, [r0, #OSMR3] 496*84ad6884SPeter Tyser 497*84ad6884SPeter Tyserreset_endless: 498*84ad6884SPeter Tyser 499*84ad6884SPeter Tyser b reset_endless 500