/* $NetBSD: start.S,v 1.14 2024/02/07 04:20:26 msaitoh Exp $ */ /* * Copyright (c) 2017 Ryo Shimizu * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include "opt_arm_debug.h" /* VERBOSE_INIT_ARM and EARLYCONS */ #include #include #include "assym.h" RCSID("$NetBSD: start.S,v 1.14 2024/02/07 04:20:26 msaitoh Exp $") /* * Padding at start of kernel image to make room for 64-byte header * (non-ELF booting) */ .header: .space 64, 0x0 /* * Kernel start routine for aarch64 boards. */ .global start start: /* DON'T CLOBBER X0-X3 REGISTERS. THEY ARE UBOOT ARGUMENTS */ /* * Relocate to L2_SIZE(2Mbyte) align if necessary * * x8 = currently loaded address * x9 = (x8 + L2_SIZE - 1) & -L2_SIZE = new (aligned) loaded address */ adrl x8, .header mov x9, #(L2_SIZE-1) add x9, x9, x8 and x9, x9, #-L2_SIZE cmp x8, x9 b.eq 9f /* x10 = size = (_edata - __kernel_text) */ adrl x10, _edata adrl x11, __kernel_text sub x10, x10, x11 /* do memmove(x9, x8, x10) */ add x8, x8, x10 add x13, x9, x10 1: ldp x11, x12, [x8, #-16]! stp x11, x12, [x13, #-16]! cmp x13, x9 b.hi 1b /* jump to new (aligned) loaded address */ add x9, x9, #(start - .header) /* skip header */ br x9 9: /* * Zero the BSS */ adrl x8, __bss_start__ adrl x9, __bss_end__ /* while (x8 < x9) *(uint128_t *)x8++ = 0; */ b 2f 1: stp xzr, xzr, [x8], #16 2: cmp x8, x9 b.lo 1b mrs x8, CurrentEL lsr x8, x8, #2 cmp x8, #0x2 b.lo 1f mrs x8, sctlr_el2 #ifdef __AARCH64EB__ orr x8, x8, #SCTLR_EE /* set: Big Endian */ #else bic x8, x8, #SCTLR_EE /* clear: Little Endian */ #endif msr sctlr_el2, x8 isb 1: mrs x8, sctlr_el1 #ifdef __AARCH64EB__ orr x8, x8, #(SCTLR_EE | SCTLR_E0E) /* set: Big Endian */ #else bic x8, x8, #(SCTLR_EE | SCTLR_E0E) /* clear: Little Endian */ #endif msr sctlr_el1, x8 isb adr x9, start ldr x10, =start sub x10, x10, x9 /* address of kern_vtopdiff (relative) */ adrl x8, kern_vtopdiff str x10, [x8] /* kern_vtopdiff = start(virt) - start(phys) */ /* * store uboot arguments to uboot_args[4] */ /* address of uboot_args (relative) */ adrl x8, uboot_args str x0, [x8, #(8*0)] str x1, [x8, #(8*1)] str x2, [x8, #(8*2)] str x3, [x8, #(8*3)] /* * ARM64 boot protocol has FDT address in x0 * */ adrl x8, fdt_addr_r str x0, [x8] adrl x8, pmapboot_pagebase ldr x9, =ARM_BOOTSTRAP_LxPT sub x9, x9, x10 str x9, [x8] b aarch64_start /* aarch64_start() @ aarch64/locore.S */ ENTRY_NP(uartputc) #ifdef EARLYCONS b ___CONCAT(EARLYCONS, _platform_early_putchar) #endif ret