diff options
Diffstat (limited to 'arch/arm64/kernel/start.S')
| -rw-r--r-- | arch/arm64/kernel/start.S | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/arch/arm64/kernel/start.S b/arch/arm64/kernel/start.S new file mode 100644 index 0000000..776744c --- /dev/null +++ b/arch/arm64/kernel/start.S @@ -0,0 +1,94 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * tashaboot arm64 entry. firmware drops us here, usually at EL2 on + * qemu virt. we park the secondaries, drop to EL1, set the stack and + * hand the dtb pointer to C. + * + * Copyright (C) 2026 Bradley Morgan <brads@mainlining.org> + */ + +#include <asm/macro.h> + +.section .text.boot +.globl _start +_start: + b reset + + .balign 8 +.globl _text_base +_text_base: + .quad 0x40000000 + +reset: + /* keep the dtb pointer before anything clobbers x0 */ + mov x19, x0 + + /* park secondary cores, they have nothing to do yet */ + mrs x0, mpidr_el1 + and x0, x0, #0xff + cbnz x0, park + + /* figure out which EL we got */ + mrs x0, CurrentEL + lsr x0, x0, #2 + cmp x0, #3 + b.eq from_el3 + cmp x0, #2 + b.eq from_el2 + cmp x0, #1 + b.eq el1_entry + b park + +from_el3: + /* EL3 is a dead end for us, drop through the EL2 path if we can */ + b park + +from_el2: + /* EL1 must be aarch64 */ + mov x0, #(1 << 31) + msr hcr_el2, x0 + + /* scrub the EL2 state so EL1 starts clean */ + msr cptr_el2, xzr + msr hstr_el2, xzr + mrs x0, cnthctl_el2 + orr x0, x0, #(3 << 0) + msr cnthctl_el2, x0 + msr vpidr_el2, xzr + + mov x0, #0x3c5 + msr scr_el3, x0 + + /* no MMU, no caches at EL1 yet */ + msr sctlr_el1, xzr + isb + + /* SPSR for EL1h with interrupts masked */ + mov x0, #0x3c5 + msr spsr_el2, x0 + adr x0, el1_entry + msr elr_el2, x0 + eret + +el1_entry: + /* stack for the bootloader, grows down from the image end */ + ldr x0, =__image_end + mov sp, x0 + + /* clear bss */ + ldr x0, =__bss_start + ldr x1, =__bss_end +1: cmp x0, x1 + b.hs 2f + str xzr, [x0], #8 + b 1b +2: + + /* dtb pointer into C arg 0 */ + mov x0, x19 + bl tashaboot_main + + /* if main returns there is nothing sensible to do */ +park: + wfe + b park |
