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 
arch_tls_stack_setup(struct k_thread * new_thread,char * stack_ptr)14 size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr)
15 {
16 	/*
17 	 * TLS area for ARM has some data fields following by
18 	 * thread data and bss. These fields are supposed to be
19 	 * used by toolchain and OS TLS code to aid in locating
20 	 * the TLS data/bss. Zephyr currently has no use for
21 	 * this so we can simply skip these. However, since GCC
22 	 * is generating code assuming these fields are there,
23 	 * we simply skip them when setting the TLS pointer.
24 	 */
25 
26 	/*
27 	 * Since we are populating things backwards,
28 	 * setup the TLS data/bss area first.
29 	 */
30 	stack_ptr -= z_tls_data_size();
31 	z_tls_copy(stack_ptr);
32 
33 	/* Skip two pointers due to toolchain */
34 	stack_ptr -= sizeof(uintptr_t) * 2;
35 
36 	/*
37 	 * Set thread TLS pointer which is used in
38 	 * context switch to point to TLS area.
39 	 */
40 	new_thread->tls = POINTER_TO_UINT(stack_ptr);
41 
42 	return (z_tls_data_size() + (sizeof(uintptr_t) * 2));
43 }
44