diff options
21 files changed, 223 insertions, 4 deletions
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h index ffdef2f30a..14836965ef 100644 --- a/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/aarch64/include/rtems/score/cpuimpl.h @@ -162,6 +162,15 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + __asm__ volatile ( + "msr TPIDR_EL0, %0" : : "r" ( context->thread_id ) : "memory" + ); +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h index 0ce347c86f..4f20113b71 100644 --- a/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/arm/include/rtems/score/cpuimpl.h @@ -160,6 +160,19 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ +#ifdef ARM_MULTILIB_HAS_THREAD_ID_REGISTER + __asm__ volatile ( + "mcr p15, 0, %0, c13, c0, 3" : : "r" ( context->thread_id ) : "memory" + ); +#else + (void) context; +#endif +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h index 1485abd365..91e57da4a0 100644 --- a/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/bfin/include/rtems/score/cpuimpl.h @@ -59,6 +59,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h index 31ec0ac8bb..71f2679dde 100644 --- a/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/i386/include/rtems/score/cpuimpl.h @@ -80,6 +80,32 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + uint32_t tmp; + uint32_t cpu_index; + +#ifdef RTEMS_SMP + cpu_index = _CPU_SMP_Get_current_processor(); +#else + cpu_index = 0; +#endif + + __asm__ volatile ( + "movl " RTEMS_XSTRING( I386_CONTEXT_CONTROL_GS_0_OFFSET ) "(%2), %0\n" + "movl %0, _Global_descriptor_table+24(,%1,8)\n" + "movl " RTEMS_XSTRING( I386_CONTEXT_CONTROL_GS_1_OFFSET ) "(%2), %0\n" + "movl %0, _Global_descriptor_table+28(,%1,8)\n" + "leal 24(,%1,8), %0\n" + "movl %0, %%gs\n" + : "=&r" ( tmp ) + : "r" ( cpu_index ), "r" ( context ) + : "memory" + ); +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h index eb0c058723..24e8e5cb41 100644 --- a/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/lm32/include/rtems/score/cpuimpl.h @@ -58,6 +58,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h index e3b61efd9f..5c7c35943a 100644 --- a/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/m68k/include/rtems/score/cpuimpl.h @@ -78,6 +78,17 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + /* + * There is nothing to do since the thread-local storage area is obtained by + * calling __m68k_read_tp(). + */ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h index 0573759d52..e4f0303ad8 100644 --- a/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/microblaze/include/rtems/score/cpuimpl.h @@ -86,6 +86,17 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + /* + * There is nothing to do since the thread-local storage area is obtained by + * calling __tls_get_addr(). + */ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h index 0568134351..23d3f35960 100644 --- a/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/mips/include/rtems/score/cpuimpl.h @@ -78,6 +78,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h index 038a1326cc..a54824f16b 100644 --- a/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/moxie/include/rtems/score/cpuimpl.h @@ -78,6 +78,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h index 215df68f67..518fac4308 100644 --- a/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/nios2/include/rtems/score/cpuimpl.h @@ -70,6 +70,18 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + register uint32_t r23 __asm__( "r23" ); + + r23 = context->r23; + + /* Make sure that the register assignment is not optimized away */ + __asm__ volatile ( "" : : "r" ( r23 ) ); +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h index 6f4abfcfc3..1eec4e6b7a 100644 --- a/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/no_cpu/include/rtems/score/cpuimpl.h @@ -166,6 +166,23 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +/** + * @brief Uses the thread-local storage area of the context. + * + * Some architectures may use dedicated registers to reference the thread-local + * storage area of the associated thread. This function should set these + * registers to the values defined by the specified processor context. + * + * @param context is the processor context defining the thread-local storage + * area to use. + */ +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h index 37cd1db436..35d186990d 100644 --- a/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/or1k/include/rtems/score/cpuimpl.h @@ -70,6 +70,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "l.nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h index cfed43ced4..4a88fe18b1 100644 --- a/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/powerpc/include/rtems/score/cpuimpl.h @@ -283,6 +283,22 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ +#ifdef __powerpc64__ + register uintptr_t tp __asm__( "13" ); +#else + register uintptr_t tp __asm__( "2" ); +#endif + + tp = ppc_get_context( context )->tp; + + /* Make sure that the register assignment is not optimized away */ + __asm__ volatile ( "" : : "r" ( tp ) ); +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h index 5162cbbd51..ca09832d0e 100644 --- a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h @@ -430,6 +430,18 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + register uintptr_t tp __asm__( "tp" ); + + tp = context->tp; + + /* Make sure that the register assignment is not optimized away */ + __asm__ volatile ( "" : : "r" ( tp ) ); +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h index 745a185d1a..cb20bab616 100644 --- a/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/sh/include/rtems/score/cpuimpl.h @@ -59,6 +59,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h index 7197eb960e..2a200be7e3 100644 --- a/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/sparc/include/rtems/score/cpuimpl.h @@ -234,6 +234,18 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + register uint32_t g7 __asm__( "g7" ); + + g7 = context->g7; + + /* Make sure that the register assignment is not optimized away */ + __asm__ volatile ( "" : : "r" ( g7 ) ); +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h index c026687d01..23aed1a8d6 100644 --- a/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/sparc64/include/rtems/score/cpuimpl.h @@ -78,6 +78,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h index 23c1437ba0..8f73b45ad6 100644 --- a/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/v850/include/rtems/score/cpuimpl.h @@ -78,6 +78,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h index d3a4b848e6..680c61ae20 100644 --- a/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h +++ b/cpukit/score/cpu/x86_64/include/rtems/score/cpuimpl.h @@ -62,6 +62,13 @@ RTEMS_INLINE_ROUTINE void _CPU_Instruction_no_operation( void ) __asm__ volatile ( "nop" ); } +RTEMS_INLINE_ROUTINE void _CPU_Use_thread_local_storage( + const Context_Control *context +) +{ + (void) context; +} + #ifdef __cplusplus } #endif diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c index 9f3c01d118..be3cbca842 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -40,6 +40,7 @@ #endif #include <rtems/score/threadidledata.h> +#include <rtems/score/cpuimpl.h> #include <rtems/score/threadimpl.h> #include <rtems/score/assert.h> #include <rtems/score/schedulerimpl.h> @@ -124,4 +125,8 @@ void _Thread_Create_idle( void ) _Thread_Create_idle_for_CPU( cpu ); } } + + _CPU_Use_thread_local_storage( + &_Per_CPU_Get_executing( _Per_CPU_Get() )->Registers + ); } diff --git a/testsuites/sptests/sptls01/init.c b/testsuites/sptests/sptls01/init.c index 5b5d274d3c..efd0fb4c6c 100644 --- a/testsuites/sptests/sptls01/init.c +++ b/testsuites/sptests/sptls01/init.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: BSD-2-Clause */ /* - * Copyright (c) 2014 embedded brains GmbH. All rights reserved. + * Copyright (C) 2014, 2022 embedded brains GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,7 +29,8 @@ #include "config.h" #endif -#include <stdio.h> +#include <rtems/bspIo.h> +#include <rtems/sysinit.h> #include "tmacros.h" @@ -45,7 +46,7 @@ static const volatile uint32_t read_only_small = 0x601dc0feUL; static void check_tls_item(uint32_t expected) { - printf("TLS item = %i\n", tls_item); + printk("TLS item = %i\n", tls_item); rtems_test_assert(tls_item == expected); } @@ -97,10 +98,15 @@ static void test(void) check_tls_item(5); } -static void Init(rtems_task_argument arg) +static void test_idle_during_system_init(void) { TEST_BEGIN(); + check_tls_item(123); +} + +static void Init(rtems_task_argument arg) +{ test(); TEST_END(); @@ -108,6 +114,12 @@ static void Init(rtems_task_argument arg) rtems_test_exit(0); } +RTEMS_SYSINIT_ITEM( + test_idle_during_system_init, + RTEMS_SYSINIT_IDLE_THREADS, + RTEMS_SYSINIT_ORDER_LAST +); + #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER |