1 /*
2  * Copyright (c) 2020 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/kernel_structs.h>
9 #include <kernel_internal.h>
10 #include <kernel_tls.h>
11 #include <zephyr/app_memory/app_memdomain.h>
12 #include <zephyr/sys/util.h>
13 
14 #if XCHAL_HAVE_THREADPTR == 0
15 #error SoC does not support THREADPTR for thread local storage.
16 #endif
17 
arch_tls_stack_setup(struct k_thread * new_thread,char * stack_ptr)18 size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr)
19 {
20 	/*
21 	 * TLS area has some data fields following by
22 	 * thread data and bss. These fields are supposed to be
23 	 * used by toolchain and OS TLS code to aid in locating
24 	 * the TLS data/bss. Zephyr currently has no use for
25 	 * this so we can simply skip these. However, since GCC
26 	 * is generating code assuming these fields are there,
27 	 * we simply skip them when setting the TLS pointer.
28 	 */
29 
30 	/*
31 	 * Since we are populating things backwards,
32 	 * setup the TLS data/bss area first.
33 	 */
34 	stack_ptr -= z_tls_data_size();
35 	z_tls_copy(stack_ptr);
36 
37 	/* Skip two pointers due to toolchain */
38 	stack_ptr -= sizeof(uintptr_t) * 2;
39 
40 	/*
41 	 * Set thread TLS pointer which is used in
42 	 * context switch to point to TLS area.
43 	 */
44 	new_thread->tls = POINTER_TO_UINT(stack_ptr);
45 
46 	return (z_tls_data_size() + (sizeof(uintptr_t) * 2));
47 }
48