mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-21 00:25:13 +08:00
score: Add _CPU_Use_thread_local_storage()
At some point during system initialization, the idle threads are created. Afterwards, the boot processor basically executes within the context of an idle thread with thread dispatching disabled. On some architectures, the thread-local storage area of the associated thread must be set in dedicated processor registers. Add the new CPU port function to do this: void _CPU_Use_thread_local_storage( const Context_Control *context ) Close #4672.
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user