blob: d1f8eb0cced5f40c41833faf5e71bae1f3295e03 [file] [edit]
/*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <autoconf.h>
#include <elfloader/gen_config.h>
#include <assembler.h>
#include <armv/assembler.h>
.extern main
.extern non_boot_main
.section ".text.start"
BEGIN_FUNC(_start)
#ifdef CONFIG_ELFLOADER_ARMV8_LEAVE_AARCH64
/* Include an Aarch64 preamble that switches to aarch32 */
.incbin "crt0_64.bin"
BEGIN_FUNC(_start32)
#endif // CONFIG_ELFLOADER_ARMV8_LEAVE_AARCH64
/* If we're not booting under EFI, r2 will contain a pointer to the DTB */
mov r0, r2
/* Disable Async aborts that might be pending from bootloader */
cpsid ifa
/* r0 contains the FDT address from the bootloader */
#if CONFIG_MAX_NUM_NODES > 1
/* Enable SMP */
mrc ACTLR(r1)
orr r1, r1, #(1 << 6) /* enable SMP bit */
#ifdef CONFIG_ARM_CORTEX_A9
orr r1, r1, #1 /* enable FW bit */
#endif
mcr ACTLR(r1)
#endif /* CONFIG_MAX_NUM_NODES > 1 */
ldr sp, =core_stack_alloc + 0xff0
#ifndef CONFIG_IMAGE_EFI
/*
* clear the BSS section, since it may not be clear yet.
* Under EFI, this is done earlier in the boot process.
*/
push {r0}
bl clear_bss
pop {r0}
#endif
b main
END_FUNC(_start)
/* Move the elf loader out of the kernel's way */
BEGIN_FUNC(finish_relocation)
#if CONFIG_IMAGE_EFI
// r0 = offset between current base address and new base address
// r1 = _DYNAMIC pointer (current base address)
// r2 = total offset (new_base)
mov r8, r1 // move to r8
// figure out relocated address of continue_boot
adr r1, LC2
ldmia r1, {r3, r4, r5}
// r3 = stack pointer (in current program)
// r4 = continue_boot (in current program)
// r5 = current base address (_text, the start of the binary)
sub sp, r3, r0 // point sp to new stack
sub r4, r4, r0 // continue_boot address in relocated elfloader
// self_reloc expects:
// r0 = current base address
// r1 = dynamic section pointer
// r2 = new base address
// r3 = 0
mov r0, r5 // current base address
mov r1, r8 // put _DYNAMIC back
// r2 is new base address, passed from relocate_below_kernel()
mov r3, #0 // NULL r3
push {r4} // save continue_boot address
bl _relocate
pop {r4}
mov r0, #1
blx r4
b abort // should never get here!
#else
/* On non-EFI, the image cannot be relocated.
* If you hit this, you probably need to modify the ELF loader
* load address.
*/
mov pc, lr
#endif
END_FUNC(finish_relocation)
.align 2
.type LC2, #object
LC2:
.word core_stack_alloc + 0xff0 // r3
.word continue_boot // r4
.word _text // r5
.size LC2, . - LC2
#if CONFIG_MAX_NUM_NODES > 1
BEGIN_FUNC(secondary_startup)
/* Invalidate caches before proceeding... */
mov r0, #0
mcr IIALL(r0)
dcache isw
/* Disable Async aborts that might be pending from bootloader */
cpsid ifa
/* Enable SMP */
mrc ACTLR(r0)
orr r0, r0, #(1 << 6) /* enable SMP bit */
#ifdef CONFIG_ARM_CORTEX_A9
orr r0, r0, #1 /* enable FW bit */
#endif
mcr ACTLR(r0)
/*
* secondary_data is a struct like this:
* 0x0 void *entry
* 0x4 void *stack
*/
ldr r0, =secondary_data
ldr r1, [r0, #0x4] /* load stack */
mov sp, r1
ldr r2, [r0] /* load entry point */
/* core_entry expects sp as its first argument */
mov r0, r1
bx r2
END_FUNC(secondary_startup)
#endif /* CONFIG_MAX_NUM_NODES */
/*
* Symbols required for libgcc.
*/
.global raise
.global __aeabi_unwind_cpp_pr0
.global __aeabi_unwind_cpp_pr1
.global __aeabi_unwind_cpp_pr2
raise:
__aeabi_unwind_cpp_pr0:
__aeabi_unwind_cpp_pr1:
__aeabi_unwind_cpp_pr2:
b raise