From 022851aba54d32831feaff13deb3d9943e130eee Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 28 Jan 2014 12:10:08 +0100 Subject: Add thread-local storage (TLS) support Tested and implemented on ARM, m68k, PowerPC and SPARC. Other architectures need more work. --- cpukit/score/cpu/m68k/Makefile.am | 1 + cpukit/score/cpu/m68k/__m68k_read_tp.c | 36 +++++++++++++++++++++++++++++++++ cpukit/score/cpu/m68k/cpu.c | 27 +++++++++++++++++++++++++ cpukit/score/cpu/m68k/rtems/score/cpu.h | 33 +++++++++--------------------- 4 files changed, 73 insertions(+), 24 deletions(-) create mode 100644 cpukit/score/cpu/m68k/__m68k_read_tp.c (limited to 'cpukit/score/cpu/m68k') 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 + * + * + * 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 +#include + +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 #include +#include #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 */ -- cgit v1.2.3