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 <bsp/irq-generic.h>
0056 #include <rtems/irq-extension.h>
0057
0058 #include "tx-support.h"
0059
0060 #include <rtems/test.h>
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 typedef enum {
0071 RtemsIntrReqHandlerIterate_Pre_Vector_Valid,
0072 RtemsIntrReqHandlerIterate_Pre_Vector_Invalid,
0073 RtemsIntrReqHandlerIterate_Pre_Vector_NA
0074 } RtemsIntrReqHandlerIterate_Pre_Vector;
0075
0076 typedef enum {
0077 RtemsIntrReqHandlerIterate_Pre_Routine_Valid,
0078 RtemsIntrReqHandlerIterate_Pre_Routine_Null,
0079 RtemsIntrReqHandlerIterate_Pre_Routine_NA
0080 } RtemsIntrReqHandlerIterate_Pre_Routine;
0081
0082 typedef enum {
0083 RtemsIntrReqHandlerIterate_Pre_Init_Yes,
0084 RtemsIntrReqHandlerIterate_Pre_Init_No,
0085 RtemsIntrReqHandlerIterate_Pre_Init_NA
0086 } RtemsIntrReqHandlerIterate_Pre_Init;
0087
0088 typedef enum {
0089 RtemsIntrReqHandlerIterate_Pre_ISR_Yes,
0090 RtemsIntrReqHandlerIterate_Pre_ISR_No,
0091 RtemsIntrReqHandlerIterate_Pre_ISR_NA
0092 } RtemsIntrReqHandlerIterate_Pre_ISR;
0093
0094 typedef enum {
0095 RtemsIntrReqHandlerIterate_Post_Status_Ok,
0096 RtemsIntrReqHandlerIterate_Post_Status_InvAddr,
0097 RtemsIntrReqHandlerIterate_Post_Status_IncStat,
0098 RtemsIntrReqHandlerIterate_Post_Status_InvId,
0099 RtemsIntrReqHandlerIterate_Post_Status_CalledFromISR,
0100 RtemsIntrReqHandlerIterate_Post_Status_NA
0101 } RtemsIntrReqHandlerIterate_Post_Status;
0102
0103 typedef enum {
0104 RtemsIntrReqHandlerIterate_Post_Visit_Yes,
0105 RtemsIntrReqHandlerIterate_Post_Visit_Nop,
0106 RtemsIntrReqHandlerIterate_Post_Visit_NA
0107 } RtemsIntrReqHandlerIterate_Post_Visit;
0108
0109 typedef struct {
0110 uint16_t Skip : 1;
0111 uint16_t Pre_Vector_NA : 1;
0112 uint16_t Pre_Routine_NA : 1;
0113 uint16_t Pre_Init_NA : 1;
0114 uint16_t Pre_ISR_NA : 1;
0115 uint16_t Post_Status : 3;
0116 uint16_t Post_Visit : 2;
0117 } RtemsIntrReqHandlerIterate_Entry;
0118
0119
0120
0121
0122 typedef struct {
0123
0124
0125
0126
0127 bool initialized_during_setup;
0128
0129
0130
0131
0132
0133 rtems_vector_number test_vector;
0134
0135
0136
0137
0138
0139 bool test_vector_was_enabled;
0140
0141
0142
0143
0144 bool initialized;
0145
0146
0147
0148
0149
0150 bool isr;
0151
0152
0153
0154
0155 uint32_t visited_entries;
0156
0157
0158
0159
0160 rtems_interrupt_entry entry;
0161
0162
0163
0164
0165 rtems_vector_number vector;
0166
0167
0168
0169
0170 rtems_interrupt_per_handler_routine routine;
0171
0172
0173
0174
0175
0176 rtems_status_code status;
0177
0178 struct {
0179
0180
0181
0182 size_t pcs[ 4 ];
0183
0184
0185
0186
0187 bool in_action_loop;
0188
0189
0190
0191
0192 size_t index;
0193
0194
0195
0196
0197 RtemsIntrReqHandlerIterate_Entry entry;
0198
0199
0200
0201
0202
0203 bool skip;
0204 } Map;
0205 } RtemsIntrReqHandlerIterate_Context;
0206
0207 static RtemsIntrReqHandlerIterate_Context
0208 RtemsIntrReqHandlerIterate_Instance;
0209
0210 static const char * const RtemsIntrReqHandlerIterate_PreDesc_Vector[] = {
0211 "Valid",
0212 "Invalid",
0213 "NA"
0214 };
0215
0216 static const char * const RtemsIntrReqHandlerIterate_PreDesc_Routine[] = {
0217 "Valid",
0218 "Null",
0219 "NA"
0220 };
0221
0222 static const char * const RtemsIntrReqHandlerIterate_PreDesc_Init[] = {
0223 "Yes",
0224 "No",
0225 "NA"
0226 };
0227
0228 static const char * const RtemsIntrReqHandlerIterate_PreDesc_ISR[] = {
0229 "Yes",
0230 "No",
0231 "NA"
0232 };
0233
0234 static const char * const * const RtemsIntrReqHandlerIterate_PreDesc[] = {
0235 RtemsIntrReqHandlerIterate_PreDesc_Vector,
0236 RtemsIntrReqHandlerIterate_PreDesc_Routine,
0237 RtemsIntrReqHandlerIterate_PreDesc_Init,
0238 RtemsIntrReqHandlerIterate_PreDesc_ISR,
0239 NULL
0240 };
0241
0242 typedef RtemsIntrReqHandlerIterate_Context Context;
0243
0244 static char entry_arg;
0245
0246 static char visitor_arg;
0247
0248 static const char entry_info[] = "Entry";
0249
0250 static void EntryRoutine( void *arg )
0251 {
0252 Context *ctx;
0253 rtems_status_code sc;
0254
0255 (void) arg;
0256 ctx = T_fixture_context();
0257 sc = rtems_interrupt_vector_disable( ctx->test_vector );
0258 T_rsc_success( sc );
0259
0260 T_eq_ptr( arg, &entry_arg );
0261 }
0262
0263 static void VisitorRoutine(
0264 void *arg,
0265 const char *info,
0266 rtems_option options,
0267 rtems_interrupt_handler handler_routine,
0268 void *handler_arg
0269 )
0270 {
0271 Context *ctx;
0272
0273 ctx = T_fixture_context();
0274 ++ctx->visited_entries;
0275 T_eq_ptr( arg, &visitor_arg );
0276 T_eq_ptr( info, entry_info );
0277 T_eq_u32( options, RTEMS_INTERRUPT_UNIQUE );
0278 T_eq_ptr( handler_routine, EntryRoutine );
0279 T_eq_ptr( handler_arg, &entry_arg );
0280 }
0281
0282 static void Action( void *arg )
0283 {
0284 Context *ctx;
0285
0286 ctx = arg;
0287 ctx->visited_entries = 0;
0288
0289 bsp_interrupt_set_handler_unique(
0290 BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
0291 ctx->initialized
0292 );
0293
0294 ctx->status = rtems_interrupt_handler_iterate(
0295 ctx->vector,
0296 ctx->routine,
0297 &visitor_arg
0298 );
0299
0300 bsp_interrupt_set_handler_unique(
0301 BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
0302 ctx->initialized_during_setup
0303 );
0304 }
0305
0306 static void RtemsIntrReqHandlerIterate_Pre_Vector_Prepare(
0307 RtemsIntrReqHandlerIterate_Context *ctx,
0308 RtemsIntrReqHandlerIterate_Pre_Vector state
0309 )
0310 {
0311 switch ( state ) {
0312 case RtemsIntrReqHandlerIterate_Pre_Vector_Valid: {
0313
0314
0315
0316 ctx->vector = ctx->test_vector;
0317 break;
0318 }
0319
0320 case RtemsIntrReqHandlerIterate_Pre_Vector_Invalid: {
0321
0322
0323
0324
0325 ctx->vector = BSP_INTERRUPT_VECTOR_COUNT;
0326 break;
0327 }
0328
0329 case RtemsIntrReqHandlerIterate_Pre_Vector_NA:
0330 break;
0331 }
0332 }
0333
0334 static void RtemsIntrReqHandlerIterate_Pre_Routine_Prepare(
0335 RtemsIntrReqHandlerIterate_Context *ctx,
0336 RtemsIntrReqHandlerIterate_Pre_Routine state
0337 )
0338 {
0339 switch ( state ) {
0340 case RtemsIntrReqHandlerIterate_Pre_Routine_Valid: {
0341
0342
0343
0344
0345 ctx->routine = VisitorRoutine;
0346 break;
0347 }
0348
0349 case RtemsIntrReqHandlerIterate_Pre_Routine_Null: {
0350
0351
0352
0353
0354 ctx->routine = NULL;
0355 break;
0356 }
0357
0358 case RtemsIntrReqHandlerIterate_Pre_Routine_NA:
0359 break;
0360 }
0361 }
0362
0363 static void RtemsIntrReqHandlerIterate_Pre_Init_Prepare(
0364 RtemsIntrReqHandlerIterate_Context *ctx,
0365 RtemsIntrReqHandlerIterate_Pre_Init state
0366 )
0367 {
0368 switch ( state ) {
0369 case RtemsIntrReqHandlerIterate_Pre_Init_Yes: {
0370
0371
0372
0373 ctx->initialized = true;
0374 break;
0375 }
0376
0377 case RtemsIntrReqHandlerIterate_Pre_Init_No: {
0378
0379
0380
0381 ctx->initialized = false;
0382 break;
0383 }
0384
0385 case RtemsIntrReqHandlerIterate_Pre_Init_NA:
0386 break;
0387 }
0388 }
0389
0390 static void RtemsIntrReqHandlerIterate_Pre_ISR_Prepare(
0391 RtemsIntrReqHandlerIterate_Context *ctx,
0392 RtemsIntrReqHandlerIterate_Pre_ISR state
0393 )
0394 {
0395 switch ( state ) {
0396 case RtemsIntrReqHandlerIterate_Pre_ISR_Yes: {
0397
0398
0399
0400
0401 ctx->isr = true;
0402 break;
0403 }
0404
0405 case RtemsIntrReqHandlerIterate_Pre_ISR_No: {
0406
0407
0408
0409
0410 ctx->isr = false;
0411 break;
0412 }
0413
0414 case RtemsIntrReqHandlerIterate_Pre_ISR_NA:
0415 break;
0416 }
0417 }
0418
0419 static void RtemsIntrReqHandlerIterate_Post_Status_Check(
0420 RtemsIntrReqHandlerIterate_Context *ctx,
0421 RtemsIntrReqHandlerIterate_Post_Status state
0422 )
0423 {
0424 switch ( state ) {
0425 case RtemsIntrReqHandlerIterate_Post_Status_Ok: {
0426
0427
0428
0429
0430 T_rsc_success( ctx->status );
0431 break;
0432 }
0433
0434 case RtemsIntrReqHandlerIterate_Post_Status_InvAddr: {
0435
0436
0437
0438
0439 T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0440 break;
0441 }
0442
0443 case RtemsIntrReqHandlerIterate_Post_Status_IncStat: {
0444
0445
0446
0447
0448 T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
0449 break;
0450 }
0451
0452 case RtemsIntrReqHandlerIterate_Post_Status_InvId: {
0453
0454
0455
0456
0457 T_rsc( ctx->status, RTEMS_INVALID_ID );
0458 break;
0459 }
0460
0461 case RtemsIntrReqHandlerIterate_Post_Status_CalledFromISR: {
0462
0463
0464
0465
0466 T_rsc( ctx->status, RTEMS_CALLED_FROM_ISR );
0467 break;
0468 }
0469
0470 case RtemsIntrReqHandlerIterate_Post_Status_NA:
0471 break;
0472 }
0473 }
0474
0475 static void RtemsIntrReqHandlerIterate_Post_Visit_Check(
0476 RtemsIntrReqHandlerIterate_Context *ctx,
0477 RtemsIntrReqHandlerIterate_Post_Visit state
0478 )
0479 {
0480 switch ( state ) {
0481 case RtemsIntrReqHandlerIterate_Post_Visit_Yes: {
0482
0483
0484
0485
0486
0487
0488
0489 T_eq_u32( ctx->visited_entries, 1 );
0490 break;
0491 }
0492
0493 case RtemsIntrReqHandlerIterate_Post_Visit_Nop: {
0494
0495
0496
0497 T_eq_u32( ctx->visited_entries, 0 );
0498 break;
0499 }
0500
0501 case RtemsIntrReqHandlerIterate_Post_Visit_NA:
0502 break;
0503 }
0504 }
0505
0506 static void RtemsIntrReqHandlerIterate_Setup(
0507 RtemsIntrReqHandlerIterate_Context *ctx
0508 )
0509 {
0510 rtems_status_code sc;
0511
0512 ctx->initialized_during_setup = bsp_interrupt_is_initialized();
0513 ctx->test_vector = GetTestableInterruptVector( NULL );
0514 ctx->test_vector_was_enabled = false;
0515 (void) rtems_interrupt_vector_is_enabled(
0516 ctx->test_vector,
0517 &ctx->test_vector_was_enabled
0518 );
0519 rtems_interrupt_entry_initialize(
0520 &ctx->entry,
0521 EntryRoutine,
0522 &entry_arg,
0523 entry_info
0524 );
0525 sc = rtems_interrupt_entry_install(
0526 ctx->test_vector,
0527 RTEMS_INTERRUPT_UNIQUE,
0528 &ctx->entry
0529 );
0530 T_rsc_success( sc );
0531 }
0532
0533 static void RtemsIntrReqHandlerIterate_Setup_Wrap( void *arg )
0534 {
0535 RtemsIntrReqHandlerIterate_Context *ctx;
0536
0537 ctx = arg;
0538 ctx->Map.in_action_loop = false;
0539 RtemsIntrReqHandlerIterate_Setup( ctx );
0540 }
0541
0542 static void RtemsIntrReqHandlerIterate_Teardown(
0543 RtemsIntrReqHandlerIterate_Context *ctx
0544 )
0545 {
0546 rtems_status_code sc;
0547
0548 sc = rtems_interrupt_entry_remove(
0549 ctx->test_vector,
0550 &ctx->entry
0551 );
0552 T_rsc_success( sc );
0553
0554 if ( ctx->test_vector_was_enabled ) {
0555 (void) rtems_interrupt_vector_enable( ctx->test_vector );
0556 }
0557 }
0558
0559 static void RtemsIntrReqHandlerIterate_Teardown_Wrap( void *arg )
0560 {
0561 RtemsIntrReqHandlerIterate_Context *ctx;
0562
0563 ctx = arg;
0564 ctx->Map.in_action_loop = false;
0565 RtemsIntrReqHandlerIterate_Teardown( ctx );
0566 }
0567
0568 static void RtemsIntrReqHandlerIterate_Action(
0569 RtemsIntrReqHandlerIterate_Context *ctx
0570 )
0571 {
0572 if ( ctx->isr ) {
0573 CallWithinISR( Action, ctx );
0574 } else {
0575 Action( ctx );
0576 }
0577 }
0578
0579 static const RtemsIntrReqHandlerIterate_Entry
0580 RtemsIntrReqHandlerIterate_Entries[] = {
0581 { 0, 0, 0, 0, 0, RtemsIntrReqHandlerIterate_Post_Status_IncStat,
0582 RtemsIntrReqHandlerIterate_Post_Visit_Nop },
0583 { 0, 0, 0, 0, 0, RtemsIntrReqHandlerIterate_Post_Status_InvAddr,
0584 RtemsIntrReqHandlerIterate_Post_Visit_NA },
0585 { 0, 0, 0, 0, 0, RtemsIntrReqHandlerIterate_Post_Status_IncStat,
0586 RtemsIntrReqHandlerIterate_Post_Visit_NA },
0587 { 0, 0, 0, 0, 0, RtemsIntrReqHandlerIterate_Post_Status_InvId,
0588 RtemsIntrReqHandlerIterate_Post_Visit_Nop },
0589 { 0, 0, 0, 0, 0, RtemsIntrReqHandlerIterate_Post_Status_CalledFromISR,
0590 RtemsIntrReqHandlerIterate_Post_Visit_Nop },
0591 { 0, 0, 0, 0, 0, RtemsIntrReqHandlerIterate_Post_Status_Ok,
0592 RtemsIntrReqHandlerIterate_Post_Visit_Yes }
0593 };
0594
0595 static const uint8_t
0596 RtemsIntrReqHandlerIterate_Map[] = {
0597 4, 5, 0, 0, 1, 1, 2, 2, 3, 3, 0, 0, 1, 1, 2, 2
0598 };
0599
0600 static size_t RtemsIntrReqHandlerIterate_Scope(
0601 void *arg,
0602 char *buf,
0603 size_t n
0604 )
0605 {
0606 RtemsIntrReqHandlerIterate_Context *ctx;
0607
0608 ctx = arg;
0609
0610 if ( ctx->Map.in_action_loop ) {
0611 return T_get_scope(
0612 RtemsIntrReqHandlerIterate_PreDesc,
0613 buf,
0614 n,
0615 ctx->Map.pcs
0616 );
0617 }
0618
0619 return 0;
0620 }
0621
0622 static T_fixture RtemsIntrReqHandlerIterate_Fixture = {
0623 .setup = RtemsIntrReqHandlerIterate_Setup_Wrap,
0624 .stop = NULL,
0625 .teardown = RtemsIntrReqHandlerIterate_Teardown_Wrap,
0626 .scope = RtemsIntrReqHandlerIterate_Scope,
0627 .initial_context = &RtemsIntrReqHandlerIterate_Instance
0628 };
0629
0630 static inline RtemsIntrReqHandlerIterate_Entry
0631 RtemsIntrReqHandlerIterate_PopEntry( RtemsIntrReqHandlerIterate_Context *ctx )
0632 {
0633 size_t index;
0634
0635 index = ctx->Map.index;
0636 ctx->Map.index = index + 1;
0637 return RtemsIntrReqHandlerIterate_Entries[
0638 RtemsIntrReqHandlerIterate_Map[ index ]
0639 ];
0640 }
0641
0642 static void RtemsIntrReqHandlerIterate_TestVariant(
0643 RtemsIntrReqHandlerIterate_Context *ctx
0644 )
0645 {
0646 RtemsIntrReqHandlerIterate_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0647 RtemsIntrReqHandlerIterate_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0648 RtemsIntrReqHandlerIterate_Pre_Init_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0649 RtemsIntrReqHandlerIterate_Pre_ISR_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0650 RtemsIntrReqHandlerIterate_Action( ctx );
0651 RtemsIntrReqHandlerIterate_Post_Status_Check(
0652 ctx,
0653 ctx->Map.entry.Post_Status
0654 );
0655 RtemsIntrReqHandlerIterate_Post_Visit_Check(
0656 ctx,
0657 ctx->Map.entry.Post_Visit
0658 );
0659 }
0660
0661
0662
0663
0664 T_TEST_CASE_FIXTURE(
0665 RtemsIntrReqHandlerIterate,
0666 &RtemsIntrReqHandlerIterate_Fixture
0667 )
0668 {
0669 RtemsIntrReqHandlerIterate_Context *ctx;
0670
0671 ctx = T_fixture_context();
0672 ctx->Map.in_action_loop = true;
0673 ctx->Map.index = 0;
0674
0675 for (
0676 ctx->Map.pcs[ 0 ] = RtemsIntrReqHandlerIterate_Pre_Vector_Valid;
0677 ctx->Map.pcs[ 0 ] < RtemsIntrReqHandlerIterate_Pre_Vector_NA;
0678 ++ctx->Map.pcs[ 0 ]
0679 ) {
0680 for (
0681 ctx->Map.pcs[ 1 ] = RtemsIntrReqHandlerIterate_Pre_Routine_Valid;
0682 ctx->Map.pcs[ 1 ] < RtemsIntrReqHandlerIterate_Pre_Routine_NA;
0683 ++ctx->Map.pcs[ 1 ]
0684 ) {
0685 for (
0686 ctx->Map.pcs[ 2 ] = RtemsIntrReqHandlerIterate_Pre_Init_Yes;
0687 ctx->Map.pcs[ 2 ] < RtemsIntrReqHandlerIterate_Pre_Init_NA;
0688 ++ctx->Map.pcs[ 2 ]
0689 ) {
0690 for (
0691 ctx->Map.pcs[ 3 ] = RtemsIntrReqHandlerIterate_Pre_ISR_Yes;
0692 ctx->Map.pcs[ 3 ] < RtemsIntrReqHandlerIterate_Pre_ISR_NA;
0693 ++ctx->Map.pcs[ 3 ]
0694 ) {
0695 ctx->Map.entry = RtemsIntrReqHandlerIterate_PopEntry( ctx );
0696 RtemsIntrReqHandlerIterate_TestVariant( ctx );
0697 }
0698 }
0699 }
0700 }
0701 }
0702
0703