sparc: add support for thread local storage
Adds the necessary bits to initialize TLS in the stack
area and sets up CPU registers during context switch. Register g7 is
used to point to the thread data. Thread data is accessed with negative
offsets from g7.
Signed-off-by: Martin Åberg <martin.aberg@gaisler.com>
diff --git a/arch/Kconfig b/arch/Kconfig
index 274d5bd..3934ce8 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -45,6 +45,7 @@
select BIG_ENDIAN
select ATOMIC_OPERATIONS_BUILTIN if SPARC_CASA
select ATOMIC_OPERATIONS_C if !SPARC_CASA
+ select ARCH_HAS_THREAD_LOCAL_STORAGE
help
SPARC architecture
diff --git a/arch/sparc/core/CMakeLists.txt b/arch/sparc/core/CMakeLists.txt
index 28b5559..82ff790 100644
--- a/arch/sparc/core/CMakeLists.txt
+++ b/arch/sparc/core/CMakeLists.txt
@@ -17,3 +17,4 @@
)
zephyr_library_sources_ifdef(CONFIG_IRQ_OFFLOAD irq_offload.c)
+zephyr_library_sources_ifdef(CONFIG_THREAD_LOCAL_STORAGE tls.c)
diff --git a/arch/sparc/core/switch.S b/arch/sparc/core/switch.S
index 17b12ce..1fe71ed 100644
--- a/arch/sparc/core/switch.S
+++ b/arch/sparc/core/switch.S
@@ -118,6 +118,9 @@
/* restore output registers */
ldd [%o0 + _thread_offset_to_o6], %o6
+#ifdef CONFIG_THREAD_LOCAL_STORAGE
+ ld [%o0 + _thread_offset_to_tls], %g7
+#endif
ld [%o0 + _thread_offset_to_psr], %g1 /* %g1 = new thread psr */
diff --git a/arch/sparc/core/tls.c b/arch/sparc/core/tls.c
new file mode 100644
index 0000000..8e9d5be
--- /dev/null
+++ b/arch/sparc/core/tls.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2019-2020 Cobham Gaisler AB
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#include <kernel.h>
+#include <kernel_structs.h>
+#include <kernel_internal.h>
+#include <kernel_tls.h>
+#include <app_memory/app_memdomain.h>
+#include <sys/util.h>
+
+size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr)
+{
+ new_thread->tls = POINTER_TO_UINT(stack_ptr);
+
+ stack_ptr -= z_tls_data_size();
+ z_tls_copy(stack_ptr);
+
+ return z_tls_data_size();
+}
diff --git a/include/arch/sparc/linker.ld b/include/arch/sparc/linker.ld
index f7b1fb0..486845d 100644
--- a/include/arch/sparc/linker.ld
+++ b/include/arch/sparc/linker.ld
@@ -42,6 +42,7 @@
_image_text_end = .;
#include <linker/common-rom.ld>
+#include <linker/thread-local-storage.ld>
SECTION_PROLOGUE(_RODATA_SECTION_NAME,,)
{