File indexing completed on 2025-05-11 08:24:51
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 <bsp/irq-generic.h>
0057
0058 #include "tx-support.h"
0059
0060 #include <rtems/test.h>
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 typedef enum {
0072 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Null,
0073 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Entry,
0074 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_NA
0075 } BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst;
0076
0077 typedef enum {
0078 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Null,
0079 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Entry,
0080 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA
0081 } BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain;
0082
0083 typedef enum {
0084 BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
0085 BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch,
0086 BspReqInterruptHandlerDispatchUnchecked_Post_Result_NA
0087 } BspReqInterruptHandlerDispatchUnchecked_Post_Result;
0088
0089 typedef enum {
0090 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
0091 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA
0092 } BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource;
0093
0094 typedef enum {
0095 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector,
0096 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA
0097 } BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode;
0098
0099 typedef struct {
0100 uint8_t Skip : 1;
0101 uint8_t Pre_LoadFirst_NA : 1;
0102 uint8_t Pre_LoadFirstAgain_NA : 1;
0103 uint8_t Post_Result : 2;
0104 uint8_t Post_FatalSource : 1;
0105 uint8_t Post_FatalCode : 1;
0106 } BspReqInterruptHandlerDispatchUnchecked_Entry;
0107
0108
0109
0110
0111
0112 typedef struct {
0113
0114
0115
0116
0117 rtems_interrupt_entry *entry_to_restore;
0118
0119
0120
0121
0122 jmp_buf before_call;
0123
0124
0125
0126
0127 rtems_interrupt_entry entry;
0128
0129
0130
0131
0132 volatile bool interrupt_occurred;
0133
0134
0135
0136
0137 uint32_t entry_counter;
0138
0139
0140
0141
0142 uint32_t fatal_counter;
0143
0144
0145
0146
0147 rtems_fatal_source fatal_source;
0148
0149
0150
0151
0152 rtems_fatal_code fatal_code;
0153
0154
0155
0156
0157 rtems_vector_number test_vector;
0158
0159
0160
0161
0162
0163 rtems_interrupt_entry **first;
0164
0165
0166
0167
0168
0169 rtems_interrupt_entry *first_again;
0170
0171 struct {
0172
0173
0174
0175
0176 size_t pci[ 2 ];
0177
0178
0179
0180
0181 size_t pcs[ 2 ];
0182
0183
0184
0185
0186 bool in_action_loop;
0187
0188
0189
0190
0191 size_t index;
0192
0193
0194
0195
0196 BspReqInterruptHandlerDispatchUnchecked_Entry entry;
0197
0198
0199
0200
0201
0202 bool skip;
0203 } Map;
0204 } BspReqInterruptHandlerDispatchUnchecked_Context;
0205
0206 static BspReqInterruptHandlerDispatchUnchecked_Context
0207 BspReqInterruptHandlerDispatchUnchecked_Instance;
0208
0209 static const char * const BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirst[] = {
0210 "Null",
0211 "Entry",
0212 "NA"
0213 };
0214
0215 static const char * const BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirstAgain[] = {
0216 "Null",
0217 "Entry",
0218 "NA"
0219 };
0220
0221 static const char * const * const BspReqInterruptHandlerDispatchUnchecked_PreDesc[] = {
0222 BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirst,
0223 BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirstAgain,
0224 NULL
0225 };
0226
0227 typedef BspReqInterruptHandlerDispatchUnchecked_Context Context;
0228
0229 static bool test_case_active;
0230
0231 static void Disable( const Context *ctx )
0232 {
0233 (void) rtems_interrupt_vector_disable( ctx->test_vector );
0234 }
0235
0236 static void ProcessInterrupt( Context *ctx )
0237 {
0238 ctx->interrupt_occurred = true;
0239 CallWithinISRClear();
0240 Disable( ctx );
0241 }
0242
0243 static void EntryRoutine( void *arg )
0244 {
0245 Context *ctx;
0246
0247 ctx = arg;
0248 ++ctx->entry_counter;
0249 ProcessInterrupt( ctx );
0250 }
0251
0252 static void Fatal(
0253 rtems_fatal_source source,
0254 rtems_fatal_code code,
0255 void *arg
0256 )
0257 {
0258 Context *ctx;
0259
0260 ctx = arg;
0261 ctx->fatal_source = source;
0262 ctx->fatal_code = code;
0263 ++ctx->fatal_counter;
0264 longjmp( ctx->before_call, 1 );
0265 }
0266
0267 void __real_bsp_interrupt_handler_default( rtems_vector_number vector );
0268
0269 void __wrap_bsp_interrupt_handler_default( rtems_vector_number vector );
0270
0271 void __wrap_bsp_interrupt_handler_default( rtems_vector_number vector )
0272 {
0273 if ( test_case_active ) {
0274 Context *ctx;
0275
0276 ctx = T_fixture_context();
0277 ProcessInterrupt( ctx );
0278
0279 if ( setjmp( ctx->before_call ) == 0 ) {
0280 __real_bsp_interrupt_handler_default( vector );
0281 }
0282 } else {
0283 __real_bsp_interrupt_handler_default( vector );
0284 }
0285 }
0286
0287 #if defined(RTEMS_SMP)
0288 void __real_bsp_interrupt_spurious( rtems_vector_number vector );
0289
0290 void __wrap_bsp_interrupt_spurious( rtems_vector_number vector );
0291
0292 void __wrap_bsp_interrupt_spurious( rtems_vector_number vector )
0293 {
0294 if ( test_case_active ) {
0295 Context *ctx;
0296
0297 ctx = T_fixture_context();
0298 *ctx->first = ctx->first_again;
0299 }
0300
0301 __real_bsp_interrupt_spurious( vector );
0302 }
0303 #endif
0304
0305 static void BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Prepare(
0306 BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
0307 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst state
0308 )
0309 {
0310 switch ( state ) {
0311 case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Null: {
0312
0313
0314
0315
0316
0317 *ctx->first = NULL;
0318 break;
0319 }
0320
0321 case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Entry: {
0322
0323
0324
0325
0326
0327 *ctx->first = &ctx->entry;
0328 break;
0329 }
0330
0331 case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_NA:
0332 break;
0333 }
0334 }
0335
0336 static void BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Prepare(
0337 BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
0338 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain state
0339 )
0340 {
0341 switch ( state ) {
0342 case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Null: {
0343
0344
0345
0346
0347
0348 ctx->first_again = NULL;
0349 break;
0350 }
0351
0352 case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Entry: {
0353
0354
0355
0356
0357
0358 ctx->first_again = &ctx->entry;
0359 break;
0360 }
0361
0362 case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA:
0363 break;
0364 }
0365 }
0366
0367 static void BspReqInterruptHandlerDispatchUnchecked_Post_Result_Check(
0368 BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
0369 BspReqInterruptHandlerDispatchUnchecked_Post_Result state
0370 )
0371 {
0372 switch ( state ) {
0373 case BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError: {
0374
0375
0376
0377 T_eq_u32( ctx->entry_counter, 0 );
0378 T_eq_u32( ctx->fatal_counter, 1 );
0379 break;
0380 }
0381
0382 case BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch: {
0383
0384
0385
0386
0387 T_eq_u32( ctx->entry_counter, 1 );
0388 T_eq_u32( ctx->fatal_counter, 0 );
0389 break;
0390 }
0391
0392 case BspReqInterruptHandlerDispatchUnchecked_Post_Result_NA:
0393 break;
0394 }
0395 }
0396
0397 static void BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_Check(
0398 BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
0399 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource state
0400 )
0401 {
0402 switch ( state ) {
0403 case BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt: {
0404
0405
0406
0407
0408 T_eq_int( ctx->fatal_source, RTEMS_FATAL_SOURCE_SPURIOUS_INTERRUPT );
0409 break;
0410 }
0411
0412 case BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA:
0413 break;
0414 }
0415 }
0416
0417 static void BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Check(
0418 BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
0419 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode state
0420 )
0421 {
0422 switch ( state ) {
0423 case BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector: {
0424
0425
0426
0427 T_eq_ulong( ctx->fatal_code, ctx->test_vector );
0428 break;
0429 }
0430
0431 case BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA:
0432 break;
0433 }
0434 }
0435
0436 static void BspReqInterruptHandlerDispatchUnchecked_Setup(
0437 BspReqInterruptHandlerDispatchUnchecked_Context *ctx
0438 )
0439 {
0440 ctx->first = NULL;
0441 ctx->test_vector = CallWithinISRGetVector();
0442 T_assert_lt_u32( ctx->test_vector, BSP_INTERRUPT_VECTOR_COUNT );
0443 ctx->first = &bsp_interrupt_dispatch_table[
0444 bsp_interrupt_dispatch_index( ctx->test_vector )
0445 ];
0446 ctx->entry_to_restore = *ctx->first;
0447
0448 rtems_interrupt_entry_initialize( &ctx->entry, EntryRoutine, ctx, "Info" );
0449 test_case_active = true;
0450 SetFatalHandler( Fatal, ctx );
0451 }
0452
0453 static void BspReqInterruptHandlerDispatchUnchecked_Setup_Wrap( void *arg )
0454 {
0455 BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
0456
0457 ctx = arg;
0458 ctx->Map.in_action_loop = false;
0459 BspReqInterruptHandlerDispatchUnchecked_Setup( ctx );
0460 }
0461
0462 static void BspReqInterruptHandlerDispatchUnchecked_Teardown(
0463 BspReqInterruptHandlerDispatchUnchecked_Context *ctx
0464 )
0465 {
0466 SetFatalHandler( NULL, NULL );
0467 test_case_active = false;
0468
0469 if ( ctx->first != NULL ) {
0470 *ctx->first = ctx->entry_to_restore;
0471 }
0472 }
0473
0474 static void BspReqInterruptHandlerDispatchUnchecked_Teardown_Wrap( void *arg )
0475 {
0476 BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
0477
0478 ctx = arg;
0479 ctx->Map.in_action_loop = false;
0480 BspReqInterruptHandlerDispatchUnchecked_Teardown( ctx );
0481 }
0482
0483 static void BspReqInterruptHandlerDispatchUnchecked_Action(
0484 BspReqInterruptHandlerDispatchUnchecked_Context *ctx
0485 )
0486 {
0487 ctx->interrupt_occurred = false;
0488 ctx->entry_counter = 0;
0489 ctx->fatal_counter = 0;
0490 ctx->fatal_source = RTEMS_FATAL_SOURCE_LAST;
0491 ctx->fatal_code = UINT32_MAX;
0492
0493 (void) rtems_interrupt_vector_enable( ctx->test_vector );
0494
0495 CallWithinISRRaise();
0496
0497 while ( !ctx->interrupt_occurred ) {
0498
0499 }
0500
0501 Disable( ctx );
0502 }
0503
0504 static const BspReqInterruptHandlerDispatchUnchecked_Entry
0505 BspReqInterruptHandlerDispatchUnchecked_Entries[] = {
0506 { 0, 0, 1, BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch,
0507 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA,
0508 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA },
0509 #if defined(RTEMS_SMP)
0510 { 0, 0, 0, BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
0511 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
0512 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector },
0513 #else
0514 { 0, 0, 1, BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
0515 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
0516 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector },
0517 #endif
0518 #if defined(RTEMS_SMP)
0519 { 0, 0, 0, BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch,
0520 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA,
0521 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA }
0522 #else
0523 { 0, 0, 1, BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
0524 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
0525 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector }
0526 #endif
0527 };
0528
0529 static const uint8_t
0530 BspReqInterruptHandlerDispatchUnchecked_Map[] = {
0531 1, 2, 0, 0
0532 };
0533
0534 static size_t BspReqInterruptHandlerDispatchUnchecked_Scope(
0535 void *arg,
0536 char *buf,
0537 size_t n
0538 )
0539 {
0540 BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
0541
0542 ctx = arg;
0543
0544 if ( ctx->Map.in_action_loop ) {
0545 return T_get_scope(
0546 BspReqInterruptHandlerDispatchUnchecked_PreDesc,
0547 buf,
0548 n,
0549 ctx->Map.pcs
0550 );
0551 }
0552
0553 return 0;
0554 }
0555
0556 static T_fixture BspReqInterruptHandlerDispatchUnchecked_Fixture = {
0557 .setup = BspReqInterruptHandlerDispatchUnchecked_Setup_Wrap,
0558 .stop = NULL,
0559 .teardown = BspReqInterruptHandlerDispatchUnchecked_Teardown_Wrap,
0560 .scope = BspReqInterruptHandlerDispatchUnchecked_Scope,
0561 .initial_context = &BspReqInterruptHandlerDispatchUnchecked_Instance
0562 };
0563
0564 static inline BspReqInterruptHandlerDispatchUnchecked_Entry
0565 BspReqInterruptHandlerDispatchUnchecked_PopEntry(
0566 BspReqInterruptHandlerDispatchUnchecked_Context *ctx
0567 )
0568 {
0569 size_t index;
0570
0571 index = ctx->Map.index;
0572 ctx->Map.index = index + 1;
0573 return BspReqInterruptHandlerDispatchUnchecked_Entries[
0574 BspReqInterruptHandlerDispatchUnchecked_Map[ index ]
0575 ];
0576 }
0577
0578 static void BspReqInterruptHandlerDispatchUnchecked_SetPreConditionStates(
0579 BspReqInterruptHandlerDispatchUnchecked_Context *ctx
0580 )
0581 {
0582 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0583
0584 if ( ctx->Map.entry.Pre_LoadFirstAgain_NA ) {
0585 ctx->Map.pcs[ 1 ] = BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA;
0586 } else {
0587 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0588 }
0589 }
0590
0591 static void BspReqInterruptHandlerDispatchUnchecked_TestVariant(
0592 BspReqInterruptHandlerDispatchUnchecked_Context *ctx
0593 )
0594 {
0595 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Prepare(
0596 ctx,
0597 ctx->Map.pcs[ 0 ]
0598 );
0599 BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Prepare(
0600 ctx,
0601 ctx->Map.pcs[ 1 ]
0602 );
0603 BspReqInterruptHandlerDispatchUnchecked_Action( ctx );
0604 BspReqInterruptHandlerDispatchUnchecked_Post_Result_Check(
0605 ctx,
0606 ctx->Map.entry.Post_Result
0607 );
0608 BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_Check(
0609 ctx,
0610 ctx->Map.entry.Post_FatalSource
0611 );
0612 BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Check(
0613 ctx,
0614 ctx->Map.entry.Post_FatalCode
0615 );
0616 }
0617
0618
0619
0620
0621 T_TEST_CASE_FIXTURE(
0622 BspReqInterruptHandlerDispatchUnchecked,
0623 &BspReqInterruptHandlerDispatchUnchecked_Fixture
0624 )
0625 {
0626 BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
0627
0628 ctx = T_fixture_context();
0629 ctx->Map.in_action_loop = true;
0630 ctx->Map.index = 0;
0631
0632 for (
0633 ctx->Map.pci[ 0 ] = BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Null;
0634 ctx->Map.pci[ 0 ] < BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_NA;
0635 ++ctx->Map.pci[ 0 ]
0636 ) {
0637 for (
0638 ctx->Map.pci[ 1 ] = BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Null;
0639 ctx->Map.pci[ 1 ] < BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA;
0640 ++ctx->Map.pci[ 1 ]
0641 ) {
0642 ctx->Map.entry = BspReqInterruptHandlerDispatchUnchecked_PopEntry( ctx );
0643 BspReqInterruptHandlerDispatchUnchecked_SetPreConditionStates( ctx );
0644 BspReqInterruptHandlerDispatchUnchecked_TestVariant( ctx );
0645 }
0646 }
0647 }
0648
0649