source: rtems/cpukit/include/rtems/score/smpimpl.h @ 7fdf48a

Last change on this file since 7fdf48a was 7fdf48a, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 28, 2019 at 12:29:21 PM

score: Add _SMP_Othercast_action()

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