source: rtems/cpukit/include/rtems/score/smpimpl.h @ 5fa893e

Last change on this file since 5fa893e was 5fa893e, checked in by Sebastian Huber <sebastian.huber@…>, on May 20, 2019 at 7:15:36 AM

score: Add _SMP_Unicast_action()

  • Property mode set to 100644
File size: 8.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup RTEMSScoreSMPImpl
5 *
6 * @brief SuperCore SMP Implementation
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2011.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_SMPIMPL_H
19#define _RTEMS_SCORE_SMPIMPL_H
20
21#include <rtems/score/smp.h>
22#include <rtems/score/percpu.h>
23#include <rtems/score/processormask.h>
24#include <rtems/fatal.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/**
31 * @addtogroup RTEMSScoreSMP
32 *
33 * This defines the interface of the SuperCore SMP support.
34 *
35 * @{
36 */
37
38/**
39 * @brief SMP message to request a processor shutdown.
40 *
41 * @see _SMP_Send_message().
42 */
43#define SMP_MESSAGE_SHUTDOWN 0x1UL
44
45/**
46 * @brief SMP message to perform per-processor jobs.
47 *
48 * @see _SMP_Send_message().
49 */
50#define SMP_MESSAGE_PERFORM_JOBS 0x2UL
51
52/**
53 * @brief SMP fatal codes.
54 */
55typedef enum {
56  SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER,
57  SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT,
58  SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR,
59  SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR,
60  SMP_FATAL_SHUTDOWN,
61  SMP_FATAL_SHUTDOWN_RESPONSE,
62  SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED,
63  SMP_FATAL_SCHEDULER_PIN_OR_UNPIN_NOT_SUPPORTED,
64  SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS
65} SMP_Fatal_code;
66
67/**
68 * @brief Terminates with the given code.
69 *
70 * @param code The code for the termination.
71 */
72static inline void _SMP_Fatal( SMP_Fatal_code code )
73{
74  _Terminate( RTEMS_FATAL_SOURCE_SMP, code );
75}
76
77/**
78 * @brief Initializes SMP Handler
79 *
80 * This method initialize the SMP Handler.
81 */
82#if defined( RTEMS_SMP )
83  void _SMP_Handler_initialize( void );
84#else
85  #define _SMP_Handler_initialize() \
86    do { } while ( 0 )
87#endif
88
89#if defined( RTEMS_SMP )
90
91/**
92 * @brief Set of online processors.
93 *
94 * A processor is online if was started during system initialization.  In this
95 * case its corresponding bit in the mask is set.
96 *
97 * @see _SMP_Handler_initialize().
98 */
99extern Processor_mask _SMP_Online_processors;
100
101/**
102 * @brief Performs high-level initialization of a secondary processor and runs
103 * the application threads.
104 *
105 * The low-level initialization code must call this function to hand over the
106 * control of this processor to RTEMS.  Interrupts must be disabled.  It must
107 * be possible to send inter-processor interrupts to this processor.  Since
108 * interrupts are disabled the inter-processor interrupt delivery is postponed
109 * until interrupts are enabled the first time.  Interrupts are enabled during
110 * the execution begin of threads in case they have interrupt level zero (this
111 * is the default).
112 *
113 * The pre-requisites for the call to this function are
114 * - disabled interrupts,
115 * - delivery of inter-processor interrupts is possible,
116 * - a valid stack pointer and enough stack space,
117 * - a valid code memory, and
118 * - a valid BSS section.
119 *
120 * This function must not be called by the main processor.  The main processor
121 * uses _Thread_Start_multitasking() instead.
122 *
123 * This function does not return to the caller.
124 *
125 * @param cpu_self The current processor control.
126 */
127void _SMP_Start_multitasking_on_secondary_processor(
128  Per_CPU_Control *cpu_self
129) RTEMS_NO_RETURN;
130
131/**
132 * @brief Interrupts handler for inter-processor interrupts.
133 *
134 * @param[in, out] cpu_self The cpu control for the operation.
135 *
136 * @return The received message.
137 */
138static inline long unsigned _SMP_Inter_processor_interrupt_handler(
139  Per_CPU_Control *cpu_self
140)
141{
142  unsigned long message;
143
144  /*
145   * In the common case the inter-processor interrupt is issued to carry out a
146   * thread dispatch.
147   */
148  cpu_self->dispatch_necessary = true;
149
150  message = _Atomic_Exchange_ulong(
151    &cpu_self->message,
152    0,
153    ATOMIC_ORDER_ACQUIRE
154  );
155
156  if ( RTEMS_PREDICT_FALSE( message != 0 ) ) {
157    if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) {
158      _SMP_Fatal( SMP_FATAL_SHUTDOWN_RESPONSE );
159      /* does not continue past here */
160    }
161
162    if ( ( message & SMP_MESSAGE_PERFORM_JOBS ) != 0 ) {
163      _Per_CPU_Perform_jobs( cpu_self );
164    }
165  }
166
167  return message;
168}
169
170/**
171 * @brief Checks if the processor with the specified index should be started.
172 *
173 * @param cpu_index The processor index.
174 *
175 * @retval true The processor should be started.
176 * @retval false The processor should not be started.
177 */
178bool _SMP_Should_start_processor( uint32_t cpu_index );
179
180/**
181 * @brief Sends an SMP message to a processor.
182 *
183 * The target processor may be the sending processor.
184 *
185 * @param cpu_index The target processor of the message.
186 * @param message The message to send.
187 */
188void _SMP_Send_message( uint32_t cpu_index, unsigned long message );
189
190/**
191 * @brief Sends an SMP message to all other online processors.
192 *
193 * @param message The message to send.
194 */
195void _SMP_Send_message_broadcast(
196  unsigned long message
197);
198
199/**
200 * @brief Sends an SMP message to a set of processors.
201 *
202 * The sending processor may be part of the set.
203 *
204 * @param targets The set of processors to send the message.
205 * @param message The message to send.
206 */
207void _SMP_Send_message_multicast(
208  const Processor_mask *targets,
209  unsigned long         message
210);
211
212typedef void ( *SMP_Action_handler )( void *arg );
213
214/**
215 * @brief Initiates an SMP multicast action to the set of target processors.
216 *
217 * The current processor may be part of the set.  The caller must ensure that
218 * no thread dispatch can happen during the call of this function, otherwise
219 * the behaviour is undefined.  In case a target processor is in a wrong state
220 * to process per-processor jobs, then this function results in an
221 * SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS fatal SMP error.
222 *
223 * @param targets The set of target processors for the action.
224 * @param handler The multicast action handler.
225 * @param arg The multicast action argument.
226 */
227void _SMP_Multicast_action(
228  const Processor_mask *targets,
229  SMP_Action_handler    handler,
230  void                 *arg
231);
232
233/**
234 * @brief Initiates an SMP multicast action to the set of all online
235 * processors.
236 *
237 * Simply calls _SMP_Multicast_action() with _SMP_Get_online_processors() as
238 * the target processor set.
239 *
240 * @param handler The multicast action handler.
241 * @param arg The multicast action argument.
242 */
243void _SMP_Broadcast_action(
244  SMP_Action_handler  handler,
245  void               *arg
246);
247
248/**
249 * @brief Initiates an SMP multicast action to the set of all online
250 * processors excluding the current processor.
251 *
252 * Simply calls _SMP_Multicast_action() with _SMP_Get_online_processors() as
253 * the target processor set excluding the current processor.
254 *
255 * @param handler The multicast action handler.
256 * @param arg The multicast action argument.
257 */
258void _SMP_Othercast_action(
259  SMP_Action_handler  handler,
260  void               *arg
261);
262
263/**
264 * @brief Initiates an SMP action on the specified target processor.
265 *
266 * This is an optimized variant of _SMP_Multicast_action().
267 *
268 * @param cpu_index The index of the target processor.
269 * @param handler The action handler.
270 * @param arg The action argument.
271 */
272void _SMP_Unicast_action(
273  uint32_t            cpu_index,
274  SMP_Action_handler  handler,
275  void               *arg
276);
277
278/**
279 * @brief Ensures that all store operations issued by the current processor
280 * before the call this function are visible to all other online processors.
281 *
282 * Simply calls _SMP_Othercast_action() with an empty multicast action.
283 */
284void _SMP_Synchronize( void );
285
286#endif /* defined( RTEMS_SMP ) */
287
288/**
289 * @brief Requests a multitasking start on all configured and available
290 * processors.
291 */
292#if defined( RTEMS_SMP )
293  void _SMP_Request_start_multitasking( void );
294#else
295  #define _SMP_Request_start_multitasking() \
296    do { } while ( 0 )
297#endif
298
299/**
300 * @brief Requests a shutdown of all processors.
301 *
302 * This function is a part of the system termination procedure.
303 *
304 * @see _Terminate().
305 */
306#if defined( RTEMS_SMP )
307  void _SMP_Request_shutdown( void );
308#else
309  #define _SMP_Request_shutdown() \
310    do { } while ( 0 )
311#endif
312
313/**
314 * @brief Gets all online processors
315 *
316 * @return The processor mask with all online processors.
317 */
318RTEMS_INLINE_ROUTINE const Processor_mask *_SMP_Get_online_processors( void )
319{
320#if defined(RTEMS_SMP)
321  return &_SMP_Online_processors;
322#else
323  return &_Processor_mask_The_one_and_only;
324#endif
325}
326
327/** @} */
328
329#ifdef __cplusplus
330}
331#endif
332
333#endif
334/* end of include file */
Note: See TracBrowser for help on using the repository browser.