1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * This file is based off of the OMAP3530/ARM Cortex start.S file from Das 4 * U-Boot, which itself got the file from armboot. 5 */ 6 7/* Early initialization code for ARMv7 architecture. */ 8 9#include <arch/asm.h> 10 11.arm 12 /* 13 * Just in case the maskrom or the vendor basic firmware passes on a 14 * parameter when calling the bootblock, store it here for handling by C 15 * code. 16 */ 17 .section .bss, "aw" @nobits 18 .global maskrom_param 19maskrom_param: 20 .word 0 21 22ENTRY(_start) 23 /* 24 * Set the CPU to System mode with IRQ and FIQ disabled. Prefetch/Data 25 * aborts may happen early and crash before the abort handlers are 26 * installed, but at least the problem will show up near the code that 27 * causes it. 28 */ 29 msr cpsr_cxf, #0xdf 30 bl _thumb_start 31ENDPROC(_start) 32 33.thumb 34ENTRY(_thumb_start) 35 36 /* Preserve the maskrom passed value, if any */ 37 mov r10, r0 38 39 bl arm_init_caches 40 41 /* 42 * From Cortex-A Series Programmer's Guide: 43 * Only CPU 0 performs initialization. Other CPUs go into WFI 44 * to do this, first work out which CPU this is 45 * this code typically is run before any other initialization step 46 */ 47 mrc p15, 0, r1, c0, c0, 5 @ Read Multiprocessor Affinity Register 48 and r1, r1, #0x3 @ Extract CPU ID bits 49 cmp r1, #0 50 bne wait_for_interrupt @ If this is not core0, wait 51 52 /* 53 * Initialize the stack to a known value. This is used to check for 54 * stack overflow later in the boot process. 55 */ 56 ldr r0, =_stack 57 ldr r1, =_estack 58 ldr r2, =0xdeadbeef 59init_stack_loop: 60 str r2, [r0] 61 add r0, #4 62 cmp r0, r1 63 bne init_stack_loop 64 65 /* Set stackpointer in internal RAM */ 66 ldr sp, =_estack 67 68 /* 69 * For platforms where the flash is memory mapped (qemu), check if the 70 * bootblock needs to relocate itself. 71 */ 72check_position: 73 adr r0, check_position 74 ldr r1, =check_position 75 76 cmp r0, r1 77 beq call_bootblock 78 79 /* Calculate source */ 80 ldr r2, =_program 81 sub r1, r1, r2 82 sub r1, r0, r1 83 /* Get destination */ 84 ldr r0, =_program 85 /* Get size */ 86 ldr r2, =_eprogram 87 sub r2, r2, r0 88 89 bl memcpy 90 91 /* Get absolute address */ 92 ldr lr, =call_bootblock 93 /* Directly modify pc as branch instruction changes the state */ 94 mov pc, lr 95 96call_bootblock: 97 98 /* Restore parameter passed in by maskrom/vendor firmware. */ 99 ldr r0, =maskrom_param 100 str r10, [r0] 101 102 ldr r0,=0x00000000 103 /* 104 * The current design of cpu_info places the struct at the top of the 105 * stack. Free enough space to accommodate for that, but make sure it's 106 * 8-byte aligned for ABI compliance. 107 */ 108 sub sp, sp, #16 109 bl main 110 111wait_for_interrupt: 112 wfi 113 mov pc, lr @ back to my caller 114ENDPROC(_thumb_start) 115