diff --git a/arch/Kconfig b/arch/Kconfig index 133e14656fd..555b623dfba 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -65,6 +65,7 @@ config RISCV bool select ARCH_IS_SET select HAS_DTS + select ARCH_HAS_THREAD_LOCAL_STORAGE imply XIP help RISCV architecture diff --git a/arch/riscv/core/CMakeLists.txt b/arch/riscv/core/CMakeLists.txt index 70287b56aff..5680cc5ae1c 100644 --- a/arch/riscv/core/CMakeLists.txt +++ b/arch/riscv/core/CMakeLists.txt @@ -14,3 +14,4 @@ zephyr_library_sources( ) zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c) +zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c) diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index 96a393c1504..2fc00fc3ef1 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -30,6 +30,11 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, stack_init->a1 = (ulong_t)p1; stack_init->a2 = (ulong_t)p2; stack_init->a3 = (ulong_t)p3; + +#ifdef CONFIG_THREAD_LOCAL_STORAGE + stack_init->tp = (ulong_t)thread->tls; +#endif + /* * Following the RISC-V architecture, * the MSTATUS register (used to globally enable/disable interrupt), diff --git a/arch/riscv/core/tls.c b/arch/riscv/core/tls.c new file mode 100644 index 00000000000..b533ec60fa0 --- /dev/null +++ b/arch/riscv/core/tls.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + /* + * TLS area for RISC-V is simple without any extra + * data. + */ + + /* + * Since we are populating things backwards, + * setup the TLS data/bss area first. + */ + stack_ptr -= z_tls_data_size(); + z_tls_copy(stack_ptr); + + /* + * Set thread TLS pointer which is used in + * context switch to point to TLS area. + */ + new_thread->tls = POINTER_TO_UINT(stack_ptr); + + return z_tls_data_size(); +} diff --git a/include/arch/riscv/common/linker.ld b/include/arch/riscv/common/linker.ld index dcb1e15b210..0093419502b 100644 --- a/include/arch/riscv/common/linker.ld +++ b/include/arch/riscv/common/linker.ld @@ -111,6 +111,7 @@ SECTIONS _image_text_end = .; #include +#include SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) { diff --git a/soc/riscv/openisa_rv32m1/linker.ld b/soc/riscv/openisa_rv32m1/linker.ld index d775450197e..790782c973a 100644 --- a/soc/riscv/openisa_rv32m1/linker.ld +++ b/soc/riscv/openisa_rv32m1/linker.ld @@ -122,6 +122,7 @@ SECTIONS _image_rodata_start = .; #include +#include SECTION_PROLOGUE(_RODATA_SECTION_NAME,,) {