1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * 4 * SPDX-License-Identifier: GPL-2.0-only 5 */ 6 7#include <autoconf.h> 8#include <elfloader/gen_config.h> 9#include <assembler.h> 10#include <armv/assembler.h> 11 12.extern main 13.extern non_boot_main 14 15.section ".text.start" 16 17BEGIN_FUNC(_start) 18#ifdef CONFIG_ELFLOADER_ARMV8_LEAVE_AARCH64 19 /* Include an Aarch64 preamble that switches to aarch32 */ 20 .incbin "crt0_64.bin" 21BEGIN_FUNC(_start32) 22#endif // CONFIG_ELFLOADER_ARMV8_LEAVE_AARCH64 23 24 /* If we're not booting under EFI, r2 will contain a pointer to the DTB */ 25 mov r0, r2 26 27 /* Disable Async aborts that might be pending from bootloader */ 28 cpsid ifa 29 30 /* r0 contains the FDT address from the bootloader */ 31#if CONFIG_MAX_NUM_NODES > 1 32 /* Enable SMP */ 33 mrc ACTLR(r1) 34 orr r1, r1, #(1 << 6) /* enable SMP bit */ 35#ifdef CONFIG_ARM_CORTEX_A9 36 orr r1, r1, #1 /* enable FW bit */ 37#endif 38 mcr ACTLR(r1) 39#endif /* CONFIG_MAX_NUM_NODES > 1 */ 40 41 ldr sp, =core_stack_alloc + 0xff0 42 43#ifndef CONFIG_IMAGE_EFI 44 /* 45 * clear the BSS section, since it may not be clear yet. 46 * Under EFI, this is done earlier in the boot process. 47 */ 48 push {r0} 49 bl clear_bss 50 pop {r0} 51#endif 52 53 b main 54END_FUNC(_start) 55 56/* Move the elf loader out of the kernel's way */ 57BEGIN_FUNC(finish_relocation) 58#if CONFIG_IMAGE_EFI 59 // r0 = offset between current base address and new base address 60 // r1 = _DYNAMIC pointer (current base address) 61 // r2 = total offset (new_base) 62 mov r8, r1 // move to r8 63 64 // figure out relocated address of continue_boot 65 adr r1, LC2 66 ldmia r1, {r3, r4, r5} 67 68 // r3 = stack pointer (in current program) 69 // r4 = continue_boot (in current program) 70 // r5 = current base address (_text, the start of the binary) 71 72 sub sp, r3, r0 // point sp to new stack 73 sub r4, r4, r0 // continue_boot address in relocated elfloader 74 75 // self_reloc expects: 76 // r0 = current base address 77 // r1 = dynamic section pointer 78 // r2 = new base address 79 // r3 = 0 80 81 mov r0, r5 // current base address 82 mov r1, r8 // put _DYNAMIC back 83 // r2 is new base address, passed from relocate_below_kernel() 84 mov r3, #0 // NULL r3 85 86 push {r4} // save continue_boot address 87 88 bl _relocate 89 90 pop {r4} 91 mov r0, #1 92 blx r4 93 b abort // should never get here! 94#else 95 /* On non-EFI, the image cannot be relocated. 96 * If you hit this, you probably need to modify the ELF loader 97 * load address. 98 */ 99 mov pc, lr 100#endif 101END_FUNC(finish_relocation) 102.align 2 103.type LC2, #object 104LC2: 105.word core_stack_alloc + 0xff0 // r3 106.word continue_boot // r4 107.word _text // r5 108.size LC2, . - LC2 109 110#if CONFIG_MAX_NUM_NODES > 1 111BEGIN_FUNC(secondary_startup) 112 /* Invalidate caches before proceeding... */ 113 mov r0, #0 114 mcr IIALL(r0) 115 dcache isw 116 117 /* Disable Async aborts that might be pending from bootloader */ 118 cpsid ifa 119 120 /* Enable SMP */ 121 mrc ACTLR(r0) 122 orr r0, r0, #(1 << 6) /* enable SMP bit */ 123#ifdef CONFIG_ARM_CORTEX_A9 124 orr r0, r0, #1 /* enable FW bit */ 125#endif 126 mcr ACTLR(r0) 127 128 /* 129 * secondary_data is a struct like this: 130 * 0x0 void *entry 131 * 0x4 void *stack 132 */ 133 ldr r0, =secondary_data 134 ldr r1, [r0, #0x4] /* load stack */ 135 mov sp, r1 136 137 ldr r2, [r0] /* load entry point */ 138 139 /* core_entry expects sp as its first argument */ 140 mov r0, r1 141 bx r2 142END_FUNC(secondary_startup) 143#endif /* CONFIG_MAX_NUM_NODES */ 144 145/* 146 * Symbols required for libgcc. 147 */ 148.global raise 149.global __aeabi_unwind_cpp_pr0 150.global __aeabi_unwind_cpp_pr1 151.global __aeabi_unwind_cpp_pr2 152raise: 153__aeabi_unwind_cpp_pr0: 154__aeabi_unwind_cpp_pr1: 155__aeabi_unwind_cpp_pr2: 156 b raise 157