27 #include <rtems/config.h> 28 #include <rtems/sysinit.h> 32 #if CPU_USE_DEFERRED_FP_SWITCH == TRUE 33 #error "deferred FP switch not implemented for SMP" 38 uint32_t _SMP_Processor_maximum;
47 static bool _Scheduler_Is_mandatory_processor(
54 static bool _Scheduler_Should_start_processor(
61 static void _SMP_Start_processors( uint32_t cpu_max )
63 uint32_t cpu_index_self;
66 cpu_index_self = _SMP_Get_current_processor();
68 for ( cpu_index = 0 ; cpu_index < cpu_max; ++cpu_index ) {
73 assignment = _Scheduler_Get_initial_assignment( cpu_index );
74 cpu = _Per_CPU_Get_by_index( cpu_index );
76 if ( cpu_index != cpu_index_self ) {
77 if ( _Scheduler_Should_start_processor( assignment ) ) {
78 started = _CPU_SMP_Start_processor( cpu_index );
80 if ( !started && _Scheduler_Is_mandatory_processor( assignment ) ) {
81 _SMP_Fatal( SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED );
91 if ( !_Scheduler_Should_start_processor( assignment ) ) {
92 _SMP_Fatal( SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER );
107 cpu->Scheduler.
control = scheduler;
108 cpu->Scheduler.
context = context;
115 uint32_t cpu_config_max;
121 for ( cpu_index = 0 ; cpu_index < cpu_config_max; ++cpu_index ) {
124 cpu = _Per_CPU_Get_by_index( cpu_index );
135 cpu_max = _CPU_SMP_Initialize();
136 cpu_max = cpu_max < cpu_config_max ? cpu_max : cpu_config_max;
137 _SMP_Processor_maximum = cpu_max;
139 for ( cpu_index = cpu_max ; cpu_index < cpu_config_max; ++cpu_index ) {
142 assignment = _Scheduler_Get_initial_assignment( cpu_index );
144 if ( _Scheduler_Is_mandatory_processor( assignment ) ) {
145 _SMP_Fatal( SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT );
149 _SMP_Start_processors( cpu_max );
151 _CPU_SMP_Finalize_initialization( cpu_max );
160 cpu_self = _Per_CPU_Get();
163 cpu_max = _SMP_Get_processor_maximum();
165 for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
168 cpu = _Per_CPU_Get_by_index( cpu_index );
170 if ( _Per_CPU_Is_processor_online( cpu ) ) {
180 assignment = _Scheduler_Get_initial_assignment( cpu_index );
181 return _Scheduler_Should_start_processor( assignment );
188 uint32_t cpu_index_self;
190 cpu_index_self = _Per_CPU_Get_index( cpu_self );
193 _SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR );
197 _SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR );
219 _Atomic_Fetch_or_ulong( &cpu->
message, message, ATOMIC_ORDER_RELEASE );
221 _CPU_SMP_Send_interrupt( cpu_index );
227 uint32_t cpu_index_self;
230 _Assert( _Debug_Is_thread_dispatching_allowed() );
231 cpu_max = _SMP_Get_processor_maximum();
232 cpu_index_self = _SMP_Get_current_processor();
234 for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
236 cpu_index != cpu_index_self
245 const Processor_mask *targets,
246 unsigned long message
252 cpu_max = _SMP_Get_processor_maximum();
254 for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
261 static void _Per_CPU_Data_initialize(
void )
265 size = RTEMS_LINKER_SET_SIZE( _Per_CPU_Data );
274 cpu = _Per_CPU_Get_by_index( 0 );
275 cpu->
data = RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data );
279 for ( cpu_index = 1 ; cpu_index < cpu_max ; ++cpu_index ) {
280 cpu = _Per_CPU_Get_by_index( cpu_index );
283 if( cpu->
data == NULL ) {
287 memcpy( cpu->
data, RTEMS_LINKER_SET_BEGIN( _Per_CPU_Data ), size);
293 _Per_CPU_Data_initialize,
294 RTEMS_SYSINIT_PER_CPU_DATA,
295 RTEMS_SYSINIT_ORDER_MIDDLE
void _SMP_Handler_initialize(void)
Initializes SMP Handler.
Processor is ready to start multitasking.
#define _ISR_Local_disable(_level)
Disables interrupts on this processor.
bool _SMP_Should_start_processor(uint32_t cpu_index)
Checks if the processor with the specified index should be started.
void _SMP_Start_multitasking_on_secondary_processor(Per_CPU_Control *cpu_self)
Performs high-level initialization of a secondary processor and runs the application threads...
struct Per_CPU_Control::@15 Jobs
FIFO list of jobs to be performed by this processor.
ISR_lock_Control Lock
This lock protects some members of this structure.
#define SCHEDULER_ASSIGN_PROCESSOR_MANDATORY
The presence of this processor is mandatory.
void _SMP_Send_message_multicast(const Processor_mask *targets, unsigned long message)
Sends an SMP message to a set of processors.
void _SMP_Send_message_broadcast(unsigned long message)
Sends an SMP message to all other online processors.
Inlined Routines Associated with the Manipulation of the Scheduler.
bool boot
Indicates if the processor is the one that performed the initial system initialization.
This header file defines parts of the application configuration information API.
const struct Scheduler_Context * context
The scheduler context of the scheduler owning this processor.
Chain_Control Threads_in_need_for_help
Chain of threads in need for help.
Information for the Assert Handler.
RTEMS_INLINE_ROUTINE bool _Processor_mask_Is_set(const Processor_mask *mask, uint32_t index)
Checks if the specified index bit of the mask is set.
const Scheduler_Assignment _Scheduler_Initial_assignments[]
The scheduler assignments.
uint32_t attributes
The scheduler assignment attributes.
static void _SMP_Fatal(SMP_Fatal_code code)
Terminates with the given code.
char * data
Begin of the per-CPU data area.
void _Thread_Start_multitasking(void) RTEMS_NO_RETURN
Starts thread multitasking.
void _SMP_Request_shutdown(void)
Requests a shutdown of all processors.
Processor_mask Processors
Lock to protect this scheduler instance.
struct Per_CPU_Control::@13 Watchdog
Watchdog state for this processor.
const struct _Scheduler_Control * control
The scheduler control of the scheduler owning this processor.
bool online
Indicates if the processor has been successfully started via _CPU_SMP_Start_processor().
void _SMP_Request_start_multitasking(void)
Requests a multitasking start on all configured and available processors.
This is the terminal state.
const Scheduler_Control * scheduler
The scheduler for this processor.
static __inline__ void _Chain_Initialize_empty(Chain_Control *the_chain)
Initializes this chain as empty.
Definition of custom per-CPU items.
Processor_mask _SMP_Online_processors
Set of online processors.
#define _ISR_lock_Set_name(_lock, _name)
Sets the name of an ISR lock.
static __inline__ Scheduler_Context * _Scheduler_Get_context(const Scheduler_Control *scheduler)
Gets the context of the scheduler.
void _Internal_error(Internal_errors_Core_list core_error) RTEMS_NO_RETURN
Terminates the system with an INTERNAL_ERROR_CORE fatal source and the specified core error code...
void * _Memory_Allocate(const Memory_Information *information, uintptr_t size, uintptr_t alignment)
Allocate a memory area from the memory information.
Inlined Routines from the Thread Handler.
Atomic_Ulong message
Bit field for SMP messages.
#define rtems_configuration_get_maximum_processors()
Returns the maximum number of processors which are configured for this application.
const Memory_Information * _Memory_Get(void)
Return the memory information of this platform.
#define _Assert(_e)
Assertion similar to assert() controlled via RTEMS_DEBUG instead of NDEBUG.
void _SMP_Send_message(uint32_t cpu_index, unsigned long message)
Sends an SMP message to a processor.
Multitasking start of processor is requested.
SuperCore SMP Implementation.
RTEMS_INLINE_ROUTINE void _Processor_mask_Set(Processor_mask *mask, uint32_t index)
Sets the specified index bit of the mask.