[6ca4f6a] | 1 | /** |
---|
| 2 | * @file |
---|
| 3 | * |
---|
| 4 | * @ingroup ScoreSMPImpl |
---|
| 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 |
---|
[c499856] | 15 | * http://www.rtems.org/license/LICENSE. |
---|
[6ca4f6a] | 16 | */ |
---|
| 17 | |
---|
| 18 | #ifndef _RTEMS_SCORE_SMPIMPL_H |
---|
| 19 | #define _RTEMS_SCORE_SMPIMPL_H |
---|
| 20 | |
---|
| 21 | #include <rtems/score/smp.h> |
---|
[8a65a960] | 22 | #include <rtems/score/percpu.h> |
---|
| 23 | #include <rtems/fatal.h> |
---|
[6ca4f6a] | 24 | |
---|
| 25 | #ifdef __cplusplus |
---|
| 26 | extern "C" { |
---|
| 27 | #endif |
---|
| 28 | |
---|
| 29 | /** |
---|
| 30 | * @defgroup ScoreSMP SMP Support |
---|
| 31 | * |
---|
| 32 | * @ingroup Score |
---|
| 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 UINT32_C(0x1) |
---|
| 45 | |
---|
[145becf] | 46 | /** |
---|
| 47 | * @brief SMP message to request a test handler invocation. |
---|
| 48 | * |
---|
| 49 | * @see _SMP_Send_message(). |
---|
| 50 | */ |
---|
| 51 | #define SMP_MESSAGE_TEST UINT32_C(0x2) |
---|
| 52 | |
---|
[6ca4f6a] | 53 | /** |
---|
| 54 | * @brief SMP fatal codes. |
---|
| 55 | */ |
---|
| 56 | typedef enum { |
---|
[79e2d9b] | 57 | SMP_FATAL_SHUTDOWN, |
---|
[53e008b] | 58 | SMP_FATAL_SHUTDOWN_EARLY, |
---|
[c5831a3f] | 59 | SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER, |
---|
| 60 | SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT, |
---|
| 61 | SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR, |
---|
[53e008b] | 62 | SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED |
---|
[6ca4f6a] | 63 | } SMP_Fatal_code; |
---|
| 64 | |
---|
[c5831a3f] | 65 | static inline void _SMP_Fatal( SMP_Fatal_code code ) |
---|
| 66 | { |
---|
| 67 | _Terminate( RTEMS_FATAL_SOURCE_SMP, false, code ); |
---|
| 68 | } |
---|
| 69 | |
---|
[6ca4f6a] | 70 | /** |
---|
| 71 | * @brief Initialize SMP Handler |
---|
| 72 | * |
---|
| 73 | * This method initialize the SMP Handler. |
---|
| 74 | */ |
---|
| 75 | #if defined( RTEMS_SMP ) |
---|
| 76 | void _SMP_Handler_initialize( void ); |
---|
| 77 | #else |
---|
| 78 | #define _SMP_Handler_initialize() \ |
---|
| 79 | do { } while ( 0 ) |
---|
| 80 | #endif |
---|
| 81 | |
---|
| 82 | #if defined( RTEMS_SMP ) |
---|
| 83 | |
---|
[911b1d2] | 84 | /** |
---|
| 85 | * @brief Performs high-level initialization of a secondary processor and runs |
---|
| 86 | * the application threads. |
---|
| 87 | * |
---|
| 88 | * The low-level initialization code must call this function to hand over the |
---|
| 89 | * control of this processor to RTEMS. Interrupts must be disabled. It must |
---|
| 90 | * be possible to send inter-processor interrupts to this processor. Since |
---|
| 91 | * interrupts are disabled the inter-processor interrupt delivery is postponed |
---|
| 92 | * until interrupts are enabled the first time. Interrupts are enabled during |
---|
| 93 | * the execution begin of threads in case they have interrupt level zero (this |
---|
| 94 | * is the default). |
---|
| 95 | * |
---|
| 96 | * The pre-requisites for the call to this function are |
---|
| 97 | * - disabled interrupts, |
---|
| 98 | * - delivery of inter-processor interrupts is possible, |
---|
| 99 | * - a valid stack pointer and enough stack space, |
---|
| 100 | * - a valid code memory, and |
---|
| 101 | * - a valid BSS section. |
---|
| 102 | * |
---|
| 103 | * This function must not be called by the main processor. The main processor |
---|
| 104 | * uses _Thread_Start_multitasking() instead. |
---|
| 105 | * |
---|
| 106 | * This function does not return to the caller. |
---|
| 107 | */ |
---|
| 108 | void _SMP_Start_multitasking_on_secondary_processor( void ) |
---|
| 109 | RTEMS_COMPILER_NO_RETURN_ATTRIBUTE; |
---|
| 110 | |
---|
[145becf] | 111 | typedef void ( *SMP_Test_message_handler )( Per_CPU_Control *cpu_self ); |
---|
| 112 | |
---|
| 113 | extern SMP_Test_message_handler _SMP_Test_message_handler; |
---|
| 114 | |
---|
| 115 | /** |
---|
| 116 | * @brief Sets the handler for test messages. |
---|
| 117 | * |
---|
| 118 | * This handler can be used to test the inter-processor interrupt |
---|
| 119 | * implementation. |
---|
| 120 | */ |
---|
| 121 | static inline void _SMP_Set_test_message_handler( |
---|
| 122 | SMP_Test_message_handler handler |
---|
| 123 | ) |
---|
| 124 | { |
---|
| 125 | _SMP_Test_message_handler = handler; |
---|
| 126 | } |
---|
| 127 | |
---|
[4d9bd56] | 128 | /** |
---|
| 129 | * @brief Interrupt handler for inter-processor interrupts. |
---|
| 130 | */ |
---|
[8a65a960] | 131 | static inline void _SMP_Inter_processor_interrupt_handler( void ) |
---|
| 132 | { |
---|
[3380ee8] | 133 | Per_CPU_Control *cpu_self = _Per_CPU_Get(); |
---|
[8a65a960] | 134 | |
---|
[3380ee8] | 135 | if ( cpu_self->message != 0 ) { |
---|
[8a65a960] | 136 | uint32_t message; |
---|
| 137 | ISR_Level level; |
---|
| 138 | |
---|
[3380ee8] | 139 | _Per_CPU_ISR_disable_and_acquire( cpu_self, level ); |
---|
| 140 | message = cpu_self->message; |
---|
| 141 | cpu_self->message = 0; |
---|
| 142 | _Per_CPU_Release_and_ISR_enable( cpu_self, level ); |
---|
[8a65a960] | 143 | |
---|
| 144 | if ( ( message & SMP_MESSAGE_SHUTDOWN ) != 0 ) { |
---|
| 145 | rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN ); |
---|
| 146 | /* does not continue past here */ |
---|
| 147 | } |
---|
[145becf] | 148 | |
---|
| 149 | if ( ( message & SMP_MESSAGE_TEST ) != 0 ) { |
---|
| 150 | ( *_SMP_Test_message_handler )( cpu_self ); |
---|
| 151 | } |
---|
[8a65a960] | 152 | } |
---|
| 153 | } |
---|
[4d9bd56] | 154 | |
---|
[6ca4f6a] | 155 | /** |
---|
| 156 | * @brief Sends a SMP message to a processor. |
---|
| 157 | * |
---|
| 158 | * The target processor may be the sending processor. |
---|
| 159 | * |
---|
[3380ee8] | 160 | * @param[in] cpu_index The target processor of the message. |
---|
[6ca4f6a] | 161 | * @param[in] message The message. |
---|
| 162 | */ |
---|
[3380ee8] | 163 | void _SMP_Send_message( uint32_t cpu_index, uint32_t message ); |
---|
[6ca4f6a] | 164 | |
---|
| 165 | /** |
---|
| 166 | * @brief Request of others CPUs. |
---|
| 167 | * |
---|
| 168 | * This method is invoked by RTEMS when it needs to make a request |
---|
| 169 | * of the other CPUs. It should be implemented using some type of |
---|
| 170 | * interprocessor interrupt. CPUs not including the originating |
---|
| 171 | * CPU should receive the message. |
---|
| 172 | * |
---|
| 173 | * @param [in] message is message to send |
---|
| 174 | */ |
---|
| 175 | void _SMP_Broadcast_message( |
---|
| 176 | uint32_t message |
---|
| 177 | ); |
---|
| 178 | |
---|
| 179 | #endif /* defined( RTEMS_SMP ) */ |
---|
| 180 | |
---|
| 181 | /** |
---|
[7336be9d] | 182 | * @brief Requests a multitasking start on all configured and available |
---|
| 183 | * processors. |
---|
[6ca4f6a] | 184 | */ |
---|
| 185 | #if defined( RTEMS_SMP ) |
---|
[7336be9d] | 186 | void _SMP_Request_start_multitasking( void ); |
---|
[6ca4f6a] | 187 | #else |
---|
[7336be9d] | 188 | #define _SMP_Request_start_multitasking() \ |
---|
[6ca4f6a] | 189 | do { } while ( 0 ) |
---|
| 190 | #endif |
---|
| 191 | |
---|
| 192 | /** |
---|
[7336be9d] | 193 | * @brief Requests a shutdown of all processors. |
---|
| 194 | * |
---|
| 195 | * This function is a part of the system termination procedure. |
---|
[6ca4f6a] | 196 | * |
---|
[7336be9d] | 197 | * @see _Terminate(). |
---|
[6ca4f6a] | 198 | */ |
---|
| 199 | #if defined( RTEMS_SMP ) |
---|
[7336be9d] | 200 | void _SMP_Request_shutdown( void ); |
---|
[6ca4f6a] | 201 | #else |
---|
[7336be9d] | 202 | #define _SMP_Request_shutdown() \ |
---|
[6ca4f6a] | 203 | do { } while ( 0 ) |
---|
| 204 | #endif |
---|
| 205 | |
---|
| 206 | /** @} */ |
---|
| 207 | |
---|
| 208 | #ifdef __cplusplus |
---|
| 209 | } |
---|
| 210 | #endif |
---|
| 211 | |
---|
| 212 | #endif |
---|
| 213 | /* end of include file */ |
---|