/* 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 */ #include .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