1/* 2 * armboot - Startup Code for OMP2420/ARM1136 CPU-core 3 * 4 * Copyright (c) 2004 Texas Instruments <r-woodruff2@ti.com> 5 * 6 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> 7 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> 8 * Copyright (c) 2002 Gary Jennejohn <garyj@denx.de> 9 * Copyright (c) 2003 Richard Woodruff <r-woodruff2@ti.com> 10 * Copyright (c) 2003 Kshitij <kshitij@ti.com> 11 * 12 * SPDX-License-Identifier: GPL-2.0+ 13 */ 14 15#include <asm-offsets.h> 16#include <config.h> 17#include <version.h> 18.globl _start 19_start: b reset 20#ifdef CONFIG_SPL_BUILD 21 ldr pc, _hang 22 ldr pc, _hang 23 ldr pc, _hang 24 ldr pc, _hang 25 ldr pc, _hang 26 ldr pc, _hang 27 ldr pc, _hang 28 29_hang: 30 .word do_hang 31 .word 0x12345678 32 .word 0x12345678 33 .word 0x12345678 34 .word 0x12345678 35 .word 0x12345678 36 .word 0x12345678 37 .word 0x12345678 /* now 16*4=64 */ 38#else 39 ldr pc, _undefined_instruction 40 ldr pc, _software_interrupt 41 ldr pc, _prefetch_abort 42 ldr pc, _data_abort 43 ldr pc, _not_used 44 ldr pc, _irq 45 ldr pc, _fiq 46 47_undefined_instruction: .word undefined_instruction 48_software_interrupt: .word software_interrupt 49_prefetch_abort: .word prefetch_abort 50_data_abort: .word data_abort 51_not_used: .word not_used 52_irq: .word irq 53_fiq: .word fiq 54_pad: .word 0x12345678 /* now 16*4=64 */ 55#endif /* CONFIG_SPL_BUILD */ 56 57 .balignl 16,0xdeadbeef 58/* 59 ************************************************************************* 60 * 61 * Startup Code (reset vector) 62 * 63 * do important init only if we don't start from memory! 64 * setup Memory and board specific bits prior to relocation. 65 * relocate armboot to ram 66 * setup stack 67 * 68 ************************************************************************* 69 */ 70 71#ifdef CONFIG_USE_IRQ 72/* IRQ stack memory (calculated at run-time) */ 73.globl IRQ_STACK_START 74IRQ_STACK_START: 75 .word 0x0badc0de 76 77/* IRQ stack memory (calculated at run-time) */ 78.globl FIQ_STACK_START 79FIQ_STACK_START: 80 .word 0x0badc0de 81#endif 82 83/* IRQ stack memory (calculated at run-time) + 8 bytes */ 84.globl IRQ_STACK_START_IN 85IRQ_STACK_START_IN: 86 .word 0x0badc0de 87 88/* 89 * the actual reset code 90 */ 91 92reset: 93 /* 94 * set the cpu to SVC32 mode 95 */ 96 mrs r0,cpsr 97 bic r0,r0,#0x1f 98 orr r0,r0,#0xd3 99 msr cpsr,r0 100 101 /* the mask ROM code should have PLL and others stable */ 102#ifndef CONFIG_SKIP_LOWLEVEL_INIT 103 bl cpu_init_crit 104#endif 105 106 bl _main 107 108/*------------------------------------------------------------------------------*/ 109 110 .globl c_runtime_cpu_setup 111c_runtime_cpu_setup: 112 113 bx lr 114 115/* 116 ************************************************************************* 117 * 118 * CPU_init_critical registers 119 * 120 * setup important registers 121 * setup memory timing 122 * 123 ************************************************************************* 124 */ 125#ifndef CONFIG_SKIP_LOWLEVEL_INIT 126cpu_init_crit: 127 /* 128 * flush v4 I/D caches 129 */ 130 mov r0, #0 131 mcr p15, 0, r0, c7, c7, 0 /* Invalidate I+D+BTB caches */ 132 mcr p15, 0, r0, c8, c7, 0 /* Invalidate Unified TLB */ 133 134 /* 135 * disable MMU stuff and caches 136 */ 137 mrc p15, 0, r0, c1, c0, 0 138 bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS) 139 bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM) 140 orr r0, r0, #0x00000002 @ set bit 2 (A) Align 141 orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache 142 mcr p15, 0, r0, c1, c0, 0 143 144 /* 145 * Jump to board specific initialization... The Mask ROM will have already initialized 146 * basic memory. Go here to bump up clock rate and handle wake up conditions. 147 */ 148 mov ip, lr /* persevere link reg across call */ 149 bl lowlevel_init /* go setup pll,mux,memory */ 150 mov lr, ip /* restore link */ 151 mov pc, lr /* back to my caller */ 152#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ 153 154#ifndef CONFIG_SPL_BUILD 155/* 156 ************************************************************************* 157 * 158 * Interrupt handling 159 * 160 ************************************************************************* 161 */ 162@ 163@ IRQ stack frame. 164@ 165#define S_FRAME_SIZE 72 166 167#define S_OLD_R0 68 168#define S_PSR 64 169#define S_PC 60 170#define S_LR 56 171#define S_SP 52 172 173#define S_IP 48 174#define S_FP 44 175#define S_R10 40 176#define S_R9 36 177#define S_R8 32 178#define S_R7 28 179#define S_R6 24 180#define S_R5 20 181#define S_R4 16 182#define S_R3 12 183#define S_R2 8 184#define S_R1 4 185#define S_R0 0 186 187#define MODE_SVC 0x13 188#define I_BIT 0x80 189 190/* 191 * use bad_save_user_regs for abort/prefetch/undef/swi ... 192 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling 193 */ 194 195 .macro bad_save_user_regs 196 sub sp, sp, #S_FRAME_SIZE @ carve out a frame on current user stack 197 stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12 198 199 ldr r2, IRQ_STACK_START_IN @ set base 2 words into abort stack 200 ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs) 201 add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack 202 203 add r5, sp, #S_SP 204 mov r1, lr 205 stmia r5, {r0 - r3} @ save sp_SVC, lr_SVC, pc, cpsr 206 mov r0, sp @ save current stack into r0 (param register) 207 .endm 208 209 .macro irq_save_user_regs 210 sub sp, sp, #S_FRAME_SIZE 211 stmia sp, {r0 - r12} @ Calling r0-r12 212 add r8, sp, #S_PC @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. 213 stmdb r8, {sp, lr}^ @ Calling SP, LR 214 str lr, [r8, #0] @ Save calling PC 215 mrs r6, spsr 216 str r6, [r8, #4] @ Save CPSR 217 str r0, [r8, #8] @ Save OLD_R0 218 mov r0, sp 219 .endm 220 221 .macro irq_restore_user_regs 222 ldmia sp, {r0 - lr}^ @ Calling r0 - lr 223 mov r0, r0 224 ldr lr, [sp, #S_PC] @ Get PC 225 add sp, sp, #S_FRAME_SIZE 226 subs pc, lr, #4 @ return & move spsr_svc into cpsr 227 .endm 228 229 .macro get_bad_stack 230 ldr r13, IRQ_STACK_START_IN @ setup our mode stack (enter in banked mode) 231 232 str lr, [r13] @ save caller lr in position 0 of saved stack 233 mrs lr, spsr @ get the spsr 234 str lr, [r13, #4] @ save spsr in position 1 of saved stack 235 236 mov r13, #MODE_SVC @ prepare SVC-Mode 237 @ msr spsr_c, r13 238 msr spsr, r13 @ switch modes, make sure moves will execute 239 mov lr, pc @ capture return pc 240 movs pc, lr @ jump to next instruction & switch modes. 241 .endm 242 243 .macro get_bad_stack_swi 244 sub r13, r13, #4 @ space on current stack for scratch reg. 245 str r0, [r13] @ save R0's value. 246 ldr r0, IRQ_STACK_START_IN @ get data regions start 247 str lr, [r0] @ save caller lr in position 0 of saved stack 248 mrs lr, spsr @ get the spsr 249 str lr, [r0, #4] @ save spsr in position 1 of saved stack 250 ldr lr, [r0] @ restore lr 251 ldr r0, [r13] @ restore r0 252 add r13, r13, #4 @ pop stack entry 253 .endm 254 255 .macro get_irq_stack @ setup IRQ stack 256 ldr sp, IRQ_STACK_START 257 .endm 258 259 .macro get_fiq_stack @ setup FIQ stack 260 ldr sp, FIQ_STACK_START 261 .endm 262#endif /* CONFIG_SPL_BUILD */ 263 264/* 265 * exception handlers 266 */ 267#ifdef CONFIG_SPL_BUILD 268 .align 5 269do_hang: 270 bl hang /* hang and never return */ 271#else /* !CONFIG_SPL_BUILD */ 272 .align 5 273undefined_instruction: 274 get_bad_stack 275 bad_save_user_regs 276 bl do_undefined_instruction 277 278 .align 5 279software_interrupt: 280 get_bad_stack_swi 281 bad_save_user_regs 282 bl do_software_interrupt 283 284 .align 5 285prefetch_abort: 286 get_bad_stack 287 bad_save_user_regs 288 bl do_prefetch_abort 289 290 .align 5 291data_abort: 292 get_bad_stack 293 bad_save_user_regs 294 bl do_data_abort 295 296 .align 5 297not_used: 298 get_bad_stack 299 bad_save_user_regs 300 bl do_not_used 301 302#ifdef CONFIG_USE_IRQ 303 304 .align 5 305irq: 306 get_irq_stack 307 irq_save_user_regs 308 bl do_irq 309 irq_restore_user_regs 310 311 .align 5 312fiq: 313 get_fiq_stack 314 /* someone ought to write a more effiction fiq_save_user_regs */ 315 irq_save_user_regs 316 bl do_fiq 317 irq_restore_user_regs 318 319#else 320 321 .align 5 322irq: 323 get_bad_stack 324 bad_save_user_regs 325 bl do_irq 326 327 .align 5 328fiq: 329 get_bad_stack 330 bad_save_user_regs 331 bl do_fiq 332 333#endif 334#endif /* CONFIG_SPL_BUILD */ 335