1/* 2 * armboot - Startup Code for ARM720 CPU-core 3 * 4 * Copyright (c) 2001 Marius Gröger <mag@sysgo.de> 5 * Copyright (c) 2002 Alex Züpke <azu@sysgo.de> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 10#include <asm-offsets.h> 11#include <config.h> 12#include <version.h> 13#include <asm/hardware.h> 14 15/* 16 ************************************************************************* 17 * 18 * Jump vector table as in table 3.1 in [1] 19 * 20 ************************************************************************* 21 */ 22 23 24.globl _start 25_start: b reset 26 ldr pc, _undefined_instruction 27 ldr pc, _software_interrupt 28 ldr pc, _prefetch_abort 29 ldr pc, _data_abort 30 ldr pc, _not_used 31 ldr pc, _irq 32 ldr pc, _fiq 33 34#ifdef CONFIG_SPL_BUILD 35_undefined_instruction: .word _undefined_instruction 36_software_interrupt: .word _software_interrupt 37_prefetch_abort: .word _prefetch_abort 38_data_abort: .word _data_abort 39_not_used: .word _not_used 40_irq: .word _irq 41_fiq: .word _fiq 42_pad: .word 0x12345678 /* now 16*4=64 */ 43#else 44_undefined_instruction: .word undefined_instruction 45_software_interrupt: .word software_interrupt 46_prefetch_abort: .word prefetch_abort 47_data_abort: .word data_abort 48_not_used: .word not_used 49_irq: .word irq 50_fiq: .word fiq 51_pad: .word 0x12345678 /* now 16*4=64 */ 52#endif /* CONFIG_SPL_BUILD */ 53 54 .balignl 16,0xdeadbeef 55 56 57/* 58 ************************************************************************* 59 * 60 * Startup Code (reset vector) 61 * 62 * do important init only if we don't start from RAM! 63 * relocate armboot to ram 64 * setup stack 65 * jump to second stage 66 * 67 ************************************************************************* 68 */ 69 70#ifdef CONFIG_USE_IRQ 71/* IRQ stack memory (calculated at run-time) */ 72.globl IRQ_STACK_START 73IRQ_STACK_START: 74 .word 0x0badc0de 75 76/* IRQ stack memory (calculated at run-time) */ 77.globl FIQ_STACK_START 78FIQ_STACK_START: 79 .word 0x0badc0de 80#endif 81 82/* IRQ stack memory (calculated at run-time) + 8 bytes */ 83.globl IRQ_STACK_START_IN 84IRQ_STACK_START_IN: 85 .word 0x0badc0de 86 87/* 88 * the actual reset code 89 */ 90 91reset: 92 /* 93 * set the cpu to SVC32 mode 94 */ 95 mrs r0,cpsr 96 bic r0,r0,#0x1f 97 orr r0,r0,#0xd3 98 msr cpsr,r0 99 100 /* 101 * we do sys-critical inits only at reboot, 102 * not when booting from ram! 103 */ 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 mov pc, lr 116 117/* 118 ************************************************************************* 119 * 120 * CPU_init_critical registers 121 * 122 * setup important registers 123 * setup memory timing 124 * 125 ************************************************************************* 126 */ 127 128#ifndef CONFIG_SKIP_LOWLEVEL_INIT 129cpu_init_crit: 130 131 mov ip, lr 132 /* 133 * before relocating, we have to setup RAM timing 134 * because memory timing is board-dependent, you will 135 * find a lowlevel_init.S in your board directory. 136 */ 137 bl lowlevel_init 138 mov lr, ip 139 140 mov pc, lr 141#endif /* CONFIG_SKIP_LOWLEVEL_INIT */ 142 143 144#ifndef CONFIG_SPL_BUILD 145/* 146 ************************************************************************* 147 * 148 * Interrupt handling 149 * 150 ************************************************************************* 151 */ 152 153@ 154@ IRQ stack frame. 155@ 156#define S_FRAME_SIZE 72 157 158#define S_OLD_R0 68 159#define S_PSR 64 160#define S_PC 60 161#define S_LR 56 162#define S_SP 52 163 164#define S_IP 48 165#define S_FP 44 166#define S_R10 40 167#define S_R9 36 168#define S_R8 32 169#define S_R7 28 170#define S_R6 24 171#define S_R5 20 172#define S_R4 16 173#define S_R3 12 174#define S_R2 8 175#define S_R1 4 176#define S_R0 0 177 178#define MODE_SVC 0x13 179#define I_BIT 0x80 180 181/* 182 * use bad_save_user_regs for abort/prefetch/undef/swi ... 183 * use irq_save_user_regs / irq_restore_user_regs for IRQ/FIQ handling 184 */ 185 186 .macro bad_save_user_regs 187 sub sp, sp, #S_FRAME_SIZE 188 stmia sp, {r0 - r12} @ Calling r0-r12 189 add r8, sp, #S_PC 190 191 ldr r2, IRQ_STACK_START_IN 192 ldmia r2, {r2 - r4} @ get pc, cpsr, old_r0 193 add r0, sp, #S_FRAME_SIZE @ restore sp_SVC 194 195 add r5, sp, #S_SP 196 mov r1, lr 197 stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_r 198 mov r0, sp 199 .endm 200 201 .macro irq_save_user_regs 202 sub sp, sp, #S_FRAME_SIZE 203 stmia sp, {r0 - r12} @ Calling r0-r12 204 add r8, sp, #S_PC 205 stmdb r8, {sp, lr}^ @ Calling SP, LR 206 str lr, [r8, #0] @ Save calling PC 207 mrs r6, spsr 208 str r6, [r8, #4] @ Save CPSR 209 str r0, [r8, #8] @ Save OLD_R0 210 mov r0, sp 211 .endm 212 213 .macro irq_restore_user_regs 214 ldmia sp, {r0 - lr}^ @ Calling r0 - lr 215 mov r0, r0 216 ldr lr, [sp, #S_PC] @ Get PC 217 add sp, sp, #S_FRAME_SIZE 218 subs pc, lr, #4 @ return & move spsr_svc into cpsr 219 .endm 220 221 .macro get_bad_stack 222 ldr r13, IRQ_STACK_START_IN @ setup our mode stack 223 224 str lr, [r13] @ save caller lr / spsr 225 mrs lr, spsr 226 str lr, [r13, #4] 227 228 mov r13, #MODE_SVC @ prepare SVC-Mode 229 msr spsr_c, r13 230 mov lr, pc 231 movs pc, lr 232 .endm 233 234 .macro get_irq_stack @ setup IRQ stack 235 ldr sp, IRQ_STACK_START 236 .endm 237 238 .macro get_fiq_stack @ setup FIQ stack 239 ldr sp, FIQ_STACK_START 240 .endm 241 242/* 243 * exception handlers 244 */ 245 .align 5 246undefined_instruction: 247 get_bad_stack 248 bad_save_user_regs 249 bl do_undefined_instruction 250 251 .align 5 252software_interrupt: 253 get_bad_stack 254 bad_save_user_regs 255 bl do_software_interrupt 256 257 .align 5 258prefetch_abort: 259 get_bad_stack 260 bad_save_user_regs 261 bl do_prefetch_abort 262 263 .align 5 264data_abort: 265 get_bad_stack 266 bad_save_user_regs 267 bl do_data_abort 268 269 .align 5 270not_used: 271 get_bad_stack 272 bad_save_user_regs 273 bl do_not_used 274 275#ifdef CONFIG_USE_IRQ 276 277 .align 5 278irq: 279 get_irq_stack 280 irq_save_user_regs 281 bl do_irq 282 irq_restore_user_regs 283 284 .align 5 285fiq: 286 get_fiq_stack 287 /* someone ought to write a more effiction fiq_save_user_regs */ 288 irq_save_user_regs 289 bl do_fiq 290 irq_restore_user_regs 291 292#else 293 294 .align 5 295irq: 296 get_bad_stack 297 bad_save_user_regs 298 bl do_irq 299 300 .align 5 301fiq: 302 get_bad_stack 303 bad_save_user_regs 304 bl do_fiq 305 306#endif 307#endif /* CONFIG_SPL_BUILD */ 308