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#ifdef CONFIG_IMAGE_BINARY 10#include <image_start_addr.h> 11#endif 12 13#include <assembler.h> 14 15.extern main 16 17.section ".text.start" 18BEGIN_FUNC(_start) 19 adrp x19, core_stack_alloc 20 add x19, x19, #0xff0 21 mov sp, x19 22#ifdef CONFIG_IMAGE_BINARY 23 stp x0, x1, [sp, #-16]! 24 bl clear_bss 25 /* 26 * Binary images may not be loaded in the correct location. 27 * Try and move ourselves so we're in the right place. 28 */ 29 bl fixup_image_base 30 mov x2, x0 31 /* restore original arguments for next step */ 32 ldp x0, x1, [sp, #-16]! 33 /* fixup_image_base returns 1 if no need to move */ 34 cmp x2, #1 35 beq 1f 36 /* otherwise, jump to the start of the new elfloader */ 37 38 br x2 391: 40#endif 41 b main 42END_FUNC(_start) 43 44#ifdef CONFIG_IMAGE_BINARY 45BEGIN_FUNC(fixup_image_base) 46 stp x29, x30, [sp, #-16]! 47 mov x29, sp 48 ldr x0, =IMAGE_START_ADDR 49 adr x1, _start 50 cmp x0, x1 51 beq image_ok 52 53 adrp x2, _end 54 add x2, x2, #:lo12:_end 55 sub x2, x2, x1 56 57 /* sanity check: don't want to overwrite ourselves! we assume 58 * everything between _start and _archive_start is important 59 * (i.e. code that might be run while relocating) 60 * but allow overlap for things after _archive_start. 61 */ 62 adrp x3, _archive_start 63 add x3, x3, #:lo12:_archive_start 64 65 add x4, x0, x2 /* Dest end */ 66 67 /* check: if (end < archive_start && end >= _start) { abort } */ 68 cmp x4, x3 69 bge 1f 70 71 cmp x4, x1 72 blt 1f 73 74 b cant_reloc 75 761: 77 /* check: if (dest < archive_start && dest >= _start) { abort } */ 78 cmp x0, x3 79 bge 2f 80 81 cmp x0, x1 82 blt 2f 83 84cant_reloc: 85 b abort 86 872: 88 /* x0 = desired image base */ 89 /* x1 = current image space */ 90 /* x2 = image size */ 91 bl memmove 92 /* x0 = dest, save it to a callee-saved register while we invalidate icache */ 93 mov x19, x0 94 bl flush_dcache 95 bl invalidate_icache 96 mov x0, x19 97 b 1f 98 99image_ok: 100 /* already in the right place, just keep booting */ 101 mov x0, #1 1021: 103 ldp x29, x30, [sp], #16 104 ret 105END_FUNC(fixup_image_base) 106#endif 107 108/* Move the elf loader out of the kernel's way */ 109BEGIN_FUNC(finish_relocation) 110 /* 111 * On aarch64 the kernel is loaded at a very high address: 112 * at least above 0x0000ff8080000000. We assume that 113 * the ELF loader will never get loaded in a way that overlaps 114 * with the kernel, so reaching this function is an error. 115 */ 116 b abort // should never get here! 117END_FUNC(finish_relocation) 118 119/* secondary cpu startup */ 120BEGIN_FUNC(secondary_startup) 121 /* 122 * secondary_data is a struct that looks like this: 123 * 0x0 void *entry 124 * 0x8 void *stack 125 */ 126 adrp x19, secondary_data 127 add x19, x19, #:lo12:secondary_data 128 129 ldr x0, [x19, #0x8] // load stack 130 mov sp, x0 131 ldr x1, [x19, #0x0] // load entry point 132 133 br x1 134END_FUNC(secondary_startup) 135