193e54a63SMarouene Boubakri/* SPDX-License-Identifier: BSD-2-Clause */ 293e54a63SMarouene Boubakri/* 3adb103f3SAlvin Chang * Copyright (c) 2023 Andes Technology Corporation 493e54a63SMarouene Boubakri * Copyright 2022-2023 NXP 593e54a63SMarouene Boubakri */ 693e54a63SMarouene Boubakri 793e54a63SMarouene Boubakri#include <asm.S> 893e54a63SMarouene Boubakri#include <generated/asm-defines.h> 993e54a63SMarouene Boubakri#include <keep.h> 10f4ea1751SAlvin Chang#include <kernel/thread.h> 11ca71b6faSYu-Chien Peter Lin#include <kernel/riscv_elf.h> 12aeee5d74SAlvin Chang#include <kernel/thread_private.h> 13b9807372SAlvin Chang#include <kernel/thread_private_arch.h> 1493e54a63SMarouene Boubakri#include <mm/core_mmu.h> 1593e54a63SMarouene Boubakri#include <platform_config.h> 1693e54a63SMarouene Boubakri#include <riscv.h> 1793e54a63SMarouene Boubakri#include <riscv_macros.S> 18470aadc6SAlvin Chang#include <tee/optee_abi.h> 19470aadc6SAlvin Chang#include <tee/teeabi_opteed.h> 20470aadc6SAlvin Chang#include <tee/teeabi_opteed_macros.h> 2193e54a63SMarouene Boubakri 2293e54a63SMarouene Boubakri.section .data 2393e54a63SMarouene Boubakri.balign 4 2493e54a63SMarouene Boubakri 2593e54a63SMarouene Boubakri#ifdef CFG_BOOT_SYNC_CPU 2693e54a63SMarouene Boubakri.equ SEM_CPU_READY, 1 2793e54a63SMarouene Boubakri#endif 2893e54a63SMarouene Boubakri 2993e54a63SMarouene Boubakri /* 3093e54a63SMarouene Boubakri * Setup sp to point to the top of the tmp stack for the current CPU: 3193e54a63SMarouene Boubakri * sp is assigned: 322e27ec6cSYu-Chien Peter Lin * stack_tmp + (hart_index + 1) * stack_tmp_stride - STACK_TMP_GUARD 3393e54a63SMarouene Boubakri */ 3493e54a63SMarouene Boubakri.macro set_sp 3593e54a63SMarouene Boubakri /* Unsupported CPU, park it before it breaks something */ 3693e54a63SMarouene Boubakri li t1, CFG_TEE_CORE_NB_CORE 372e27ec6cSYu-Chien Peter Lin csrr t0, CSR_XSCRATCH /* t0: hart_index */ 3893e54a63SMarouene Boubakri bge t0, t1, unhandled_cpu 390cc8f3e4SAlvin Chang addi t0, t0, 1 4093e54a63SMarouene Boubakri lw t1, stack_tmp_stride 410cc8f3e4SAlvin Chang mul t1, t0, t1 420cc8f3e4SAlvin Chang la t2, stack_tmp_rel 430cc8f3e4SAlvin Chang lw t0, 0(t2) 440cc8f3e4SAlvin Chang add t0, t0, t2 450cc8f3e4SAlvin Chang add sp, t1, t0 4693e54a63SMarouene Boubakri.endm 4793e54a63SMarouene Boubakri 4893e54a63SMarouene Boubakri.macro cpu_is_ready 4993e54a63SMarouene Boubakri#ifdef CFG_BOOT_SYNC_CPU 5093e54a63SMarouene Boubakri csrr t0, CSR_XSCRATCH 5193e54a63SMarouene Boubakri la t1, sem_cpu_sync 5293e54a63SMarouene Boubakri slli t0, t0, 2 5393e54a63SMarouene Boubakri add t1, t1, t0 5493e54a63SMarouene Boubakri li t2, SEM_CPU_READY 5593e54a63SMarouene Boubakri sw t2, 0(t1) 5693e54a63SMarouene Boubakri fence 5793e54a63SMarouene Boubakri#endif 5893e54a63SMarouene Boubakri.endm 5993e54a63SMarouene Boubakri 6093e54a63SMarouene Boubakri.macro set_tp 6129661368SYu-Chien Peter Lin csrr t0, CSR_XSCRATCH /* t0: hart_index */ 6229661368SYu-Chien Peter Lin li t1, THREAD_CORE_LOCAL_SIZE 6329661368SYu-Chien Peter Lin mul t2, t1, t0 6493e54a63SMarouene Boubakri la tp, thread_core_local 65a4c2e0cbSJens Wiklander LDR tp, 0(tp) 6629661368SYu-Chien Peter Lin add tp, tp, t2 6729661368SYu-Chien Peter Lin /* Save hart_id and hart_index into thread_core_local */ 6829661368SYu-Chien Peter Lin sw s0, THREAD_CORE_LOCAL_HART_ID(tp) 6929661368SYu-Chien Peter Lin sw t0, THREAD_CORE_LOCAL_HART_INDEX(tp) 7093e54a63SMarouene Boubakri.endm 7193e54a63SMarouene Boubakri 7293e54a63SMarouene Boubakri.macro wait_primary 7393e54a63SMarouene Boubakri#ifdef CFG_BOOT_SYNC_CPU 7493e54a63SMarouene Boubakri la t0, sem_cpu_sync 7593e54a63SMarouene Boubakri li t2, SEM_CPU_READY 7693e54a63SMarouene Boubakri1: 7793e54a63SMarouene Boubakri fence w, w 7893e54a63SMarouene Boubakri lw t1, 0(t0) 7993e54a63SMarouene Boubakri bne t1, t2, 1b 8093e54a63SMarouene Boubakri#endif 8193e54a63SMarouene Boubakri.endm 8293e54a63SMarouene Boubakri 8393e54a63SMarouene Boubakri.macro wait_secondary 8493e54a63SMarouene Boubakri#ifdef CFG_BOOT_SYNC_CPU 8593e54a63SMarouene Boubakri la t0, sem_cpu_sync 8693e54a63SMarouene Boubakri li t1, CFG_TEE_CORE_NB_CORE 8793e54a63SMarouene Boubakri li t2, SEM_CPU_READY 8893e54a63SMarouene Boubakri1: 8993e54a63SMarouene Boubakri addi t1, t1, -1 9093e54a63SMarouene Boubakri beqz t1, 3f 9193e54a63SMarouene Boubakri addi t0, t0, 4 9293e54a63SMarouene Boubakri2: 9393e54a63SMarouene Boubakri fence 9493e54a63SMarouene Boubakri lw t1, 0(t0) 9593e54a63SMarouene Boubakri bne t1, t2, 2b 9693e54a63SMarouene Boubakri j 1b 9793e54a63SMarouene Boubakri3: 9893e54a63SMarouene Boubakri#endif 9993e54a63SMarouene Boubakri.endm 10093e54a63SMarouene Boubakri 10193e54a63SMarouene Boubakri#ifdef CFG_BOOT_SYNC_CPU 10293e54a63SMarouene Boubakri#define flush_cpu_semaphores \ 10393e54a63SMarouene Boubakri la t0, sem_cpu_sync_start 10493e54a63SMarouene Boubakri la t1, sem_cpu_sync_end 10593e54a63SMarouene Boubakri fence 10693e54a63SMarouene Boubakri#else 10793e54a63SMarouene Boubakri#define flush_cpu_semaphores 10893e54a63SMarouene Boubakri#endif 10993e54a63SMarouene Boubakri 11093e54a63SMarouene BoubakriFUNC _start , : 111adb103f3SAlvin Chang /* 112adb103f3SAlvin Chang * Register usage: 113adb103f3SAlvin Chang * a0 - if non-NULL holds the hart ID 114adb103f3SAlvin Chang * a1 - if non-NULL holds the system DTB address 115adb103f3SAlvin Chang * 11629661368SYu-Chien Peter Lin * s0 - saved a0 117adb103f3SAlvin Chang * s1 - saved a1 118adb103f3SAlvin Chang */ 11993e54a63SMarouene Boubakri.option push 12093e54a63SMarouene Boubakri.option norelax 12193e54a63SMarouene Boubakri la gp, __global_pointer$ 12293e54a63SMarouene Boubakri.option pop 12393e54a63SMarouene Boubakri#ifdef CFG_RISCV_M_MODE 12493e54a63SMarouene Boubakri csrr a0, CSR_MHARTID 12593e54a63SMarouene Boubakri#endif 12629661368SYu-Chien Peter Lin mv s0, a0 /* Save hart ID into s0 */ 1272e27ec6cSYu-Chien Peter Lin 128adb103f3SAlvin Chang#if defined(CFG_DT_ADDR) 129adb103f3SAlvin Chang li s1, CFG_DT_ADDR 130adb103f3SAlvin Chang#else 131adb103f3SAlvin Chang mv s1, a1 /* Save device tree address into s1 */ 132adb103f3SAlvin Chang#endif 133058cf712SAlvin Chang /* Only first hart who wins lottery runs the primary boot sequence. */ 134058cf712SAlvin Chang la a3, hart_lottery 135058cf712SAlvin Chang li a2, 1 136058cf712SAlvin Chang amoadd.w a3, a2, (a3) 1372e27ec6cSYu-Chien Peter Lin /* a3 read from hart_lottery also represents the hart_index */ 1382e27ec6cSYu-Chien Peter Lin csrw CSR_XSCRATCH, a3 1392e27ec6cSYu-Chien Peter Lin 140058cf712SAlvin Chang bnez a3, reset_secondary 14193e54a63SMarouene Boubakri jal reset_primary 14293e54a63SMarouene Boubakri j . 14393e54a63SMarouene BoubakriEND_FUNC _start 14493e54a63SMarouene Boubakri 14593e54a63SMarouene BoubakriLOCAL_FUNC reset_primary , : , .identity_map 14693e54a63SMarouene BoubakriUNWIND( .cantunwind) 147ca71b6faSYu-Chien Peter Lin#ifdef CFG_CORE_ASLR 148ca71b6faSYu-Chien Peter Lin li a0, 0 149ca71b6faSYu-Chien Peter Lin jal relocate 150ca71b6faSYu-Chien Peter Lin#endif 15193e54a63SMarouene Boubakri /* 15293e54a63SMarouene Boubakri * Zero bss 15393e54a63SMarouene Boubakri */ 15493e54a63SMarouene Boubakri lla t0, __bss_start 15593e54a63SMarouene Boubakri lla t1, __bss_end 15693e54a63SMarouene Boubakri beq t0, t1, 1f 15793e54a63SMarouene Boubakri0: 15893e54a63SMarouene Boubakri STR zero, (t0) 15993e54a63SMarouene Boubakri add t0, t0, RISCV_XLEN_BYTES 16093e54a63SMarouene Boubakri bne t0, t1, 0b 16193e54a63SMarouene Boubakri1: 16293e54a63SMarouene Boubakri#ifdef CFG_RISCV_S_MODE 16393e54a63SMarouene Boubakri lla t0, _start 16493e54a63SMarouene Boubakri lla t1, start_addr 16593e54a63SMarouene Boubakri STR t0, (t1) 16693e54a63SMarouene Boubakri#endif 16793e54a63SMarouene Boubakri 16893e54a63SMarouene Boubakri csrw CSR_SATP, zero 169b9807372SAlvin Chang 170b9807372SAlvin Chang /* Setup sp and tp */ 171bb538722SAlvin Chang#if defined(CFG_DYN_CONFIG) 172b9807372SAlvin Chang /* 173b9807372SAlvin Chang * Point sp to a temporary stack at the end of mapped core memory. 174b9807372SAlvin Chang * Point tp to a temporary struct thread_core_local before the temporary 175b9807372SAlvin Chang * stack. 176b9807372SAlvin Chang */ 177b9807372SAlvin Chang la t0, __vcore_free_end 178b9807372SAlvin Chang li t1, THREAD_BOOT_INIT_TMP_ALLOC 179b9807372SAlvin Chang sub t1, t0, t1 180b9807372SAlvin Chang 181b9807372SAlvin Chang /* Clear the allocated struct thread_core_local */ 182b9807372SAlvin Chang add t2, t1, THREAD_CORE_LOCAL_SIZE 183b9807372SAlvin Chang1: addi t2, t2, -RISCV_XLEN_BYTES 184b9807372SAlvin Chang STR zero, (t2) 185b9807372SAlvin Chang bgt t2, t1, 1b 186b9807372SAlvin Chang 187b9807372SAlvin Chang li t2, THREAD_ID_INVALID 188b9807372SAlvin Chang sh t2, THREAD_CORE_LOCAL_CURR_THREAD(t1) 189b9807372SAlvin Chang li t2, THREAD_CLF_TMP 190b9807372SAlvin Chang sw t2, THREAD_CORE_LOCAL_FLAGS(t1) 191b9807372SAlvin Chang li t2, (__STACK_CANARY_SIZE / 2) 192b9807372SAlvin Chang sub t0, t0, t2 193b9807372SAlvin Chang STR t0, THREAD_CORE_LOCAL_TMP_STACK_VA_END(t1) 194b9807372SAlvin Chang li t2, (THREAD_BOOT_INIT_TMP_ALLOC / 2) 195b9807372SAlvin Chang sub t2, t0, t2 196b9807372SAlvin Chang STR t2, THREAD_CORE_LOCAL_ABT_STACK_VA_END(t1) 197b9807372SAlvin Chang csrr t2, CSR_XSCRATCH /* t2: hart_index */ 198*f1651448SAlvin Chang sw s0, THREAD_CORE_LOCAL_HART_ID(t1) 199b9807372SAlvin Chang sw t2, THREAD_CORE_LOCAL_HART_INDEX(t1) 200b9807372SAlvin Chang 201b9807372SAlvin Chang mv sp, t0 202b9807372SAlvin Chang mv tp, t1 203b9807372SAlvin Chang /* 204b9807372SAlvin Chang * Record a single core, to be changed later before secure world 205b9807372SAlvin Chang * boot is done. 206b9807372SAlvin Chang */ 207b9807372SAlvin Chang la t2, thread_core_local 208b9807372SAlvin Chang STR tp, 0(t2) 209b9807372SAlvin Chang la t2, thread_core_count 210b9807372SAlvin Chang li t0, 1 211b9807372SAlvin Chang STR t0, 0(t2) 212b9807372SAlvin Chang#else 21393e54a63SMarouene Boubakri set_sp 21493e54a63SMarouene Boubakri set_tp 21593e54a63SMarouene Boubakri 216f4ea1751SAlvin Chang /* Initialize thread_core_local[hart_index] for early boot */ 217f4ea1751SAlvin Chang jal thread_get_abt_stack 218f4ea1751SAlvin Chang mv a1, sp 219f4ea1751SAlvin Chang STR a1, THREAD_CORE_LOCAL_TMP_STACK_VA_END(tp) 220f4ea1751SAlvin Chang STR a0, THREAD_CORE_LOCAL_ABT_STACK_VA_END(tp) 221f4ea1751SAlvin Chang li a0, THREAD_ID_INVALID 222f4ea1751SAlvin Chang sh a0, THREAD_CORE_LOCAL_CURR_THREAD(tp) 223f4ea1751SAlvin Chang li a0, THREAD_CLF_TMP 224f4ea1751SAlvin Chang sw a0, THREAD_CORE_LOCAL_FLAGS(tp) 225b9807372SAlvin Chang#endif 226f4ea1751SAlvin Chang 22793e54a63SMarouene Boubakri jal plat_primary_init_early 22893e54a63SMarouene Boubakri jal console_init 22993e54a63SMarouene Boubakri 2306ce6769fSAlvin Chang la a0, __vcore_free_start 2316ce6769fSAlvin Chang la a1, __vcore_free_end 232bb538722SAlvin Chang#ifdef CFG_DYN_CONFIG 233b9807372SAlvin Chang li a2, THREAD_BOOT_INIT_TMP_ALLOC 234b9807372SAlvin Chang sub a1, a1, a2 235b9807372SAlvin Chang#endif 2366ce6769fSAlvin Chang la a2, __vcore_free_end 2376ce6769fSAlvin Chang jal boot_mem_init 2386ce6769fSAlvin Chang 239c98d8011SYu-Chien Peter Lin#ifdef CFG_CORE_ASLR 240c98d8011SYu-Chien Peter Lin#ifdef CFG_CORE_ASLR_SEED 241c98d8011SYu-Chien Peter Lin li a0, CFG_CORE_ASLR_SEED 242c98d8011SYu-Chien Peter Lin#else 243c98d8011SYu-Chien Peter Lin jal get_aslr_seed 244c98d8011SYu-Chien Peter Lin#endif 245c98d8011SYu-Chien Peter Lin#else 24693e54a63SMarouene Boubakri mv a0, x0 247c98d8011SYu-Chien Peter Lin#endif 24893e54a63SMarouene Boubakri la a1, boot_mmu_config 24993e54a63SMarouene Boubakri jal core_init_mmu_map 25093e54a63SMarouene Boubakri 251ca71b6faSYu-Chien Peter Lin#ifdef CFG_CORE_ASLR 252ca71b6faSYu-Chien Peter Lin la a0, boot_mmu_config 253ca71b6faSYu-Chien Peter Lin LDR a0, CORE_MMU_CONFIG_MAP_OFFSET(a0) 254ca71b6faSYu-Chien Peter Lin beqz a0, 1f /* no offset, skip dynamic relocation */ 255ca71b6faSYu-Chien Peter Lin jal relocate 256ca71b6faSYu-Chien Peter Lin1: 257ca71b6faSYu-Chien Peter Lin#endif 25893e54a63SMarouene Boubakri 259c98d8011SYu-Chien Peter Lin jal enable_mmu 260c98d8011SYu-Chien Peter Lin 261b9807372SAlvin Chang#ifdef CFG_CORE_ASLR 262bb538722SAlvin Chang#if defined(CFG_DYN_CONFIG) 263b9807372SAlvin Chang /* 264b9807372SAlvin Chang * thread_core_local holds only one core and thread_core_count is 1 265b9807372SAlvin Chang * so tp points to the updated pointer for thread_core_local. 266b9807372SAlvin Chang */ 267b9807372SAlvin Chang la t0, thread_core_local 268b9807372SAlvin Chang STR tp, 0(t0) 269b9807372SAlvin Chang#endif 270c98d8011SYu-Chien Peter Lin 271c98d8011SYu-Chien Peter Lin /* 272c98d8011SYu-Chien Peter Lin * Update recorded end_va. This must be done before calling into C 273c98d8011SYu-Chien Peter Lin * code to make sure that the stack pointer matches what we have in 274c98d8011SYu-Chien Peter Lin * thread_core_local[]. 275c98d8011SYu-Chien Peter Lin */ 276c98d8011SYu-Chien Peter Lin la a0, boot_mmu_config 277c98d8011SYu-Chien Peter Lin LDR a0, CORE_MMU_CONFIG_MAP_OFFSET(a0) 278c98d8011SYu-Chien Peter Lin LDR a1, THREAD_CORE_LOCAL_TMP_STACK_VA_END(tp) 279c98d8011SYu-Chien Peter Lin add a1, a1, a0 280c98d8011SYu-Chien Peter Lin STR a1, THREAD_CORE_LOCAL_TMP_STACK_VA_END(tp) 281c98d8011SYu-Chien Peter Lin LDR a1, THREAD_CORE_LOCAL_ABT_STACK_VA_END(tp) 282c98d8011SYu-Chien Peter Lin add a1, a1, a0 283c98d8011SYu-Chien Peter Lin STR a1, THREAD_CORE_LOCAL_ABT_STACK_VA_END(tp) 284c98d8011SYu-Chien Peter Lin 285c98d8011SYu-Chien Peter Lin /* Update relocations recorded with boot_mem_add_reloc() */ 286c98d8011SYu-Chien Peter Lin jal boot_mem_relocate 287c98d8011SYu-Chien Peter Lin /* 288c98d8011SYu-Chien Peter Lin * Reinitialize console, since register_serial_console() has 289c98d8011SYu-Chien Peter Lin * previously registered a PA and with ASLR the VA is different 290c98d8011SYu-Chien Peter Lin * from the PA. 291c98d8011SYu-Chien Peter Lin */ 292c98d8011SYu-Chien Peter Lin jal console_init 293b9807372SAlvin Chang#endif 294b9807372SAlvin Chang 29593e54a63SMarouene Boubakri jal boot_init_primary_early 296aeee5d74SAlvin Chang 297f4ea1751SAlvin Chang mv a0, s1 /* s1 contains saved device tree address */ 298f4ea1751SAlvin Chang mv a1, x0 /* unused */ 299f4ea1751SAlvin Chang jal boot_init_primary_late 300f4ea1751SAlvin Chang 301bb538722SAlvin Chang#if defined(CFG_DYN_CONFIG) 302b9807372SAlvin Chang /* Get hart index */ 303b9807372SAlvin Chang jal __get_core_pos 304b9807372SAlvin Chang 305b9807372SAlvin Chang /* 306b9807372SAlvin Chang * Switch to the new thread_core_local and thread_core_count and 307b9807372SAlvin Chang * keep the pointer to the new thread_core_local in a1. 308b9807372SAlvin Chang */ 309b9807372SAlvin Chang LDR a1, __thread_core_count_new 310b9807372SAlvin Chang la a2, thread_core_count 311b9807372SAlvin Chang STR a1, 0(a2) 312b9807372SAlvin Chang LDR a1, __thread_core_local_new 313b9807372SAlvin Chang la a2, thread_core_local 314b9807372SAlvin Chang STR a1, 0(a2) 315b9807372SAlvin Chang 316b9807372SAlvin Chang /* 317b9807372SAlvin Chang * Update tp to point the new thread_core_local. 318b9807372SAlvin Chang * Update sp to use the new tmp stack. 319b9807372SAlvin Chang */ 320b9807372SAlvin Chang li a2, THREAD_CORE_LOCAL_SIZE 321b9807372SAlvin Chang /* tp = a2 * a0(hart index) + a1(thread_core_local) */ 322b9807372SAlvin Chang mul a2, a2, a0 323b9807372SAlvin Chang add tp, a2, a1 324b9807372SAlvin Chang LDR sp, THREAD_CORE_LOCAL_TMP_STACK_VA_END(tp) 325b9807372SAlvin Chang#endif 326b9807372SAlvin Chang 327aeee5d74SAlvin Chang /* 328f4ea1751SAlvin Chang * Before entering boot_init_primary_runtime(), we do these two steps: 329aeee5d74SAlvin Chang * 1. Save current sp to s2, and set sp as threads[0].stack_va_end 330aeee5d74SAlvin Chang * 2. Clear the flag which indicates usage of the temporary stack in the 331aeee5d74SAlvin Chang * current hart's thread_core_local structure. 332aeee5d74SAlvin Chang */ 333aeee5d74SAlvin Chang mv s2, sp 334aeee5d74SAlvin Chang la a0, threads 33591d4649dSJens Wiklander LDR a0, 0(a0) 336aeee5d74SAlvin Chang LDR a0, THREAD_CTX_STACK_VA_END(a0) 337aeee5d74SAlvin Chang mv sp, a0 338aeee5d74SAlvin Chang jal thread_get_core_local 339aeee5d74SAlvin Chang mv s3, a0 34078444d33SAlvin Chang sw zero, THREAD_CORE_LOCAL_FLAGS(s3) 341aeee5d74SAlvin Chang 342f4ea1751SAlvin Chang jal boot_init_primary_runtime 3431ede8ef4SAlvin Chang jal boot_init_primary_final 34493e54a63SMarouene Boubakri 345aeee5d74SAlvin Chang /* 346aeee5d74SAlvin Chang * After returning from boot_init_primary_late(), the flag and sp are 347aeee5d74SAlvin Chang * restored. 348aeee5d74SAlvin Chang */ 349aeee5d74SAlvin Chang li a0, THREAD_CLF_TMP 35078444d33SAlvin Chang sw a0, THREAD_CORE_LOCAL_FLAGS(s3) 351aeee5d74SAlvin Chang mv sp, s2 352aeee5d74SAlvin Chang 35371ee6d2aSYu-Chien Peter Lin#ifdef _CFG_CORE_STACK_PROTECTOR 35471ee6d2aSYu-Chien Peter Lin /* Update stack canary value */ 35571ee6d2aSYu-Chien Peter Lin addi sp, sp, -STACK_ALIGNMENT 35671ee6d2aSYu-Chien Peter Lin mv a0, sp 35771ee6d2aSYu-Chien Peter Lin li a1, 1 35871ee6d2aSYu-Chien Peter Lin#ifdef RV32 35971ee6d2aSYu-Chien Peter Lin li a2, 4 36071ee6d2aSYu-Chien Peter Lin#else 36171ee6d2aSYu-Chien Peter Lin li a2, 8 36271ee6d2aSYu-Chien Peter Lin#endif 36371ee6d2aSYu-Chien Peter Lin jal plat_get_random_stack_canaries 36471ee6d2aSYu-Chien Peter Lin LDR s0, 0(sp) 36571ee6d2aSYu-Chien Peter Lin la s1, __stack_chk_guard 36671ee6d2aSYu-Chien Peter Lin STR s0, 0(s1) 36771ee6d2aSYu-Chien Peter Lin addi sp, sp, STACK_ALIGNMENT 36871ee6d2aSYu-Chien Peter Lin#endif 36971ee6d2aSYu-Chien Peter Lin 37093e54a63SMarouene Boubakri cpu_is_ready 37193e54a63SMarouene Boubakri flush_cpu_semaphores 37293e54a63SMarouene Boubakri wait_secondary 37393e54a63SMarouene Boubakri 37493e54a63SMarouene Boubakri jal thread_clr_boot_thread 375470aadc6SAlvin Chang 376470aadc6SAlvin Chang li a0, TEEABI_OPTEED_RETURN_ENTRY_DONE 377470aadc6SAlvin Chang la a1, thread_vector_table 3781eef6015SAlvin Chang li a2, 0 3791eef6015SAlvin Chang li a3, 0 3801eef6015SAlvin Chang li a4, 0 3811eef6015SAlvin Chang li a5, 0 382472c70beSAlvin Chang j thread_return_to_udomain 38393e54a63SMarouene BoubakriEND_FUNC reset_primary 38493e54a63SMarouene Boubakri 38593e54a63SMarouene BoubakriLOCAL_FUNC reset_secondary , : , .identity_map 38693e54a63SMarouene BoubakriUNWIND( .cantunwind) 38793e54a63SMarouene Boubakri wait_primary 38893e54a63SMarouene Boubakri csrw CSR_SATP, zero 3890c44e924SYu-Chien Peter Lin jal enable_mmu 390bb538722SAlvin Chang#if defined(CFG_DYN_CONFIG) 391b9807372SAlvin Chang /* 392b9807372SAlvin Chang * Update tp to point the new thread_core_local. 393b9807372SAlvin Chang * Update sp to use the new tmp stack. 394b9807372SAlvin Chang */ 395b9807372SAlvin Chang csrr t0, CSR_XSCRATCH /* t0: hart_index */ 396b9807372SAlvin Chang LDR t1, thread_core_local 397b9807372SAlvin Chang li t2, THREAD_CORE_LOCAL_SIZE 398b9807372SAlvin Chang /* tp = t2 * t0(hart index) + t1(thread_core_local) */ 399b9807372SAlvin Chang mul t2, t2, t0 400b9807372SAlvin Chang add tp, t2, t1 4015ee429d5SYu-Chien Peter Lin sw s0, THREAD_CORE_LOCAL_HART_ID(tp) 402b9807372SAlvin Chang sw t0, THREAD_CORE_LOCAL_HART_INDEX(tp) 403b9807372SAlvin Chang LDR sp, THREAD_CORE_LOCAL_TMP_STACK_VA_END(tp) 404b9807372SAlvin Chang#else 40593e54a63SMarouene Boubakri set_sp 40693e54a63SMarouene Boubakri set_tp 407b9807372SAlvin Chang#endif 40893e54a63SMarouene Boubakri cpu_is_ready 40993e54a63SMarouene Boubakri 41093e54a63SMarouene Boubakri jal boot_init_secondary 41163bfec5eSAlvin Chang#ifdef CFG_RISCV_WITH_M_MODE_SM 41263bfec5eSAlvin Chang /* Return to untrusted domain */ 41363bfec5eSAlvin Chang li a0, TEEABI_OPTEED_RETURN_ON_DONE 4141eef6015SAlvin Chang li a1, 0 4151eef6015SAlvin Chang li a2, 0 4161eef6015SAlvin Chang li a3, 0 4171eef6015SAlvin Chang li a4, 0 4181eef6015SAlvin Chang li a5, 0 41963bfec5eSAlvin Chang j thread_return_to_udomain 42063bfec5eSAlvin Chang#endif 42193e54a63SMarouene Boubakri j . 42293e54a63SMarouene BoubakriEND_FUNC reset_secondary 42393e54a63SMarouene Boubakri 42493e54a63SMarouene BoubakriLOCAL_FUNC unhandled_cpu , : 42593e54a63SMarouene Boubakri wfi 42693e54a63SMarouene Boubakri j unhandled_cpu 42793e54a63SMarouene BoubakriEND_FUNC unhandled_cpu 42893e54a63SMarouene Boubakri 429ca71b6faSYu-Chien Peter Lin#if defined(CFG_CORE_ASLR) 430ca71b6faSYu-Chien Peter Lin/* 431ca71b6faSYu-Chien Peter Lin * void relocate(unsigned long offset); 432ca71b6faSYu-Chien Peter Lin * 433ca71b6faSYu-Chien Peter Lin * This function updates dynamic relocations. 434ca71b6faSYu-Chien Peter Lin */ 435ca71b6faSYu-Chien Peter LinLOCAL_FUNC relocate , : 436ca71b6faSYu-Chien Peter Lin /* 437ca71b6faSYu-Chien Peter Lin * a0 holds relocate offset 438ca71b6faSYu-Chien Peter Lin */ 439ca71b6faSYu-Chien Peter Lin la t0, __rel_dyn_start 440ca71b6faSYu-Chien Peter Lin la t1, __rel_dyn_end 441ca71b6faSYu-Chien Peter Lin beq t0, t1, 5f 442ca71b6faSYu-Chien Peter Lin2: 443ca71b6faSYu-Chien Peter Lin LDR t5, RISCV_XLEN_BYTES(t0) /* t5: relocation info:type */ 444ca71b6faSYu-Chien Peter Lin li t3, R_RISCV_RELATIVE 445ca71b6faSYu-Chien Peter Lin bne t5, t3, 3f 446ca71b6faSYu-Chien Peter Lin LDR t3, 0(t0) /* t3: offset */ 447ca71b6faSYu-Chien Peter Lin LDR t5, (RISCV_XLEN_BYTES * 2)(t0) /* t5: addend */ 448ca71b6faSYu-Chien Peter Lin add t5, t5, a0 /* t5: add ASLR offset */ 449ca71b6faSYu-Chien Peter Lin STR t5, 0(t3) /* update address */ 450ca71b6faSYu-Chien Peter Lin j 4f 451ca71b6faSYu-Chien Peter Lin 452ca71b6faSYu-Chien Peter Lin3: 453ca71b6faSYu-Chien Peter Lin la t4, __dyn_sym_start 454ca71b6faSYu-Chien Peter Lin srli t6, t5, SYM_INDEX /* t6: sym table index */ 455ca71b6faSYu-Chien Peter Lin andi t5, t5, 0xFF /* t5: relocation type */ 456ca71b6faSYu-Chien Peter Lin li t3, RELOC_TYPE 457ca71b6faSYu-Chien Peter Lin bne t5, t3, 4f 458ca71b6faSYu-Chien Peter Lin 459ca71b6faSYu-Chien Peter Lin /* address R_RISCV_64 or R_RISCV_32 cases */ 460ca71b6faSYu-Chien Peter Lin LDR t3, 0(t0) 461ca71b6faSYu-Chien Peter Lin li t5, SYM_SIZE 462ca71b6faSYu-Chien Peter Lin mul t6, t6, t5 463ca71b6faSYu-Chien Peter Lin add t5, t4, t6 464ca71b6faSYu-Chien Peter Lin LDR t6, (RISCV_XLEN_BYTES * 2)(t0) /* t6: addend */ 465ca71b6faSYu-Chien Peter Lin LDR t5, RISCV_XLEN_BYTES(t5) /* t5: sym value */ 466ca71b6faSYu-Chien Peter Lin add t5, t5, t6 467ca71b6faSYu-Chien Peter Lin add t5, t5, a0 /* t5: add ASLR offset */ 468ca71b6faSYu-Chien Peter Lin STR t5, 0(t3) /* update address */ 469ca71b6faSYu-Chien Peter Lin 470ca71b6faSYu-Chien Peter Lin4: 471ca71b6faSYu-Chien Peter Lin addi t0, t0, (RISCV_XLEN_BYTES * 3) 472ca71b6faSYu-Chien Peter Lin blt t0, t1, 2b 473ca71b6faSYu-Chien Peter Lin5: 474ca71b6faSYu-Chien Peter Lin ret 475ca71b6faSYu-Chien Peter LinEND_FUNC relocate 476ca71b6faSYu-Chien Peter Lin#endif 477ca71b6faSYu-Chien Peter Lin 478c98d8011SYu-Chien Peter Lin/* 479c98d8011SYu-Chien Peter Lin * void enable_mmu(void); 480c98d8011SYu-Chien Peter Lin * 481c98d8011SYu-Chien Peter Lin * Initializes and enables the Memory Management Unit (MMU). 482c98d8011SYu-Chien Peter Lin * This function is designed to be called while executing in 483c98d8011SYu-Chien Peter Lin * an identity-mapped region, where physical and virtual 484c98d8011SYu-Chien Peter Lin * addresses are identical. When CFG_CORE_ASLR=y: 485c98d8011SYu-Chien Peter Lin * - Execution is switched to the new virtual address region, 486c98d8011SYu-Chien Peter Lin * based on the randomized offset. 487c98d8011SYu-Chien Peter Lin * - CPU registers (global pointer, thread pointer, stack 488c98d8011SYu-Chien Peter Lin * pointer, return address) are updated so execution 489c98d8011SYu-Chien Peter Lin * continue correctly in a new address space. 490c98d8011SYu-Chien Peter Lin */ 491c98d8011SYu-Chien Peter LinLOCAL_FUNC enable_mmu , : , .identity_map 492c98d8011SYu-Chien Peter Lin /* Set SATP from boot_mmu_config.satp[hartidx] */ 493c98d8011SYu-Chien Peter Lin csrr a0, CSR_XSCRATCH 494c98d8011SYu-Chien Peter Lin la a1, boot_mmu_config 495c98d8011SYu-Chien Peter Lin LDR a3, CORE_MMU_CONFIG_MAP_OFFSET(a1) 496c98d8011SYu-Chien Peter Lin addi a1, a1, CORE_MMU_CONFIG_SATP 497c98d8011SYu-Chien Peter Lin li a2, CORE_MMU_CONFIG_SATP_SIZE 498c98d8011SYu-Chien Peter Lin mul a0, a0, a2 499c98d8011SYu-Chien Peter Lin add a1, a1, a0 500c98d8011SYu-Chien Peter Lin LDR a2, 0(a1) 501c98d8011SYu-Chien Peter Lin csrw CSR_SATP, a2 502c98d8011SYu-Chien Peter Lin sfence.vma zero, zero 503c98d8011SYu-Chien Peter Lin#ifdef CFG_CORE_ASLR 504c98d8011SYu-Chien Peter Lin /* Update CPU registers with the ASLR offset */ 505c98d8011SYu-Chien Peter Lin add gp, gp, a3 506c98d8011SYu-Chien Peter Lin add tp, tp, a3 507c98d8011SYu-Chien Peter Lin add sp, sp, a3 508c98d8011SYu-Chien Peter Lin add ra, ra, a3 509c98d8011SYu-Chien Peter Lin#endif 510c98d8011SYu-Chien Peter Lin ret 511c98d8011SYu-Chien Peter LinEND_FUNC enable_mmu 512c98d8011SYu-Chien Peter Lin 513058cf712SAlvin Chang .section .identity_map.data 514058cf712SAlvin Chang .balign 8 515058cf712SAlvin ChangLOCAL_DATA hart_lottery , : 516058cf712SAlvin Chang /* The hart who first increments this variable will be primary hart. */ 517058cf712SAlvin Chang .word 0 518058cf712SAlvin ChangEND_DATA hart_lottery 519058cf712SAlvin Chang 52093e54a63SMarouene Boubakri#ifdef CFG_BOOT_SYNC_CPU 52193e54a63SMarouene BoubakriLOCAL_DATA sem_cpu_sync_start , : 52293e54a63SMarouene Boubakri .word sem_cpu_sync 52393e54a63SMarouene BoubakriEND_DATA sem_cpu_sync_start 52493e54a63SMarouene Boubakri 52593e54a63SMarouene BoubakriLOCAL_DATA sem_cpu_sync_end , : 52693e54a63SMarouene Boubakri .word sem_cpu_sync + (CFG_TEE_CORE_NB_CORE << 2) 52793e54a63SMarouene BoubakriEND_DATA sem_cpu_sync_end 52893e54a63SMarouene Boubakri#endif 52993e54a63SMarouene Boubakri 530bb538722SAlvin Chang#if !defined(CFG_DYN_CONFIG) 53193e54a63SMarouene BoubakriLOCAL_DATA stack_tmp_rel , : 53293e54a63SMarouene Boubakri .word stack_tmp - stack_tmp_rel - STACK_TMP_GUARD 53393e54a63SMarouene BoubakriEND_DATA stack_tmp_rel 534b9807372SAlvin Chang#endif 53593e54a63SMarouene Boubakri 536e99612acSYu-Chien Peter Lin .section .identity_map.data 53793e54a63SMarouene Boubakri .balign 8 538e99612acSYu-Chien Peter LinDATA boot_mmu_config , : /* struct core_mmu_config */ 53993e54a63SMarouene Boubakri .skip CORE_MMU_CONFIG_SIZE 54093e54a63SMarouene BoubakriEND_DATA boot_mmu_config 541