forked from Imagelibrary/rtems
score: Delete _Thread_BSP_context
Do not return to BSP context in the exit() shutdown path. This makes it possible to re-use the initialization stack. It can be used for the interrupt stack for example. On targets with a small RAM this is a considerable benefit. This change eliminates also some special cases and simplifies the code. Delete _Thread_Set_global_exit_status(), _Thread_Get_global_exit_status() and _Thread_Stop_multitasking().
This commit is contained in:
@@ -33,7 +33,6 @@
|
||||
#include <rtems/config.h>
|
||||
#include <rtems/debug.h>
|
||||
#include <rtems/extensionimpl.h>
|
||||
#include <rtems/fatal.h>
|
||||
#include <rtems/init.h>
|
||||
#include <rtems/io.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
@@ -215,25 +214,20 @@ void rtems_initialize_device_drivers(void)
|
||||
|
||||
void rtems_initialize_start_multitasking(void)
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
_System_state_Set( SYSTEM_STATE_UP );
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
_SMP_Request_other_cores_to_perform_first_context_switch();
|
||||
#endif
|
||||
|
||||
_Thread_Start_multitasking( &_Thread_BSP_context );
|
||||
_Thread_Start_multitasking();
|
||||
|
||||
/*******************************************************************
|
||||
*******************************************************************
|
||||
*******************************************************************
|
||||
****** APPLICATION RUNS HERE ******
|
||||
****** RETURNS WHEN SYSTEM IS SHUT DOWN ******
|
||||
****** THE FUNCTION NEVER RETURNS ******
|
||||
*******************************************************************
|
||||
*******************************************************************
|
||||
*******************************************************************/
|
||||
|
||||
status = _Thread_Get_global_exit_status();
|
||||
rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, status );
|
||||
}
|
||||
|
||||
@@ -15,47 +15,37 @@
|
||||
|
||||
#include <rtems/init.h>
|
||||
#include <rtems/score/sysstate.h>
|
||||
#include <rtems/score/threadimpl.h>
|
||||
#include <rtems/score/interr.h>
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
#include <rtems/score/smp.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* rtems_shutdown_executive
|
||||
*
|
||||
* This kernel routine shutdowns the executive. It halts multitasking
|
||||
* and returns control to the application execution "thread" which
|
||||
* initialially invoked the rtems_initialize_executive directive.
|
||||
*
|
||||
* Input parameters: NONE
|
||||
*
|
||||
* Output parameters: NONE
|
||||
*/
|
||||
|
||||
void rtems_shutdown_executive(
|
||||
uint32_t result
|
||||
)
|
||||
void rtems_shutdown_executive( uint32_t result )
|
||||
{
|
||||
Internal_errors_Source source;
|
||||
bool is_internal;
|
||||
Internal_errors_t code;
|
||||
|
||||
if ( _System_state_Is_up( _System_state_Get() ) ) {
|
||||
#if defined(RTEMS_SMP)
|
||||
_SMP_Request_other_cores_to_shutdown();
|
||||
#endif
|
||||
|
||||
_Thread_Set_global_exit_status( result );
|
||||
_Thread_Stop_multitasking();
|
||||
|
||||
/*******************************************************************
|
||||
*******************************************************************
|
||||
****** RETURN TO RTEMS_INITIALIZE_START_MULTITASKING() ******
|
||||
****** AND THEN TO BOOT_CARD() ******
|
||||
*******************************************************************
|
||||
*******************************************************************/
|
||||
source = RTEMS_FATAL_SOURCE_EXIT;
|
||||
is_internal = false;
|
||||
code = result;
|
||||
} else {
|
||||
source = INTERNAL_ERROR_CORE;
|
||||
is_internal = true;
|
||||
code = INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP;
|
||||
}
|
||||
_Internal_error_Occurred(
|
||||
INTERNAL_ERROR_CORE,
|
||||
true,
|
||||
INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP
|
||||
);
|
||||
|
||||
_Internal_error_Occurred( source, is_internal, code );
|
||||
|
||||
/***************************************************************
|
||||
***************************************************************
|
||||
* SYSTEM SHUTS DOWN!!! WE DO NOT RETURN TO THIS POINT!!! *
|
||||
***************************************************************
|
||||
***************************************************************/
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief ARMV7M Start and Stop Multitasking
|
||||
* @brief ARMV7M Start Multitasking
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2011 Sebastian Huber. All rights reserved.
|
||||
* Copyright (c) 2011-2014 Sebastian Huber. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
@@ -27,18 +27,14 @@
|
||||
#ifdef ARM_MULTILIB_ARCH_V7M
|
||||
|
||||
void __attribute__((naked)) _ARMV7M_Start_multitasking(
|
||||
Context_Control *bsp,
|
||||
Context_Control *heir
|
||||
)
|
||||
{
|
||||
__asm__ volatile (
|
||||
/* Store BSP context */
|
||||
"stm r0, {r4-r11, lr}\n"
|
||||
"str sp, [r0, %[spctxoff]]\n"
|
||||
/* Restore heir context */
|
||||
"ldr r2, [r1, %[spctxoff]]\n"
|
||||
"ldr r2, [r0, %[spctxoff]]\n"
|
||||
"msr psp, r2\n"
|
||||
"ldm r1, {r4-r11, lr}\n"
|
||||
"ldm r0, {r4-r11, lr}\n"
|
||||
/* Enable process stack pointer (PSP) */
|
||||
"mrs r2, control\n"
|
||||
"orr r2, #0x2\n"
|
||||
@@ -50,26 +46,4 @@ void __attribute__((naked)) _ARMV7M_Start_multitasking(
|
||||
);
|
||||
}
|
||||
|
||||
void __attribute__((naked)) _ARMV7M_Stop_multitasking( Context_Control *bsp )
|
||||
{
|
||||
__asm__ volatile (
|
||||
/* Disable interrupts */
|
||||
"mov r2, #0x80\n"
|
||||
"msr basepri_max, r2\n"
|
||||
/* Restore BSP context */
|
||||
"ldr r2, [r0, %[spctxoff]]\n"
|
||||
"msr msp, r2\n"
|
||||
"ldm r0, {r4-r11, lr}\n"
|
||||
/* Disable process stack pointer (PSP) */
|
||||
"mrs r2, control\n"
|
||||
"bic r2, #0x2\n"
|
||||
"msr control, r2\n"
|
||||
/* Return to BSP */
|
||||
"bx lr\n"
|
||||
:
|
||||
: [spctxoff] "J" (offsetof(Context_Control, register_sp))
|
||||
);
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
#endif /* ARM_MULTILIB_ARCH_V7M */
|
||||
|
||||
@@ -458,11 +458,8 @@ void _CPU_Context_restore( Context_Control *new_context )
|
||||
RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
|
||||
|
||||
#if defined(ARM_MULTILIB_ARCH_V7M)
|
||||
void _ARMV7M_Start_multitasking( Context_Control *bsp, Context_Control *heir );
|
||||
void _ARMV7M_Stop_multitasking( Context_Control *bsp )
|
||||
RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
|
||||
void _ARMV7M_Start_multitasking( Context_Control *heir );
|
||||
#define _CPU_Start_multitasking _ARMV7M_Start_multitasking
|
||||
#define _CPU_Stop_multitasking _ARMV7M_Stop_multitasking
|
||||
#endif
|
||||
|
||||
void _CPU_Context_volatile_clobber( uintptr_t pattern );
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define _RTEMS_SCORE_THREADIMPL_H
|
||||
|
||||
#include <rtems/score/thread.h>
|
||||
#include <rtems/score/interr.h>
|
||||
#include <rtems/score/isr.h>
|
||||
#include <rtems/score/objectimpl.h>
|
||||
#include <rtems/score/statesimpl.h>
|
||||
@@ -53,15 +54,6 @@ SCORE_EXTERN void *rtems_ada_self;
|
||||
*/
|
||||
SCORE_EXTERN Objects_Information _Thread_Internal_information;
|
||||
|
||||
/**
|
||||
* The following context area contains the context of the "thread"
|
||||
* which invoked the start multitasking routine. This context is
|
||||
* restored as the last action of the stop multitasking routine. Thus
|
||||
* control of the processor can be returned to the environment
|
||||
* which initiated the system.
|
||||
*/
|
||||
SCORE_EXTERN Context_Control _Thread_BSP_context;
|
||||
|
||||
/**
|
||||
* The following holds how many user extensions are in the system. This
|
||||
* is used to determine how many user extension data areas to allocate
|
||||
@@ -114,13 +106,8 @@ void _Thread_Create_idle(void);
|
||||
* This routine initiates multitasking. It is invoked only as
|
||||
* part of initialization and its invocation is the last act of
|
||||
* the non-multitasking part of the system initialization.
|
||||
*
|
||||
*
|
||||
* - INTERRUPT LATENCY:
|
||||
* + ready chain
|
||||
* + select heir
|
||||
*/
|
||||
void _Thread_Start_multitasking( Context_Control *context );
|
||||
void _Thread_Start_multitasking( void ) RTEMS_COMPILER_NO_RETURN_ATTRIBUTE;
|
||||
|
||||
/**
|
||||
* @brief Allocate the requested stack space for the thread.
|
||||
@@ -445,36 +432,6 @@ void _Thread_blocking_operation_Cancel(
|
||||
ISR_Level level
|
||||
);
|
||||
|
||||
/**
|
||||
* This routine halts multitasking and returns control to
|
||||
* the "thread" (i.e. the BSP) which initially invoked the
|
||||
* routine which initialized the system.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Stop_multitasking( void )
|
||||
{
|
||||
#if defined(_CPU_Stop_multitasking)
|
||||
_CPU_Stop_multitasking( &_Thread_BSP_context );
|
||||
#else
|
||||
/*
|
||||
* This may look a bit of an odd but _Context_Restart_self is just
|
||||
* a very careful restore of a specific context which ensures that
|
||||
* if we were running within the same context, it would work.
|
||||
*
|
||||
* And we will not return to this thread, so there is no point of
|
||||
* saving the context.
|
||||
*/
|
||||
_Context_Restart_self( &_Thread_BSP_context );
|
||||
#endif
|
||||
|
||||
/***************************************************************
|
||||
***************************************************************
|
||||
* SYSTEM SHUTS DOWN!!! WE DO NOT RETURN TO THIS POINT!!! *
|
||||
***************************************************************
|
||||
***************************************************************
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns true if the_thread is the currently executing
|
||||
* thread, and false otherwise.
|
||||
@@ -630,24 +587,6 @@ RTEMS_INLINE_ROUTINE void _Thread_Internal_free (
|
||||
_Objects_Free( &_Thread_Internal_information, &the_task->Object );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Set_global_exit_status(
|
||||
uint32_t exit_status
|
||||
)
|
||||
{
|
||||
Thread_Control *idle = (Thread_Control *)
|
||||
_Thread_Internal_information.local_table[ 1 ];
|
||||
|
||||
idle->Wait.return_code = exit_status;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE uint32_t _Thread_Get_global_exit_status( void )
|
||||
{
|
||||
const Thread_Control *idle = (const Thread_Control *)
|
||||
_Thread_Internal_information.local_table[ 1 ];
|
||||
|
||||
return idle->Wait.return_code;
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Thread_Signal_notification( Thread_Control *thread )
|
||||
{
|
||||
if ( _ISR_Is_in_progress() && _Thread_Is_executing( thread ) ) {
|
||||
|
||||
@@ -40,7 +40,7 @@ void rtems_smp_secondary_cpu_initialize( void )
|
||||
|
||||
_Per_CPU_Wait_for_state( self_cpu, PER_CPU_STATE_BEGIN_MULTITASKING );
|
||||
|
||||
_Thread_Start_multitasking( NULL );
|
||||
_Thread_Start_multitasking();
|
||||
}
|
||||
|
||||
void rtems_smp_process_interrupt( void )
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include <rtems/score/threadimpl.h>
|
||||
|
||||
void _Thread_Start_multitasking( Context_Control *context )
|
||||
void _Thread_Start_multitasking( void )
|
||||
{
|
||||
Per_CPU_Control *self_cpu = _Per_CPU_Get();
|
||||
Thread_Control *heir = self_cpu->heir;
|
||||
@@ -28,7 +28,13 @@ void _Thread_Start_multitasking( Context_Control *context )
|
||||
#if defined(RTEMS_SMP)
|
||||
_Per_CPU_Change_state( self_cpu, PER_CPU_STATE_UP );
|
||||
|
||||
/*
|
||||
* Threads begin execution in the _Thread_Handler() function. This
|
||||
* function will set the thread dispatch disable level to zero and calls
|
||||
* _Per_CPU_Release().
|
||||
*/
|
||||
_Per_CPU_Acquire( self_cpu );
|
||||
self_cpu->thread_dispatch_disable_level = 1;
|
||||
|
||||
self_cpu->executing->is_executing = false;
|
||||
heir->is_executing = true;
|
||||
@@ -59,26 +65,9 @@ void _Thread_Start_multitasking( Context_Control *context )
|
||||
_Context_Restore_fp( &heir->fp_context );
|
||||
#endif
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
if ( context != NULL ) {
|
||||
#endif
|
||||
|
||||
#if defined(_CPU_Start_multitasking)
|
||||
_CPU_Start_multitasking( context, &heir->Registers );
|
||||
_CPU_Start_multitasking( &heir->Registers );
|
||||
#else
|
||||
_Context_Switch( context, &heir->Registers );
|
||||
#endif
|
||||
|
||||
#if defined(RTEMS_SMP)
|
||||
} else {
|
||||
/*
|
||||
* Threads begin execution in the _Thread_Handler() function. This
|
||||
* function will set the thread dispatch disable level to zero and calls
|
||||
* _Per_CPU_Release().
|
||||
*/
|
||||
self_cpu->thread_dispatch_disable_level = 1;
|
||||
|
||||
_CPU_Context_restore( &heir->Registers );
|
||||
}
|
||||
_CPU_Context_Restart_self( &heir->Registers );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -385,8 +385,7 @@ uninitialized =
|
||||
|
||||
/*tasksimpl.h*/ (sizeof _RTEMS_tasks_Information) +
|
||||
|
||||
/*thread.h*/ (sizeof _Thread_BSP_context) +
|
||||
(sizeof _Thread_Dispatch_disable_level) +
|
||||
/*thread.h*/ (sizeof _Thread_Dispatch_disable_level) +
|
||||
(sizeof _Thread_Maximum_extensions) +
|
||||
(sizeof _Thread_Ticks_per_timeslice) +
|
||||
(sizeof _Thread_Executing) +
|
||||
|
||||
Reference in New Issue
Block a user