summaryrefslogtreecommitdiffstats
path: root/cpukit/score/cpu
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-01-28 12:10:08 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-04 10:06:35 +0100
commit022851aba54d32831feaff13deb3d9943e130eee (patch)
treec1d6a8404dae393bd147790f6a9cf09c2f327b5a /cpukit/score/cpu
parentbsps: Thread-local storage (TLS) for linkcmds (diff)
downloadrtems-022851aba54d32831feaff13deb3d9943e130eee.tar.bz2
Add thread-local storage (TLS) support
Tested and implemented on ARM, m68k, PowerPC and SPARC. Other architectures need more work.
Diffstat (limited to 'cpukit/score/cpu')
-rw-r--r--cpukit/score/cpu/arm/Makefile.am2
-rw-r--r--cpukit/score/cpu/arm/__aeabi_read_tp.c44
-rw-r--r--cpukit/score/cpu/arm/__tls_get_addr.c35
-rw-r--r--cpukit/score/cpu/arm/armv7m-context-initialize.c8
-rw-r--r--cpukit/score/cpu/arm/cpu.c20
-rw-r--r--cpukit/score/cpu/arm/cpu_asm.S10
-rw-r--r--cpukit/score/cpu/arm/rtems/score/arm.h5
-rw-r--r--cpukit/score/cpu/arm/rtems/score/cpu.h10
-rw-r--r--cpukit/score/cpu/avr/rtems/score/cpu.h3
-rw-r--r--cpukit/score/cpu/bfin/cpu.c3
-rw-r--r--cpukit/score/cpu/bfin/rtems/score/cpu.h4
-rw-r--r--cpukit/score/cpu/h8300/rtems/score/cpu.h2
-rw-r--r--cpukit/score/cpu/i386/rtems/score/cpu.h2
-rw-r--r--cpukit/score/cpu/lm32/rtems/score/cpu.h2
-rw-r--r--cpukit/score/cpu/m32c/context_init.c3
-rw-r--r--cpukit/score/cpu/m32c/rtems/score/cpu.h4
-rw-r--r--cpukit/score/cpu/m32r/context_init.c3
-rw-r--r--cpukit/score/cpu/m32r/rtems/score/cpu.h4
-rw-r--r--cpukit/score/cpu/m68k/Makefile.am1
-rw-r--r--cpukit/score/cpu/m68k/__m68k_read_tp.c36
-rw-r--r--cpukit/score/cpu/m68k/cpu.c27
-rw-r--r--cpukit/score/cpu/m68k/rtems/score/cpu.h33
-rw-r--r--cpukit/score/cpu/mips/cpu.c3
-rw-r--r--cpukit/score/cpu/mips/rtems/score/cpu.h3
-rw-r--r--cpukit/score/cpu/moxie/rtems/score/cpu.h2
-rw-r--r--cpukit/score/cpu/nios2/nios2-context-initialize.c3
-rw-r--r--cpukit/score/cpu/nios2/rtems/score/cpu.h4
-rw-r--r--cpukit/score/cpu/no_cpu/rtems/score/cpu.h3
-rw-r--r--cpukit/score/cpu/powerpc/rtems/score/cpu.h3
-rw-r--r--cpukit/score/cpu/sh/cpu.c3
-rw-r--r--cpukit/score/cpu/sh/rtems/score/cpu.h3
-rw-r--r--cpukit/score/cpu/sparc/cpu.c10
-rw-r--r--cpukit/score/cpu/sparc/rtems/score/cpu.h4
-rw-r--r--cpukit/score/cpu/sparc64/cpu.c10
-rw-r--r--cpukit/score/cpu/sparc64/rtems/score/cpu.h3
-rw-r--r--cpukit/score/cpu/v850/cpu.c3
-rw-r--r--cpukit/score/cpu/v850/rtems/score/cpu.h4
37 files changed, 270 insertions, 52 deletions
diff --git a/cpukit/score/cpu/arm/Makefile.am b/cpukit/score/cpu/arm/Makefile.am
index edd72480bd..fe97e03e29 100644
--- a/cpukit/score/cpu/arm/Makefile.am
+++ b/cpukit/score/cpu/arm/Makefile.am
@@ -15,6 +15,8 @@ include_rtems_score_HEADERS += rtems/score/cpusmplock.h
noinst_LIBRARIES = libscorecpu.a
libscorecpu_a_CPPFLAGS = $(AM_CPPFLAGS)
libscorecpu_a_SOURCES =
+libscorecpu_a_SOURCES += __aeabi_read_tp.c
+libscorecpu_a_SOURCES += __tls_get_addr.c
libscorecpu_a_SOURCES += cpu.c
libscorecpu_a_SOURCES += cpu_asm.S
libscorecpu_a_SOURCES += arm-context-validate.S
diff --git a/cpukit/score/cpu/arm/__aeabi_read_tp.c b/cpukit/score/cpu/arm/__aeabi_read_tp.c
new file mode 100644
index 0000000000..afdfd99d8b
--- /dev/null
+++ b/cpukit/score/cpu/arm/__aeabi_read_tp.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/thread.h>
+#include <rtems/score/percpu.h>
+
+#ifndef RTEMS_SMP
+
+void __attribute__((naked)) __aeabi_read_tp(void);
+
+void __attribute__((naked)) __aeabi_read_tp(void)
+{
+ __asm__ volatile (
+ "ldr r0, =_Per_CPU_Information\n"
+ "ldr r0, [r0, %[executingoff]]\n"
+#if defined(__thumb__) && !defined(__thumb2__)
+ "add r0, %[tlsareaoff]\n"
+ "ldr r0, [r0]\n"
+#else
+ "ldr r0, [r0, %[tlsareaoff]]\n"
+#endif
+ "bx lr\n"
+ :
+ : [executingoff] "I" (offsetof(Per_CPU_Control, executing)),
+ [tlsareaoff] "I" (offsetof(Thread_Control, Start.tls_area))
+ );
+}
+
+#endif /* RTEMS_SMP */
diff --git a/cpukit/score/cpu/arm/__tls_get_addr.c b/cpukit/score/cpu/arm/__tls_get_addr.c
new file mode 100644
index 0000000000..cd046518e1
--- /dev/null
+++ b/cpukit/score/cpu/arm/__tls_get_addr.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/thread.h>
+#include <rtems/score/tls.h>
+
+#include <assert.h>
+
+void *__tls_get_addr(const TLS_Index *ti);
+
+void *__tls_get_addr(const TLS_Index *ti)
+{
+ const Thread_Control *executing = _Thread_Get_executing();
+ void *tls_block = (char *) executing->Start.tls_area
+ + _TLS_Get_thread_control_block_area_size( (uintptr_t) _TLS_Alignment );
+
+ assert(ti->module == 1);
+
+ return (char *) tls_block + ti->offset;
+}
diff --git a/cpukit/score/cpu/arm/armv7m-context-initialize.c b/cpukit/score/cpu/arm/armv7m-context-initialize.c
index 892df4d8c8..13aa0a9b19 100644
--- a/cpukit/score/cpu/arm/armv7m-context-initialize.c
+++ b/cpukit/score/cpu/arm/armv7m-context-initialize.c
@@ -26,6 +26,7 @@
#include <rtems/score/armv7m.h>
#include <rtems/score/thread.h>
+#include <rtems/score/tls.h>
#ifdef ARM_MULTILIB_ARCH_V7M
@@ -35,7 +36,8 @@ void _CPU_Context_Initialize(
size_t stack_area_size,
uint32_t new_level,
void (*entry_point)( void ),
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
char *stack_area_end = (char *) stack_area_begin + stack_area_size;
@@ -44,6 +46,10 @@ void _CPU_Context_Initialize(
context->register_lr = entry_point;
context->register_sp = stack_area_end;
+
+ if ( tls_area != NULL ) {
+ _TLS_TCB_at_area_begin_initialize( tls_area );
+ }
}
#endif /* ARM_MULTILIB_ARCH_V7M */
diff --git a/cpukit/score/cpu/arm/cpu.c b/cpukit/score/cpu/arm/cpu.c
index 1c1fe5d3de..c3f071df55 100644
--- a/cpukit/score/cpu/arm/cpu.c
+++ b/cpukit/score/cpu/arm/cpu.c
@@ -32,6 +32,7 @@
#include <rtems/score/isr.h>
#include <rtems/score/wkspace.h>
#include <rtems/score/thread.h>
+#include <rtems/score/tls.h>
#include <rtems/score/cpu.h>
#ifdef ARM_MULTILIB_VFP_D32
@@ -41,6 +42,14 @@
);
#endif
+#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
+ RTEMS_STATIC_ASSERT(
+ offsetof( Context_Control, thread_id )
+ == ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET,
+ ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET
+ );
+#endif
+
RTEMS_STATIC_ASSERT(
sizeof( CPU_Exception_frame ) == ARM_EXCEPTION_FRAME_SIZE,
ARM_EXCEPTION_FRAME_SIZE
@@ -71,13 +80,22 @@ void _CPU_Context_Initialize(
size_t stack_area_size,
uint32_t new_level,
void (*entry_point)( void ),
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
the_context->register_sp = (uint32_t) stack_area_begin + stack_area_size;
the_context->register_lr = (uint32_t) entry_point;
the_context->register_cpsr = ( ( new_level != 0 ) ? ARM_PSR_I : 0 )
| arm_cpu_mode;
+
+#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
+ the_context->thread_id = (uint32_t) tls_area;
+#endif
+
+ if ( tls_area != NULL ) {
+ _TLS_TCB_at_area_begin_initialize( tls_area );
+ }
}
/* Preprocessor magic for stringification of x */
diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S
index 7fb4062d50..1771ddd661 100644
--- a/cpukit/score/cpu/arm/cpu_asm.S
+++ b/cpukit/score/cpu/arm/cpu_asm.S
@@ -62,12 +62,22 @@ DEFINE_FUNCTION_ARM(_CPU_Context_switch)
vstm r3, {d8-d15}
#endif
+#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
+ mrc p15, 0, r3, c13, c0, 3
+ str r3, [r0, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
+#endif
+
/* Start restoring context */
_restore:
#ifdef ARM_MULTILIB_HAS_LOAD_STORE_EXCLUSIVE
clrex
#endif
+#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
+ ldr r3, [r1, #ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET]
+ mcr p15, 0, r3, c13, c0, 3
+#endif
+
#ifdef ARM_MULTILIB_VFP_D32
add r3, r1, #ARM_CONTEXT_CONTROL_D8_OFFSET
vldm r3, {d8-d15}
diff --git a/cpukit/score/cpu/arm/rtems/score/arm.h b/cpukit/score/cpu/arm/rtems/score/arm.h
index 608f753d11..3e428f9201 100644
--- a/cpukit/score/cpu/arm/rtems/score/arm.h
+++ b/cpukit/score/cpu/arm/rtems/score/arm.h
@@ -44,6 +44,11 @@ extern "C" {
#define ARM_MULTILIB_HAS_LOAD_STORE_EXCLUSIVE
#endif
+#if defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__)
+ #define ARM_MULTILIB_HAS_THREAD_ID_REGISTER
+#endif
+
#if defined(__ARM_NEON__)
#define ARM_MULTILIB_VFP_D32
#elif !defined(__SOFTFP__)
diff --git a/cpukit/score/cpu/arm/rtems/score/cpu.h b/cpukit/score/cpu/arm/rtems/score/cpu.h
index 2d9b5d50b6..216f39f862 100644
--- a/cpukit/score/cpu/arm/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/rtems/score/cpu.h
@@ -212,6 +212,10 @@
/** @} */
+#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
+ #define ARM_CONTEXT_CONTROL_THREAD_ID_OFFSET 44
+#endif
+
#ifdef ARM_MULTILIB_VFP_D32
#define ARM_CONTEXT_CONTROL_D8_OFFSET 48
#endif
@@ -267,6 +271,9 @@ typedef struct {
#else
void *register_sp;
#endif
+#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER
+ uint32_t thread_id;
+#endif
#ifdef ARM_MULTILIB_VFP_D32
uint64_t register_d8;
uint64_t register_d9;
@@ -400,7 +407,8 @@ void _CPU_Context_Initialize(
size_t stack_area_size,
uint32_t new_level,
void (*entry_point)( void ),
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
#define _CPU_Context_Get_SP( _context ) \
diff --git a/cpukit/score/cpu/avr/rtems/score/cpu.h b/cpukit/score/cpu/avr/rtems/score/cpu.h
index b67b2416a5..f82b7637d3 100644
--- a/cpukit/score/cpu/avr/rtems/score/cpu.h
+++ b/cpukit/score/cpu/avr/rtems/score/cpu.h
@@ -963,7 +963,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/*
diff --git a/cpukit/score/cpu/bfin/cpu.c b/cpukit/score/cpu/bfin/cpu.c
index 05b9243513..268848e02b 100644
--- a/cpukit/score/cpu/bfin/cpu.c
+++ b/cpukit/score/cpu/bfin/cpu.c
@@ -186,7 +186,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
uint32_t stack_high; /* highest "stack aligned" address */
diff --git a/cpukit/score/cpu/bfin/rtems/score/cpu.h b/cpukit/score/cpu/bfin/rtems/score/cpu.h
index 1af3f81f81..a8c60a5c44 100644
--- a/cpukit/score/cpu/bfin/rtems/score/cpu.h
+++ b/cpukit/score/cpu/bfin/rtems/score/cpu.h
@@ -817,6 +817,7 @@ uint32_t _CPU_ISR_Get_level( void );
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
+ * @param[in] tls_area is the thread-local storage (TLS) area
*
* Port Specific Information:
*
@@ -828,7 +829,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/**
diff --git a/cpukit/score/cpu/h8300/rtems/score/cpu.h b/cpukit/score/cpu/h8300/rtems/score/cpu.h
index f75f2e5825..66774d4039 100644
--- a/cpukit/score/cpu/h8300/rtems/score/cpu.h
+++ b/cpukit/score/cpu/h8300/rtems/score/cpu.h
@@ -756,7 +756,7 @@ uint32_t _CPU_ISR_Get_level( void );
#define CPU_CCR_INTERRUPTS_OFF 0x00
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
+ _isr, _entry_point, _is_fp, _tls_area ) \
/* Locate Me */ \
do { \
uintptr_t _stack; \
diff --git a/cpukit/score/cpu/i386/rtems/score/cpu.h b/cpukit/score/cpu/i386/rtems/score/cpu.h
index 43422ed9d7..dd06059853 100644
--- a/cpukit/score/cpu/i386/rtems/score/cpu.h
+++ b/cpukit/score/cpu/i386/rtems/score/cpu.h
@@ -443,7 +443,7 @@ uint32_t _CPU_ISR_Get_level( void );
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
+ _isr, _entry_point, _is_fp, _tls_area ) \
do { \
uint32_t _stack; \
\
diff --git a/cpukit/score/cpu/lm32/rtems/score/cpu.h b/cpukit/score/cpu/lm32/rtems/score/cpu.h
index 95553efa48..4699c1a226 100644
--- a/cpukit/score/cpu/lm32/rtems/score/cpu.h
+++ b/cpukit/score/cpu/lm32/rtems/score/cpu.h
@@ -823,7 +823,7 @@ uint32_t _CPU_ISR_Get_level( void );
extern char _gp[];
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
+ _isr, _entry_point, _is_fp, _tls_area ) \
do { \
uint32_t _stack = (uint32_t)(_stack_base) + (_size) - 4; \
(_the_context)->gp = (uint32_t)_gp; \
diff --git a/cpukit/score/cpu/m32c/context_init.c b/cpukit/score/cpu/m32c/context_init.c
index d7c1c5dd92..b2edcf8a21 100644
--- a/cpukit/score/cpu/m32c/context_init.c
+++ b/cpukit/score/cpu/m32c/context_init.c
@@ -50,7 +50,8 @@ void _CPU_Context_Initialize(
size_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
void *stackEnd = stack_base;
diff --git a/cpukit/score/cpu/m32c/rtems/score/cpu.h b/cpukit/score/cpu/m32c/rtems/score/cpu.h
index 5841885c8e..681fb4bcd0 100644
--- a/cpukit/score/cpu/m32c/rtems/score/cpu.h
+++ b/cpukit/score/cpu/m32c/rtems/score/cpu.h
@@ -809,6 +809,7 @@ uint32_t _CPU_ISR_Get_level( void );
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
+ * @param[in] tls_area is the thread-local storage (TLS) area
*
* Port Specific Information:
*
@@ -820,7 +821,8 @@ void _CPU_Context_Initialize(
size_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/**
diff --git a/cpukit/score/cpu/m32r/context_init.c b/cpukit/score/cpu/m32r/context_init.c
index bdfd758d91..d8ecc5309d 100644
--- a/cpukit/score/cpu/m32r/context_init.c
+++ b/cpukit/score/cpu/m32r/context_init.c
@@ -33,7 +33,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
void *stackEnd = stack_base;
diff --git a/cpukit/score/cpu/m32r/rtems/score/cpu.h b/cpukit/score/cpu/m32r/rtems/score/cpu.h
index 0fea7bdc4b..95a897a1e2 100644
--- a/cpukit/score/cpu/m32r/rtems/score/cpu.h
+++ b/cpukit/score/cpu/m32r/rtems/score/cpu.h
@@ -828,6 +828,7 @@ uint32_t _CPU_ISR_Get_level( void );
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
+ * @param[in] tls_area is the thread-local storage (TLS) area
*
* Port Specific Information:
*
@@ -839,7 +840,8 @@ void _CPU_Context_Initialize(
size_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/**
diff --git a/cpukit/score/cpu/m68k/Makefile.am b/cpukit/score/cpu/m68k/Makefile.am
index 863a071499..9d8d333dab 100644
--- a/cpukit/score/cpu/m68k/Makefile.am
+++ b/cpukit/score/cpu/m68k/Makefile.am
@@ -20,6 +20,7 @@ include_rtems_score_HEADERS += rtems/score/cpuatomic.h
libscorecpu_a_SOURCES = cpu.c cpu_asm.S
libscorecpu_a_SOURCES += m68k-exception-frame-print.c
+libscorecpu_a_SOURCES += __m68k_read_tp.c
include $(srcdir)/preinstall.am
include $(top_srcdir)/automake/local.am
diff --git a/cpukit/score/cpu/m68k/__m68k_read_tp.c b/cpukit/score/cpu/m68k/__m68k_read_tp.c
new file mode 100644
index 0000000000..3e024a84b3
--- /dev/null
+++ b/cpukit/score/cpu/m68k/__m68k_read_tp.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/thread.h>
+#include <rtems/score/tls.h>
+
+void __m68k_read_tp(void);
+
+void __m68k_read_tp(void)
+{
+ const Thread_Control *executing = _Thread_Get_executing();
+ void *tp = (char *) executing->Start.tls_area +
+ _TLS_Get_thread_control_block_area_size((uintptr_t) _TLS_Alignment)
+ + 0x7000;
+
+ __asm__ volatile (
+ "move.l %0, %%a0"
+ :
+ : "d" (tp)
+ );
+}
diff --git a/cpukit/score/cpu/m68k/cpu.c b/cpukit/score/cpu/m68k/cpu.c
index 3776345769..589d099f9d 100644
--- a/cpukit/score/cpu/m68k/cpu.c
+++ b/cpukit/score/cpu/m68k/cpu.c
@@ -19,6 +19,7 @@
#include <rtems/system.h>
#include <rtems/score/isr.h>
+#include <rtems/score/tls.h>
#if defined( __mcoldfire__ ) && ( M68K_HAS_FPU == 1 )
uint32_t _CPU_cacr_shadow;
@@ -181,3 +182,29 @@ void _CPU_Context_restore_fp (Context_Control_fp **fp_context_ptr)
_fpCCR = *fp;
}
#endif
+
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ void *stack_area_begin,
+ size_t stack_area_size,
+ uint32_t new_level,
+ void (*entry_point)( void ),
+ bool is_fp,
+ void *tls_area
+)
+{
+ uint32_t stack;
+
+ the_context->sr = 0x3000 | (new_level << 8);
+ stack = (uint32_t)stack_area_begin + stack_area_size - 4;
+ the_context->a7_msp = (void *)stack;
+ *(void **)stack = (void *)entry_point;
+
+#if (defined(__mcoldfire__) && ( M68K_HAS_FPU == 1 ))
+ the_context->fpu_dis = is_fp ? 0x00 : 0x10;
+#endif
+
+ if ( tls_area != NULL ) {
+ _TLS_TCB_before_tls_block_initialize( tls_area );
+ }
+}
diff --git a/cpukit/score/cpu/m68k/rtems/score/cpu.h b/cpukit/score/cpu/m68k/rtems/score/cpu.h
index ccec3a6a64..9981f5393d 100644
--- a/cpukit/score/cpu/m68k/rtems/score/cpu.h
+++ b/cpukit/score/cpu/m68k/rtems/score/cpu.h
@@ -448,30 +448,15 @@ uint32_t _CPU_ISR_Get_level( void );
* + initialize an FP context area
*/
-#if (defined(__mcoldfire__) && ( M68K_HAS_FPU == 1 ))
-#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
- do { \
- uint32_t _stack; \
- \
- (_the_context)->sr = 0x3000 | ((_isr) << 8); \
- _stack = (uint32_t)(_stack_base) + (_size) - 4; \
- (_the_context)->a7_msp = (void *)_stack; \
- *(void **)_stack = (void *)(_entry_point); \
- (_the_context)->fpu_dis = (_is_fp == TRUE) ? 0x00 : 0x10; \
- } while ( 0 )
-#else
-#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
- do { \
- uint32_t _stack; \
- \
- (_the_context)->sr = 0x3000 | ((_isr) << 8); \
- _stack = (uint32_t)(_stack_base) + (_size) - 4; \
- (_the_context)->a7_msp = (void *)_stack; \
- *(void **)_stack = (void *)(_entry_point); \
- } while ( 0 )
-#endif
+void _CPU_Context_Initialize(
+ Context_Control *the_context,
+ void *stack_area_begin,
+ size_t stack_area_size,
+ uint32_t new_level,
+ void (*entry_point)( void ),
+ bool is_fp,
+ void *tls_area
+);
/* end of Context handler macros */
diff --git a/cpukit/score/cpu/mips/cpu.c b/cpukit/score/cpu/mips/cpu.c
index 5f7abeb368..3be5df361a 100644
--- a/cpukit/score/cpu/mips/cpu.c
+++ b/cpukit/score/cpu/mips/cpu.c
@@ -173,7 +173,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
uintptr_t stack_tmp;
diff --git a/cpukit/score/cpu/mips/rtems/score/cpu.h b/cpukit/score/cpu/mips/rtems/score/cpu.h
index 1d1449ce6f..629996117a 100644
--- a/cpukit/score/cpu/mips/rtems/score/cpu.h
+++ b/cpukit/score/cpu/mips/rtems/score/cpu.h
@@ -858,7 +858,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
diff --git a/cpukit/score/cpu/moxie/rtems/score/cpu.h b/cpukit/score/cpu/moxie/rtems/score/cpu.h
index 309110a399..36a956cdc8 100644
--- a/cpukit/score/cpu/moxie/rtems/score/cpu.h
+++ b/cpukit/score/cpu/moxie/rtems/score/cpu.h
@@ -651,7 +651,7 @@ uint32_t _CPU_ISR_Get_level( void );
#define CPU_CCR_INTERRUPTS_OFF 0x00
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
+ _isr, _entry_point, _is_fp, _tls_area ) \
/* Locate Me */ \
do { \
uintptr_t _stack; \
diff --git a/cpukit/score/cpu/nios2/nios2-context-initialize.c b/cpukit/score/cpu/nios2/nios2-context-initialize.c
index e74e04f356..6b884d0085 100644
--- a/cpukit/score/cpu/nios2/nios2-context-initialize.c
+++ b/cpukit/score/cpu/nios2/nios2-context-initialize.c
@@ -27,7 +27,8 @@ void _CPU_Context_Initialize(
size_t stack_area_size,
uint32_t new_level,
void (*entry_point)( void ),
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
const Nios2_MPU_Configuration *mpu_config = _Nios2_MPU_Get_configuration();
diff --git a/cpukit/score/cpu/nios2/rtems/score/cpu.h b/cpukit/score/cpu/nios2/rtems/score/cpu.h
index e0dfd9fd36..bdd8f57e96 100644
--- a/cpukit/score/cpu/nios2/rtems/score/cpu.h
+++ b/cpukit/score/cpu/nios2/rtems/score/cpu.h
@@ -295,6 +295,7 @@ uint32_t _CPU_ISR_Get_level( void );
* @param[in] new_level is the interrupt level for the task
* @param[in] entry_point is the task's entry point
* @param[in] is_fp is set to @c true if the task is a floating point task
+ * @param[in] tls_area is the thread-local storage (TLS) area
*/
void _CPU_Context_Initialize(
Context_Control *context,
@@ -302,7 +303,8 @@ void _CPU_Context_Initialize(
size_t stack_area_size,
uint32_t new_level,
void (*entry_point)( void ),
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
#define _CPU_Context_Restart_self( _the_context ) \
diff --git a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
index f1f02edaf0..783da76dee 100644
--- a/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
+++ b/cpukit/score/cpu/no_cpu/rtems/score/cpu.h
@@ -932,13 +932,14 @@ uint32_t _CPU_ISR_Get_level( void );
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
+ * @param[in] _tls_area The thread-local storage (TLS) area.
*
* Port Specific Information:
*
* XXX document implementation including references if appropriate
*/
#define _CPU_Context_Initialize( _the_context, _stack_base, _size, \
- _isr, _entry_point, _is_fp ) \
+ _isr, _entry_point, _is_fp, _tls_area ) \
{ \
}
diff --git a/cpukit/score/cpu/powerpc/rtems/score/cpu.h b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
index 6263d34fb7..8eb2327b93 100644
--- a/cpukit/score/cpu/powerpc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/powerpc/rtems/score/cpu.h
@@ -797,7 +797,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/*
diff --git a/cpukit/score/cpu/sh/cpu.c b/cpukit/score/cpu/sh/cpu.c
index 57d6ffc6db..be3fedd04d 100644
--- a/cpukit/score/cpu/sh/cpu.c
+++ b/cpukit/score/cpu/sh/cpu.c
@@ -211,7 +211,8 @@ void _CPU_Context_Initialize(
uint32_t _size,
uint32_t _isr,
void (*_entry_point)(void),
- int _is_fp )
+ int _is_fp,
+ void *_tls_base)
{
_the_context->r15 = (uint32_t *) ((uint32_t) (_stack_base) + (_size) );
#if defined(__sh1__) || defined(__sh2__) || defined(__SH2E__)
diff --git a/cpukit/score/cpu/sh/rtems/score/cpu.h b/cpukit/score/cpu/sh/rtems/score/cpu.h
index 41d96384de..ff9ad55ae4 100644
--- a/cpukit/score/cpu/sh/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sh/rtems/score/cpu.h
@@ -603,7 +603,8 @@ SCORE_EXTERN void _CPU_Context_Initialize(
uint32_t _size,
uint32_t _isr,
void (*_entry_point)(void),
- int _is_fp );
+ int _is_fp,
+ void *_tls_area );
/*
* This routine is responsible for somehow restarting the currently
diff --git a/cpukit/score/cpu/sparc/cpu.c b/cpukit/score/cpu/sparc/cpu.c
index 1865a21ee8..11e31f9d10 100644
--- a/cpukit/score/cpu/sparc/cpu.c
+++ b/cpukit/score/cpu/sparc/cpu.c
@@ -20,6 +20,7 @@
#include <rtems/system.h>
#include <rtems/score/isr.h>
#include <rtems/score/percpu.h>
+#include <rtems/score/tls.h>
#include <rtems/rtems/cache.h>
RTEMS_STATIC_ASSERT(
@@ -232,7 +233,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
uint32_t stack_high; /* highest "stack aligned" address */
@@ -285,4 +287,10 @@ void _CPU_Context_Initialize(
* thread can have an _ISR_Dispatch stack frame on its stack.
*/
the_context->isr_dispatch_disable = 0;
+
+ if ( tls_area != NULL ) {
+ void *tcb = _TLS_TCB_after_tls_block_initialize( tls_area );
+
+ the_context->g7 = (uintptr_t) tcb;
+ }
}
diff --git a/cpukit/score/cpu/sparc/rtems/score/cpu.h b/cpukit/score/cpu/sparc/rtems/score/cpu.h
index 690ddcf90c..ae893112f3 100644
--- a/cpukit/score/cpu/sparc/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc/rtems/score/cpu.h
@@ -1019,6 +1019,7 @@ uint32_t _CPU_ISR_Get_level( void );
* @param[in] new_level is the interrupt level for the task
* @param[in] entry_point is the task's entry point
* @param[in] is_fp is set to TRUE if the task is a floating point task
+ * @param[in] tls_area is the thread-local storage (TLS) area
*
* NOTE: Implemented as a subroutine for the SPARC port.
*/
@@ -1028,7 +1029,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/**
diff --git a/cpukit/score/cpu/sparc64/cpu.c b/cpukit/score/cpu/sparc64/cpu.c
index 94f9340614..d7c2f47904 100644
--- a/cpukit/score/cpu/sparc64/cpu.c
+++ b/cpukit/score/cpu/sparc64/cpu.c
@@ -20,6 +20,7 @@
#include <rtems/system.h>
#include <rtems/asm.h>
#include <rtems/score/isr.h>
+#include <rtems/score/tls.h>
#include <rtems/rtems/cache.h>
/*
@@ -65,7 +66,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
uint64_t stack_high; /* highest "stack aligned" address */
@@ -99,4 +101,10 @@ void _CPU_Context_Initialize(
* thread can have an _ISR_Dispatch stack frame on its stack.
*/
the_context->isr_dispatch_disable = 0;
+
+ if ( tls_area != NULL ) {
+ void *tcb = _TLS_TCB_after_tls_block_initialize( tls_area );
+
+ the_context->g7 = (uintptr_t) tcb;
+ }
}
diff --git a/cpukit/score/cpu/sparc64/rtems/score/cpu.h b/cpukit/score/cpu/sparc64/rtems/score/cpu.h
index 8d3e27318b..22ec97d17a 100644
--- a/cpukit/score/cpu/sparc64/rtems/score/cpu.h
+++ b/cpukit/score/cpu/sparc64/rtems/score/cpu.h
@@ -838,7 +838,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/*
diff --git a/cpukit/score/cpu/v850/cpu.c b/cpukit/score/cpu/v850/cpu.c
index 50065b6623..d4022f36a0 100644
--- a/cpukit/score/cpu/v850/cpu.c
+++ b/cpukit/score/cpu/v850/cpu.c
@@ -61,7 +61,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
)
{
uint32_t stack_high; /* highest "stack aligned" address */
diff --git a/cpukit/score/cpu/v850/rtems/score/cpu.h b/cpukit/score/cpu/v850/rtems/score/cpu.h
index 3e110b5776..f41bde0953 100644
--- a/cpukit/score/cpu/v850/rtems/score/cpu.h
+++ b/cpukit/score/cpu/v850/rtems/score/cpu.h
@@ -790,6 +790,7 @@ uint32_t _CPU_ISR_Get_level( void );
* point thread. This is typically only used on CPUs where the
* FPU may be easily disabled by software such as on the SPARC
* where the PSR contains an enable FPU bit.
+ * @param[in] tls_area is the thread-local storage (TLS) area
*
* Port Specific Information:
*
@@ -801,7 +802,8 @@ void _CPU_Context_Initialize(
uint32_t size,
uint32_t new_level,
void *entry_point,
- bool is_fp
+ bool is_fp,
+ void *tls_area
);
/**