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