xref: /optee_os/core/arch/riscv/kernel/entry.S (revision f1651448a92150c573f763f95293fccaed3af843)
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