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