![]() |
|
|||
File indexing completed on 2025-05-11 08:24:13
0001 /* SPDX-License-Identifier: BSD-2-Clause */ 0002 0003 /** 0004 * @file 0005 * 0006 * @ingroup RTEMSScoreSMP 0007 * 0008 * @brief This header file provides interfaces of the 0009 * @ref RTEMSScoreSMP which are only used by the implementation. 0010 */ 0011 0012 /* 0013 * COPYRIGHT (c) 1989-2011. 0014 * On-Line Applications Research Corporation (OAR). 0015 * 0016 * Redistribution and use in source and binary forms, with or without 0017 * modification, are permitted provided that the following conditions 0018 * are met: 0019 * 1. Redistributions of source code must retain the above copyright 0020 * notice, this list of conditions and the following disclaimer. 0021 * 2. Redistributions in binary form must reproduce the above copyright 0022 * notice, this list of conditions and the following disclaimer in the 0023 * documentation and/or other materials provided with the distribution. 0024 * 0025 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 0026 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 0027 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 0028 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 0029 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 0030 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 0031 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 0032 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 0033 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 0034 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 0035 * POSSIBILITY OF SUCH DAMAGE. 0036 */ 0037 0038 #ifndef _RTEMS_SCORE_SMPIMPL_H 0039 #define _RTEMS_SCORE_SMPIMPL_H 0040 0041 #include <rtems/score/smp.h> 0042 #include <rtems/score/percpu.h> 0043 #include <rtems/score/processormaskimpl.h> 0044 #include <rtems/fatal.h> 0045 0046 #ifdef __cplusplus 0047 extern "C" { 0048 #endif 0049 0050 /** 0051 * @addtogroup RTEMSScoreSMP 0052 * 0053 * This defines the interface of the SuperCore SMP support. 0054 * 0055 * @{ 0056 */ 0057 0058 /** 0059 * @brief SMP message to request a processor shutdown. 0060 * 0061 * @see _SMP_Send_message(). 0062 */ 0063 #define SMP_MESSAGE_SHUTDOWN 0x1UL 0064 0065 /** 0066 * @brief SMP message to perform per-processor jobs. 0067 * 0068 * @see _SMP_Send_message(). 0069 */ 0070 #define SMP_MESSAGE_PERFORM_JOBS 0x2UL 0071 0072 /** 0073 * @brief SMP message to force the message processing in 0074 * _SMP_Try_to_process_message(). 0075 * 0076 * This message bit is never sent to a processor. It is only used to force the 0077 * message processing in _SMP_Try_to_process_message(). Any non-zero value 0078 * would do it. 0079 */ 0080 #define SMP_MESSAGE_FORCE_PROCESSING 0x4UL 0081 0082 /** 0083 * @brief SMP fatal codes. 0084 */ 0085 typedef enum { 0086 SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER, 0087 SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT, 0088 SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR, 0089 SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR, 0090 SMP_FATAL_SHUTDOWN, 0091 SMP_FATAL_SHUTDOWN_RESPONSE, 0092 SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED, 0093 SMP_FATAL_SCHEDULER_PIN_OR_UNPIN_NOT_SUPPORTED, 0094 SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS, 0095 SMP_FATAL_SCHEDULER_REQUIRES_EXACTLY_ONE_PROCESSOR, 0096 SMP_FATAL_MULTITASKING_START_ON_NOT_ONLINE_PROCESSOR 0097 } SMP_Fatal_code; 0098 0099 /** 0100 * @brief Terminates with the given code. 0101 * 0102 * @param code The code for the termination. 0103 */ 0104 static inline void _SMP_Fatal( SMP_Fatal_code code ) 0105 { 0106 _Terminate( RTEMS_FATAL_SOURCE_SMP, code ); 0107 } 0108 0109 /** 0110 * @brief Initializes SMP Handler 0111 * 0112 * This method initialize the SMP Handler. 0113 */ 0114 #if defined( RTEMS_SMP ) 0115 void _SMP_Handler_initialize( void ); 0116 #else 0117 #define _SMP_Handler_initialize() \ 0118 do { } while ( 0 ) 0119 #endif 0120 0121 #if defined( RTEMS_SMP ) 0122 0123 /** 0124 * @brief Set of online processors. 0125 * 0126 * A processor is online if was started during system initialization. In this 0127 * case its corresponding bit in the mask is set. 0128 * 0129 * @see _SMP_Handler_initialize(). 0130 */ 0131 extern Processor_mask _SMP_Online_processors; 0132 0133 /** 0134 * @brief Performs high-level initialization of a secondary processor and runs 0135 * the application threads. 0136 * 0137 * The low-level initialization code must call this function to hand over the 0138 * control of this processor to RTEMS. Interrupts must be disabled. It must 0139 * be possible to send inter-processor interrupts to this processor. Since 0140 * interrupts are disabled the inter-processor interrupt delivery is postponed 0141 * until interrupts are enabled the first time. Interrupts are enabled during 0142 * the execution begin of threads in case they have interrupt level zero (this 0143 * is the default). 0144 * 0145 * The pre-requisites for the call to this function are 0146 * - disabled interrupts, 0147 * - delivery of inter-processor interrupts is possible, 0148 * - a valid stack pointer and enough stack space, 0149 * - a valid code memory, and 0150 * - a valid BSS section. 0151 * 0152 * This function must not be called by the main processor. The main processor 0153 * uses _Thread_Start_multitasking() instead. 0154 * 0155 * This function does not return to the caller. 0156 * 0157 * @param cpu_self The current processor control. 0158 */ 0159 RTEMS_NO_RETURN void _SMP_Start_multitasking_on_secondary_processor( 0160 Per_CPU_Control *cpu_self 0161 ); 0162 0163 /** 0164 * @brief Processes the SMP message. 0165 * 0166 * @param[in, out] cpu_self is the processor control of the processor executing 0167 * this function. 0168 * 0169 * @param message is the message to process. 0170 */ 0171 void _SMP_Process_message( Per_CPU_Control *cpu_self, long unsigned message ); 0172 0173 /** 0174 * @brief Tries to process the current SMP message. 0175 * 0176 * This function may be used in busy wait loops. 0177 * 0178 * @param cpu_self is the processor control of the processor executing this 0179 * function. 0180 * 0181 * @param message is used to check if the SMP message processing should be 0182 * carried out. If it is not equal to zero, then _SMP_Process_message() is 0183 * called with a newly fetched message. This parameter is not used to process 0184 * the message. It is only used to check if the processing is necessary. 0185 * Use #SMP_MESSAGE_FORCE_PROCESSING to force the message processing. 0186 */ 0187 void _SMP_Try_to_process_message( 0188 Per_CPU_Control *cpu_self, 0189 unsigned long message 0190 ); 0191 0192 /** 0193 * @brief Processes an inter-processor interrupt. 0194 * 0195 * Use this function for the inter-processor interrupt handler. Never call 0196 * this function in a tight loop. 0197 * 0198 * @param[in, out] cpu_self is the processor control of the processor executing 0199 * this function. 0200 */ 0201 static inline void _SMP_Inter_processor_interrupt_handler( 0202 Per_CPU_Control *cpu_self 0203 ) 0204 { 0205 unsigned long message; 0206 0207 /* 0208 * In the common case the inter-processor interrupt is issued to carry out a 0209 * thread dispatch. 0210 */ 0211 cpu_self->dispatch_necessary = true; 0212 0213 message = _Atomic_Exchange_ulong( 0214 &cpu_self->message, 0215 0, 0216 ATOMIC_ORDER_ACQUIRE 0217 ); 0218 0219 if ( RTEMS_PREDICT_FALSE( message != 0 ) ) { 0220 _SMP_Process_message( cpu_self, message ); 0221 } 0222 } 0223 0224 /** 0225 * @brief Checks if the processor with the specified index should be started. 0226 * 0227 * @param cpu_index The processor index. 0228 * 0229 * @retval true The processor should be started. 0230 * @retval false The processor should not be started. 0231 */ 0232 bool _SMP_Should_start_processor( uint32_t cpu_index ); 0233 0234 /** 0235 * @brief Sends the SMP message to the processor. 0236 * 0237 * The target processor may be the sending processor. 0238 * 0239 * @param[in, out] cpu is the processor control of the target processor. 0240 * 0241 * @param message is the message to send. 0242 */ 0243 void _SMP_Send_message( Per_CPU_Control *cpu, unsigned long message ); 0244 0245 typedef void ( *SMP_Action_handler )( void *arg ); 0246 0247 /** 0248 * @brief Initiates an SMP multicast action to the set of target processors. 0249 * 0250 * The current processor may be part of the set. The caller must ensure that 0251 * no thread dispatch can happen during the call of this function, otherwise 0252 * the behaviour is undefined. In case a target processor is in a wrong state 0253 * to process per-processor jobs, then this function results in an 0254 * SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS fatal SMP error. 0255 * 0256 * @param targets The set of target processors for the action. 0257 * @param handler The multicast action handler. 0258 * @param arg The multicast action argument. 0259 */ 0260 void _SMP_Multicast_action( 0261 const Processor_mask *targets, 0262 SMP_Action_handler handler, 0263 void *arg 0264 ); 0265 0266 /** 0267 * @brief Initiates an SMP multicast action to the set of all online 0268 * processors. 0269 * 0270 * Simply calls _SMP_Multicast_action() with _SMP_Get_online_processors() as 0271 * the target processor set. 0272 * 0273 * @param handler The multicast action handler. 0274 * @param arg The multicast action argument. 0275 */ 0276 void _SMP_Broadcast_action( 0277 SMP_Action_handler handler, 0278 void *arg 0279 ); 0280 0281 /** 0282 * @brief Initiates an SMP multicast action to the set of all online 0283 * processors excluding the current processor. 0284 * 0285 * Simply calls _SMP_Multicast_action() with _SMP_Get_online_processors() as 0286 * the target processor set excluding the current processor. 0287 * 0288 * @param handler The multicast action handler. 0289 * @param arg The multicast action argument. 0290 */ 0291 void _SMP_Othercast_action( 0292 SMP_Action_handler handler, 0293 void *arg 0294 ); 0295 0296 /** 0297 * @brief Initiates an SMP action on the specified target processor. 0298 * 0299 * This is an optimized variant of _SMP_Multicast_action(). 0300 * 0301 * @param cpu_index The index of the target processor. 0302 * @param handler The action handler. 0303 * @param arg The action argument. 0304 */ 0305 void _SMP_Unicast_action( 0306 uint32_t cpu_index, 0307 SMP_Action_handler handler, 0308 void *arg 0309 ); 0310 0311 /** 0312 * @brief Ensures that all store operations issued by the current processor 0313 * before the call this function are visible to all other online processors. 0314 * 0315 * Simply calls _SMP_Othercast_action() with an empty multicast action. 0316 */ 0317 void _SMP_Synchronize( void ); 0318 0319 /** 0320 * @brief Waits until all other online processors reached the 0321 * ::PER_CPU_STATE_READY_TO_START_MULTITASKING state. 0322 * 0323 * The waiting is done without a timeout. If secondary processors cannot reach 0324 * this state, then it is expected that they indicate this failure with an 0325 * ::SMP_MESSAGE_SHUTDOWN message or reset the system. 0326 * 0327 * While waiting for state changes, SMP messages for the current processor are 0328 * processed. 0329 */ 0330 void _SMP_Wait_for_ready_to_start_multitasking( void ); 0331 0332 #endif /* defined( RTEMS_SMP ) */ 0333 0334 /** 0335 * @brief Requests a multitasking start on all configured and available 0336 * processors. 0337 */ 0338 #if defined( RTEMS_SMP ) 0339 void _SMP_Request_start_multitasking( void ); 0340 #else 0341 #define _SMP_Request_start_multitasking() \ 0342 do { } while ( 0 ) 0343 #endif 0344 0345 /** 0346 * @brief Requests a shutdown of all processors. 0347 * 0348 * This function is a part of the system termination procedure. 0349 * 0350 * @see _Terminate(). 0351 */ 0352 #if defined( RTEMS_SMP ) 0353 void _SMP_Request_shutdown( void ); 0354 #else 0355 #define _SMP_Request_shutdown() \ 0356 do { } while ( 0 ) 0357 #endif 0358 0359 /** 0360 * @brief Gets all online processors 0361 * 0362 * @return The processor mask with all online processors. 0363 */ 0364 static inline const Processor_mask *_SMP_Get_online_processors( void ) 0365 { 0366 #if defined(RTEMS_SMP) 0367 return &_SMP_Online_processors; 0368 #else 0369 return &_Processor_mask_The_one_and_only; 0370 #endif 0371 } 0372 0373 /** 0374 * @brief Indicate if inter-processor interrupts are needed. 0375 * 0376 * @return True if inter-processor interrupts are needed for the correct system 0377 * operation, otherwise false. 0378 */ 0379 static inline bool _SMP_Need_inter_processor_interrupts( void ) 0380 { 0381 /* 0382 * Use the configured processor maximum instead of the actual to allow 0383 * testing on uni-processor systems. 0384 */ 0385 return _SMP_Processor_configured_maximum > 1; 0386 } 0387 0388 /** @} */ 0389 0390 #ifdef __cplusplus 0391 } 0392 #endif 0393 0394 #endif 0395 /* end of include file */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |