1/* 2 * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230) 3 * Copyright 2015, 2016 Hesham Almatary <heshamelmatary@gmail.com> 4 * Copyright 2021, HENSOLDT Cyber 5 * 6 * SPDX-License-Identifier: GPL-2.0-only 7 */ 8 9#include <config.h> 10#include <util.h> 11 12.section .boot.text, "ax" 13.global _start 14.extern init_kernel 15.extern kernel_stack_alloc 16.extern __global_pointer$ 17.extern restore_user_context 18 19/* 20 * When SMP is enabled, the elfloader passes the hart ID in a6 21 * and logical core ID in a7. 22 */ 23_start: 24 fence.i 25.option push 26.option norelax 271:auipc gp, %pcrel_hi(__global_pointer$) 28 addi gp, gp, %pcrel_lo(1b) 29.option pop 30 la sp, (kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS)) 31 csrw sscratch, x0 /* zero sscratch for the init task */ 32 33#if CONFIG_MAX_NUM_NODES > 1 34/* setup the per-core stack */ 35 mv t0, a7 36 slli t0, t0, CONFIG_KERNEL_STACK_BITS 37 add sp, sp, t0 38 /* put the stack in sscratch */ 39 csrw sscratch, sp 40#endif 41 42 /* Call bootstrapping implemented in C with parameters: 43 * a0/x10: user image physical start address 44 * a1/x11: user image physical end address 45 * a2/x12: physical/virtual offset 46 * a3/x13: user image virtual entry address 47 * a4/x14: DTB physical address (0 if there is none) 48 * a5/x15: DTB size (0 if there is none) 49 * a6/x16: hart ID (SMP only, unused on non-SMP) 50 * a7/x17: core ID (SMP only, unused on non-SMP) 51 */ 52 jal init_kernel 53 54 /* Restore the initial thread. Note that the function restore_user_context() 55 * could technically also be called at the end of init_kernel() directly, 56 * there is no need to return to the assembly code here at all. However, for 57 * verification things are a lot easier when init_kernel() is a normal C 58 * function that returns. The function restore_user_context() is not a 59 * normal C function and thus handled specially in verification, it does 60 * highly architecture specific things to exit to user mode. 61 */ 62 la ra, restore_user_context 63 jr ra 64