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 RtemsIntrReqGetAffinity_Pre_Vector_Valid,
0073 RtemsIntrReqGetAffinity_Pre_Vector_Invalid,
0074 RtemsIntrReqGetAffinity_Pre_Vector_NA
0075 } RtemsIntrReqGetAffinity_Pre_Vector;
0076
0077 typedef enum {
0078 RtemsIntrReqGetAffinity_Pre_CPUSetSize_Valid,
0079 RtemsIntrReqGetAffinity_Pre_CPUSetSize_TooSmall,
0080 RtemsIntrReqGetAffinity_Pre_CPUSetSize_Askew,
0081 RtemsIntrReqGetAffinity_Pre_CPUSetSize_NA
0082 } RtemsIntrReqGetAffinity_Pre_CPUSetSize;
0083
0084 typedef enum {
0085 RtemsIntrReqGetAffinity_Pre_CPUSet_Valid,
0086 RtemsIntrReqGetAffinity_Pre_CPUSet_Null,
0087 RtemsIntrReqGetAffinity_Pre_CPUSet_NA
0088 } RtemsIntrReqGetAffinity_Pre_CPUSet;
0089
0090 typedef enum {
0091 RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Yes,
0092 RtemsIntrReqGetAffinity_Pre_CanGetAffinity_No,
0093 RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA
0094 } RtemsIntrReqGetAffinity_Pre_CanGetAffinity;
0095
0096 typedef enum {
0097 RtemsIntrReqGetAffinity_Post_Status_Ok,
0098 RtemsIntrReqGetAffinity_Post_Status_InvAddr,
0099 RtemsIntrReqGetAffinity_Post_Status_InvId,
0100 RtemsIntrReqGetAffinity_Post_Status_InvSize,
0101 RtemsIntrReqGetAffinity_Post_Status_Unsat,
0102 RtemsIntrReqGetAffinity_Post_Status_NA
0103 } RtemsIntrReqGetAffinity_Post_Status;
0104
0105 typedef enum {
0106 RtemsIntrReqGetAffinity_Post_CPUSetObj_Set,
0107 RtemsIntrReqGetAffinity_Post_CPUSetObj_Partial,
0108 RtemsIntrReqGetAffinity_Post_CPUSetObj_Zero,
0109 RtemsIntrReqGetAffinity_Post_CPUSetObj_Nop,
0110 RtemsIntrReqGetAffinity_Post_CPUSetObj_NA
0111 } RtemsIntrReqGetAffinity_Post_CPUSetObj;
0112
0113 typedef struct {
0114 uint16_t Skip : 1;
0115 uint16_t Pre_Vector_NA : 1;
0116 uint16_t Pre_CPUSetSize_NA : 1;
0117 uint16_t Pre_CPUSet_NA : 1;
0118 uint16_t Pre_CanGetAffinity_NA : 1;
0119 uint16_t Post_Status : 3;
0120 uint16_t Post_CPUSetObj : 3;
0121 } RtemsIntrReqGetAffinity_Entry;
0122
0123
0124
0125
0126 typedef struct {
0127
0128
0129
0130 rtems_vector_number vector;
0131
0132
0133
0134
0135 rtems_vector_number some_vector;
0136
0137
0138
0139
0140
0141 cpu_set_t cpuset_obj[ 2 ];
0142
0143
0144
0145
0146
0147 rtems_status_code status;
0148
0149
0150
0151
0152
0153 bool valid_vector;
0154
0155
0156
0157
0158 size_t cpusetsize;
0159
0160
0161
0162
0163 cpu_set_t *cpuset;
0164
0165 struct {
0166
0167
0168
0169
0170 size_t pci[ 4 ];
0171
0172
0173
0174
0175 size_t pcs[ 4 ];
0176
0177
0178
0179
0180 bool in_action_loop;
0181
0182
0183
0184
0185 size_t index;
0186
0187
0188
0189
0190 RtemsIntrReqGetAffinity_Entry entry;
0191
0192
0193
0194
0195
0196 bool skip;
0197 } Map;
0198 } RtemsIntrReqGetAffinity_Context;
0199
0200 static RtemsIntrReqGetAffinity_Context
0201 RtemsIntrReqGetAffinity_Instance;
0202
0203 static const char * const RtemsIntrReqGetAffinity_PreDesc_Vector[] = {
0204 "Valid",
0205 "Invalid",
0206 "NA"
0207 };
0208
0209 static const char * const RtemsIntrReqGetAffinity_PreDesc_CPUSetSize[] = {
0210 "Valid",
0211 "TooSmall",
0212 "Askew",
0213 "NA"
0214 };
0215
0216 static const char * const RtemsIntrReqGetAffinity_PreDesc_CPUSet[] = {
0217 "Valid",
0218 "Null",
0219 "NA"
0220 };
0221
0222 static const char * const RtemsIntrReqGetAffinity_PreDesc_CanGetAffinity[] = {
0223 "Yes",
0224 "No",
0225 "NA"
0226 };
0227
0228 static const char * const * const RtemsIntrReqGetAffinity_PreDesc[] = {
0229 RtemsIntrReqGetAffinity_PreDesc_Vector,
0230 RtemsIntrReqGetAffinity_PreDesc_CPUSetSize,
0231 RtemsIntrReqGetAffinity_PreDesc_CPUSet,
0232 RtemsIntrReqGetAffinity_PreDesc_CanGetAffinity,
0233 NULL
0234 };
0235
0236 typedef RtemsIntrReqGetAffinity_Context Context;
0237
0238 static void CheckGetAffinity(
0239 Context *ctx,
0240 const rtems_interrupt_attributes *attr
0241 )
0242 {
0243 rtems_status_code sc;
0244 cpu_set_t set[ 2 ];
0245
0246 #pragma GCC diagnostic push
0247 #pragma GCC diagnostic ignored "-Warray-bounds"
0248
0249 if ( attr->can_get_affinity ) {
0250 CPU_ZERO_S( sizeof( ctx->cpuset_obj ), ctx->cpuset_obj );
0251 } else {
0252 CPU_FILL_S( sizeof( ctx->cpuset_obj ), ctx->cpuset_obj );
0253 }
0254
0255 sc = rtems_interrupt_get_affinity(
0256 ctx->vector,
0257 ctx->cpusetsize,
0258 ctx->cpuset
0259 );
0260
0261 CPU_ZERO_S( sizeof( set ), set );
0262
0263 if ( attr->can_get_affinity ) {
0264 T_rsc_success( sc );
0265 T_false( CPU_EQUAL_S( sizeof( set ), ctx->cpuset_obj, set ) );
0266 } else {
0267 T_rsc( sc, RTEMS_UNSATISFIED );
0268 T_true( CPU_EQUAL_S( sizeof( set ), ctx->cpuset_obj, set ) );
0269 }
0270
0271 #pragma GCC diagnostic pop
0272 }
0273
0274 static void RtemsIntrReqGetAffinity_Pre_Vector_Prepare(
0275 RtemsIntrReqGetAffinity_Context *ctx,
0276 RtemsIntrReqGetAffinity_Pre_Vector state
0277 )
0278 {
0279 switch ( state ) {
0280 case RtemsIntrReqGetAffinity_Pre_Vector_Valid: {
0281
0282
0283
0284 ctx->valid_vector = true;
0285 break;
0286 }
0287
0288 case RtemsIntrReqGetAffinity_Pre_Vector_Invalid: {
0289
0290
0291
0292
0293 ctx->valid_vector = false;
0294 break;
0295 }
0296
0297 case RtemsIntrReqGetAffinity_Pre_Vector_NA:
0298 break;
0299 }
0300 }
0301
0302 static void RtemsIntrReqGetAffinity_Pre_CPUSetSize_Prepare(
0303 RtemsIntrReqGetAffinity_Context *ctx,
0304 RtemsIntrReqGetAffinity_Pre_CPUSetSize state
0305 )
0306 {
0307 switch ( state ) {
0308 case RtemsIntrReqGetAffinity_Pre_CPUSetSize_Valid: {
0309
0310
0311
0312
0313
0314
0315 ctx->cpusetsize = sizeof( ctx->cpuset_obj );
0316 break;
0317 }
0318
0319 case RtemsIntrReqGetAffinity_Pre_CPUSetSize_TooSmall: {
0320
0321
0322
0323
0324
0325
0326 ctx->cpusetsize = 0;
0327 break;
0328 }
0329
0330 case RtemsIntrReqGetAffinity_Pre_CPUSetSize_Askew: {
0331
0332
0333
0334
0335 ctx->cpusetsize = SIZE_MAX;
0336 break;
0337 }
0338
0339 case RtemsIntrReqGetAffinity_Pre_CPUSetSize_NA:
0340 break;
0341 }
0342 }
0343
0344 static void RtemsIntrReqGetAffinity_Pre_CPUSet_Prepare(
0345 RtemsIntrReqGetAffinity_Context *ctx,
0346 RtemsIntrReqGetAffinity_Pre_CPUSet state
0347 )
0348 {
0349 switch ( state ) {
0350 case RtemsIntrReqGetAffinity_Pre_CPUSet_Valid: {
0351
0352
0353
0354
0355 ctx->cpuset = ctx->cpuset_obj;
0356 break;
0357 }
0358
0359 case RtemsIntrReqGetAffinity_Pre_CPUSet_Null: {
0360
0361
0362
0363 ctx->cpuset = NULL;
0364 break;
0365 }
0366
0367 case RtemsIntrReqGetAffinity_Pre_CPUSet_NA:
0368 break;
0369 }
0370 }
0371
0372 static void RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Prepare(
0373 RtemsIntrReqGetAffinity_Context *ctx,
0374 RtemsIntrReqGetAffinity_Pre_CanGetAffinity state
0375 )
0376 {
0377 switch ( state ) {
0378 case RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Yes: {
0379
0380
0381
0382
0383
0384 break;
0385 }
0386
0387 case RtemsIntrReqGetAffinity_Pre_CanGetAffinity_No: {
0388
0389
0390
0391
0392
0393 break;
0394 }
0395
0396 case RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA:
0397 break;
0398 }
0399 }
0400
0401 static void RtemsIntrReqGetAffinity_Post_Status_Check(
0402 RtemsIntrReqGetAffinity_Context *ctx,
0403 RtemsIntrReqGetAffinity_Post_Status state
0404 )
0405 {
0406 switch ( state ) {
0407 case RtemsIntrReqGetAffinity_Post_Status_Ok: {
0408
0409
0410
0411
0412
0413 break;
0414 }
0415
0416 case RtemsIntrReqGetAffinity_Post_Status_InvAddr: {
0417
0418
0419
0420
0421 T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0422 break;
0423 }
0424
0425 case RtemsIntrReqGetAffinity_Post_Status_InvId: {
0426
0427
0428
0429
0430 T_rsc( ctx->status, RTEMS_INVALID_ID );
0431 break;
0432 }
0433
0434 case RtemsIntrReqGetAffinity_Post_Status_InvSize: {
0435
0436
0437
0438
0439 T_rsc( ctx->status, RTEMS_INVALID_SIZE );
0440 break;
0441 }
0442
0443 case RtemsIntrReqGetAffinity_Post_Status_Unsat: {
0444
0445
0446
0447
0448
0449 break;
0450 }
0451
0452 case RtemsIntrReqGetAffinity_Post_Status_NA:
0453 break;
0454 }
0455 }
0456
0457 static void RtemsIntrReqGetAffinity_Post_CPUSetObj_Check(
0458 RtemsIntrReqGetAffinity_Context *ctx,
0459 RtemsIntrReqGetAffinity_Post_CPUSetObj state
0460 )
0461 {
0462 switch ( state ) {
0463 case RtemsIntrReqGetAffinity_Post_CPUSetObj_Set: {
0464
0465
0466
0467
0468
0469
0470
0471 break;
0472 }
0473
0474 case RtemsIntrReqGetAffinity_Post_CPUSetObj_Partial: {
0475
0476
0477
0478
0479
0480
0481
0482
0483 break;
0484 }
0485
0486 case RtemsIntrReqGetAffinity_Post_CPUSetObj_Zero: {
0487
0488
0489
0490
0491
0492
0493
0494
0495 break;
0496 }
0497
0498 case RtemsIntrReqGetAffinity_Post_CPUSetObj_Nop: {
0499
0500
0501
0502
0503
0504
0505
0506
0507
0508 break;
0509 }
0510
0511 case RtemsIntrReqGetAffinity_Post_CPUSetObj_NA:
0512 break;
0513 }
0514 }
0515
0516 static void RtemsIntrReqGetAffinity_Setup(
0517 RtemsIntrReqGetAffinity_Context *ctx
0518 )
0519 {
0520 rtems_interrupt_attributes required;
0521
0522 memset( &required, 0, sizeof( required ) );
0523 required.can_get_affinity = true;
0524 ctx->some_vector = GetValidInterruptVectorNumber( &required );
0525 }
0526
0527 static void RtemsIntrReqGetAffinity_Setup_Wrap( void *arg )
0528 {
0529 RtemsIntrReqGetAffinity_Context *ctx;
0530
0531 ctx = arg;
0532 ctx->Map.in_action_loop = false;
0533 RtemsIntrReqGetAffinity_Setup( ctx );
0534 }
0535
0536 static void RtemsIntrReqGetAffinity_Action(
0537 RtemsIntrReqGetAffinity_Context *ctx
0538 )
0539 {
0540 if (
0541 ctx->valid_vector && ctx->cpusetsize == sizeof( ctx->cpuset_obj ) &&
0542 ctx->cpuset == ctx->cpuset_obj
0543 ) {
0544 for (
0545 ctx->vector = 0;
0546 ctx->vector < BSP_INTERRUPT_VECTOR_COUNT;
0547 ++ctx->vector
0548 ) {
0549 rtems_status_code sc;
0550 rtems_interrupt_attributes attr;
0551
0552 memset( &attr, 0, sizeof( attr ) );
0553 sc = rtems_interrupt_get_attributes( ctx->vector, &attr );
0554
0555 if ( sc == RTEMS_INVALID_ID ) {
0556 continue;
0557 }
0558
0559 T_rsc_success( sc );
0560
0561 CheckGetAffinity( ctx, &attr );
0562 }
0563 } else {
0564 cpu_set_t set[ 2 ];
0565
0566 if ( ctx->valid_vector ) {
0567 ctx->vector = ctx->some_vector;
0568 } else {
0569 ctx->vector = BSP_INTERRUPT_VECTOR_COUNT;
0570 }
0571
0572 #pragma GCC diagnostic push
0573 #pragma GCC diagnostic ignored "-Warray-bounds"
0574
0575 CPU_FILL_S( sizeof( ctx->cpuset_obj ), ctx->cpuset_obj );
0576
0577 ctx->status = rtems_interrupt_get_affinity(
0578 ctx->vector,
0579 ctx->cpusetsize,
0580 ctx->cpuset
0581 );
0582
0583 if (
0584 ctx->cpuset == NULL ||
0585 ctx->cpusetsize != sizeof( ctx->cpuset_obj )
0586 ) {
0587 CPU_FILL_S( sizeof( set ), set );
0588 } else {
0589 CPU_ZERO_S( sizeof( set ), set );
0590 }
0591
0592 T_true( CPU_EQUAL_S( sizeof( set ), ctx->cpuset_obj, set ) );
0593
0594 #pragma GCC diagnostic pop
0595 }
0596 }
0597
0598 static const RtemsIntrReqGetAffinity_Entry
0599 RtemsIntrReqGetAffinity_Entries[] = {
0600 { 0, 0, 0, 0, 0, RtemsIntrReqGetAffinity_Post_Status_InvAddr,
0601 RtemsIntrReqGetAffinity_Post_CPUSetObj_Nop },
0602 { 0, 0, 0, 0, 1, RtemsIntrReqGetAffinity_Post_Status_InvId,
0603 RtemsIntrReqGetAffinity_Post_CPUSetObj_Zero },
0604 { 0, 0, 0, 0, 1, RtemsIntrReqGetAffinity_Post_Status_InvAddr,
0605 RtemsIntrReqGetAffinity_Post_CPUSetObj_Nop },
0606 { 0, 0, 0, 0, 0, RtemsIntrReqGetAffinity_Post_Status_Unsat,
0607 RtemsIntrReqGetAffinity_Post_CPUSetObj_Zero },
0608 { 0, 0, 0, 0, 0, RtemsIntrReqGetAffinity_Post_Status_InvSize,
0609 RtemsIntrReqGetAffinity_Post_CPUSetObj_Nop },
0610 { 0, 0, 0, 0, 0, RtemsIntrReqGetAffinity_Post_Status_Ok,
0611 RtemsIntrReqGetAffinity_Post_CPUSetObj_Set },
0612 { 0, 0, 0, 0, 0, RtemsIntrReqGetAffinity_Post_Status_InvSize,
0613 RtemsIntrReqGetAffinity_Post_CPUSetObj_Partial }
0614 };
0615
0616 static const uint8_t
0617 RtemsIntrReqGetAffinity_Map[] = {
0618 5, 3, 0, 0, 6, 3, 0, 0, 4, 4, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2
0619 };
0620
0621 static size_t RtemsIntrReqGetAffinity_Scope( void *arg, char *buf, size_t n )
0622 {
0623 RtemsIntrReqGetAffinity_Context *ctx;
0624
0625 ctx = arg;
0626
0627 if ( ctx->Map.in_action_loop ) {
0628 return T_get_scope(
0629 RtemsIntrReqGetAffinity_PreDesc,
0630 buf,
0631 n,
0632 ctx->Map.pcs
0633 );
0634 }
0635
0636 return 0;
0637 }
0638
0639 static T_fixture RtemsIntrReqGetAffinity_Fixture = {
0640 .setup = RtemsIntrReqGetAffinity_Setup_Wrap,
0641 .stop = NULL,
0642 .teardown = NULL,
0643 .scope = RtemsIntrReqGetAffinity_Scope,
0644 .initial_context = &RtemsIntrReqGetAffinity_Instance
0645 };
0646
0647 static inline RtemsIntrReqGetAffinity_Entry RtemsIntrReqGetAffinity_PopEntry(
0648 RtemsIntrReqGetAffinity_Context *ctx
0649 )
0650 {
0651 size_t index;
0652
0653 index = ctx->Map.index;
0654 ctx->Map.index = index + 1;
0655 return RtemsIntrReqGetAffinity_Entries[
0656 RtemsIntrReqGetAffinity_Map[ index ]
0657 ];
0658 }
0659
0660 static void RtemsIntrReqGetAffinity_SetPreConditionStates(
0661 RtemsIntrReqGetAffinity_Context *ctx
0662 )
0663 {
0664 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0665 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0666 ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0667
0668 if ( ctx->Map.entry.Pre_CanGetAffinity_NA ) {
0669 ctx->Map.pcs[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA;
0670 } else {
0671 ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
0672 }
0673 }
0674
0675 static void RtemsIntrReqGetAffinity_TestVariant(
0676 RtemsIntrReqGetAffinity_Context *ctx
0677 )
0678 {
0679 RtemsIntrReqGetAffinity_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0680 RtemsIntrReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0681 RtemsIntrReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0682 RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0683 RtemsIntrReqGetAffinity_Action( ctx );
0684 RtemsIntrReqGetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0685 RtemsIntrReqGetAffinity_Post_CPUSetObj_Check(
0686 ctx,
0687 ctx->Map.entry.Post_CPUSetObj
0688 );
0689 }
0690
0691
0692
0693
0694 T_TEST_CASE_FIXTURE(
0695 RtemsIntrReqGetAffinity,
0696 &RtemsIntrReqGetAffinity_Fixture
0697 )
0698 {
0699 RtemsIntrReqGetAffinity_Context *ctx;
0700
0701 ctx = T_fixture_context();
0702 ctx->Map.in_action_loop = true;
0703 ctx->Map.index = 0;
0704
0705 for (
0706 ctx->Map.pci[ 0 ] = RtemsIntrReqGetAffinity_Pre_Vector_Valid;
0707 ctx->Map.pci[ 0 ] < RtemsIntrReqGetAffinity_Pre_Vector_NA;
0708 ++ctx->Map.pci[ 0 ]
0709 ) {
0710 for (
0711 ctx->Map.pci[ 1 ] = RtemsIntrReqGetAffinity_Pre_CPUSetSize_Valid;
0712 ctx->Map.pci[ 1 ] < RtemsIntrReqGetAffinity_Pre_CPUSetSize_NA;
0713 ++ctx->Map.pci[ 1 ]
0714 ) {
0715 for (
0716 ctx->Map.pci[ 2 ] = RtemsIntrReqGetAffinity_Pre_CPUSet_Valid;
0717 ctx->Map.pci[ 2 ] < RtemsIntrReqGetAffinity_Pre_CPUSet_NA;
0718 ++ctx->Map.pci[ 2 ]
0719 ) {
0720 for (
0721 ctx->Map.pci[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Yes;
0722 ctx->Map.pci[ 3 ] < RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA;
0723 ++ctx->Map.pci[ 3 ]
0724 ) {
0725 ctx->Map.entry = RtemsIntrReqGetAffinity_PopEntry( ctx );
0726 RtemsIntrReqGetAffinity_SetPreConditionStates( ctx );
0727 RtemsIntrReqGetAffinity_TestVariant( ctx );
0728 }
0729 }
0730 }
0731 }
0732 }
0733
0734