File indexing completed on 2025-05-11 08:24:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054
0055 #include <setjmp.h>
0056 #include <rtems/sysinit.h>
0057 #include <rtems/score/atomic.h>
0058 #include <rtems/score/percpu.h>
0059 #include <rtems/score/smpimpl.h>
0060
0061 #include "tr-fatal-smp.h"
0062 #include "tx-support.h"
0063
0064 #include <rtems/test.h>
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101 typedef struct {
0102
0103
0104
0105
0106 rtems_fatal_source source;
0107
0108
0109
0110
0111
0112 rtems_fatal_code code;
0113 } ScoreSmpValFatal_Context;
0114
0115 static ScoreSmpValFatal_Context
0116 ScoreSmpValFatal_Instance;
0117
0118 static void TriggerTestCase( void )
0119 {
0120 _SMP_Request_shutdown();
0121 (void) _CPU_Thread_Idle_body( 0 );
0122 }
0123
0124 RTEMS_SYSINIT_ITEM(
0125 TriggerTestCase,
0126 RTEMS_SYSINIT_DEVICE_DRIVERS,
0127 RTEMS_SYSINIT_ORDER_MIDDLE
0128 );
0129
0130 static jmp_buf fatal_before;
0131
0132 static Atomic_Uint fatal_counter;
0133
0134 static rtems_fatal_source fatal_source;
0135
0136 static rtems_fatal_code fatal_code;
0137
0138 static void FatalRecordAndJump(
0139 rtems_fatal_source source,
0140 rtems_fatal_code code,
0141 void *arg
0142 )
0143 {
0144 (void) arg;
0145
0146 fatal_source = source;
0147 fatal_code = code;
0148 _Atomic_Fetch_add_uint( &fatal_counter, 1, ATOMIC_ORDER_RELAXED );
0149 _ISR_Set_level( 0 );
0150 longjmp( fatal_before, 1 );
0151 }
0152
0153 static void DoNothing( void *arg )
0154 {
0155 (void) arg;
0156 }
0157
0158 static const Per_CPU_Job_context job_context = {
0159 .handler = DoNothing
0160 };
0161
0162 Per_CPU_Job job = {
0163 .context = &job_context
0164 };
0165
0166 static T_fixture ScoreSmpValFatal_Fixture = {
0167 .setup = NULL,
0168 .stop = NULL,
0169 .teardown = NULL,
0170 .scope = NULL,
0171 .initial_context = &ScoreSmpValFatal_Instance
0172 };
0173
0174
0175
0176
0177 static void ScoreSmpValFatal_Action_0( ScoreSmpValFatal_Context *ctx )
0178 {
0179
0180
0181
0182
0183
0184 T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
0185
0186
0187
0188
0189 T_step_eq_ulong( 1, ctx->code, SMP_FATAL_SHUTDOWN_RESPONSE );
0190
0191
0192
0193
0194 T_step_eq_int(
0195 2,
0196 _Per_CPU_Get_state( _Per_CPU_Get() ),
0197 PER_CPU_STATE_SHUTDOWN
0198 );
0199
0200
0201
0202
0203
0204 _SMP_Process_message( _Per_CPU_Get(), SMP_MESSAGE_SHUTDOWN );
0205 }
0206
0207
0208
0209
0210
0211 static void ScoreSmpValFatal_Action_1( ScoreSmpValFatal_Context *ctx )
0212 {
0213 Per_CPU_Control *cpu;
0214
0215 SetFatalHandler( FatalRecordAndJump, ctx );
0216 cpu = _Per_CPU_Get_by_index( 0 );
0217 _Per_CPU_Submit_job( cpu, &job );
0218
0219 if ( setjmp( fatal_before ) == 0 ) {
0220 _Per_CPU_Wait_for_job( cpu, &job );
0221 }
0222
0223 T_step_eq_uint(
0224 3,
0225 _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
0226 1
0227 );
0228 T_step_eq_int( 4, fatal_source, RTEMS_FATAL_SOURCE_SMP );
0229 T_step_eq_ulong(
0230 5,
0231 fatal_code,
0232 SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS
0233 );
0234 SetFatalHandler( NULL, NULL );
0235 }
0236
0237
0238
0239
0240
0241 static void ScoreSmpValFatal_Action_2( ScoreSmpValFatal_Context *ctx )
0242 {
0243 Per_CPU_Control *cpu;
0244
0245 SetFatalHandler( FatalRecordAndJump, ctx );
0246
0247
0248
0249
0250
0251
0252 cpu = _Per_CPU_Get_by_index( 3 );
0253
0254 if ( setjmp( fatal_before ) == 0 ) {
0255 _SMP_Start_multitasking_on_secondary_processor( cpu );
0256 }
0257
0258 T_step_eq_uint(
0259 6,
0260 _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
0261 2
0262 );
0263 T_step_eq_int( 7, fatal_source, RTEMS_FATAL_SOURCE_SMP );
0264 T_step_eq_ulong(
0265 8,
0266 fatal_code,
0267 SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR
0268 );
0269 SetFatalHandler( NULL, NULL );
0270 }
0271
0272
0273
0274
0275
0276 static void ScoreSmpValFatal_Action_3( ScoreSmpValFatal_Context *ctx )
0277 {
0278 Per_CPU_Control *cpu;
0279
0280 SetFatalHandler( FatalRecordAndJump, ctx );
0281 cpu = _Per_CPU_Get_by_index( 2 );
0282
0283 if ( setjmp( fatal_before ) == 0 ) {
0284 _SMP_Start_multitasking_on_secondary_processor( cpu );
0285 }
0286
0287 T_step_eq_uint(
0288 9,
0289 _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
0290 3
0291 );
0292 T_step_eq_int( 10, fatal_source, RTEMS_FATAL_SOURCE_SMP );
0293 T_step_eq_ulong(
0294 11,
0295 fatal_code,
0296 SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR
0297 );
0298 SetFatalHandler( NULL, NULL );
0299 }
0300
0301 void ScoreSmpValFatal_Run( rtems_fatal_source source, rtems_fatal_code code )
0302 {
0303 ScoreSmpValFatal_Context *ctx;
0304
0305 ctx = &ScoreSmpValFatal_Instance;
0306 ctx->source = source;
0307 ctx->code = code;
0308
0309 ctx = T_case_begin( "ScoreSmpValFatal", &ScoreSmpValFatal_Fixture );
0310
0311 T_plan( 12 );
0312
0313 ScoreSmpValFatal_Action_0( ctx );
0314 ScoreSmpValFatal_Action_1( ctx );
0315 ScoreSmpValFatal_Action_2( ctx );
0316 ScoreSmpValFatal_Action_3( ctx );
0317
0318 T_case_end();
0319 }
0320
0321