Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:51

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsIntrReqSetAffinity
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /*
0035  * This file is part of the RTEMS quality process and was automatically
0036  * generated.  If you find something that needs to be fixed or
0037  * worded better please post a report or patch to an RTEMS mailing list
0038  * or raise a bug report:
0039  *
0040  * https://www.rtems.org/bugs.html
0041  *
0042  * For information on updating and regenerating please refer to the How-To
0043  * section in the Software Requirements Engineering chapter of the
0044  * RTEMS Software Engineering manual.  The manual is provided as a part of
0045  * a release.  For development sources please refer to the online
0046  * documentation at:
0047  *
0048  * https://docs.rtems.org
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  * @defgroup RtemsIntrReqSetAffinity spec:/rtems/intr/req/set-affinity
0064  *
0065  * @ingroup TestsuitesValidationIntr
0066  *
0067  * @{
0068  */
0069 
0070 typedef enum {
0071   RtemsIntrReqSetAffinity_Pre_Vector_Valid,
0072   RtemsIntrReqSetAffinity_Pre_Vector_Invalid,
0073   RtemsIntrReqSetAffinity_Pre_Vector_NA
0074 } RtemsIntrReqSetAffinity_Pre_Vector;
0075 
0076 typedef enum {
0077   RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew,
0078   RtemsIntrReqSetAffinity_Pre_CPUSetSize_Normal,
0079   RtemsIntrReqSetAffinity_Pre_CPUSetSize_Huge,
0080   RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA
0081 } RtemsIntrReqSetAffinity_Pre_CPUSetSize;
0082 
0083 typedef enum {
0084   RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid,
0085   RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Empty,
0086   RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA
0087 } RtemsIntrReqSetAffinity_Pre_CPUSetOnline;
0088 
0089 typedef enum {
0090   RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero,
0091   RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Zero,
0092   RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA
0093 } RtemsIntrReqSetAffinity_Pre_CPUSetHuge;
0094 
0095 typedef enum {
0096   RtemsIntrReqSetAffinity_Pre_CPUSet_Valid,
0097   RtemsIntrReqSetAffinity_Pre_CPUSet_Null,
0098   RtemsIntrReqSetAffinity_Pre_CPUSet_NA
0099 } RtemsIntrReqSetAffinity_Pre_CPUSet;
0100 
0101 typedef enum {
0102   RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Yes,
0103   RtemsIntrReqSetAffinity_Pre_CanSetAffinity_No,
0104   RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA
0105 } RtemsIntrReqSetAffinity_Pre_CanSetAffinity;
0106 
0107 typedef enum {
0108   RtemsIntrReqSetAffinity_Post_Status_Ok,
0109   RtemsIntrReqSetAffinity_Post_Status_InvAddr,
0110   RtemsIntrReqSetAffinity_Post_Status_InvId,
0111   RtemsIntrReqSetAffinity_Post_Status_InvNum,
0112   RtemsIntrReqSetAffinity_Post_Status_Unsat,
0113   RtemsIntrReqSetAffinity_Post_Status_NA
0114 } RtemsIntrReqSetAffinity_Post_Status;
0115 
0116 typedef enum {
0117   RtemsIntrReqSetAffinity_Post_SetAffinity_Set,
0118   RtemsIntrReqSetAffinity_Post_SetAffinity_Nop,
0119   RtemsIntrReqSetAffinity_Post_SetAffinity_NA
0120 } RtemsIntrReqSetAffinity_Post_SetAffinity;
0121 
0122 typedef struct {
0123   uint16_t Skip : 1;
0124   uint16_t Pre_Vector_NA : 1;
0125   uint16_t Pre_CPUSetSize_NA : 1;
0126   uint16_t Pre_CPUSetOnline_NA : 1;
0127   uint16_t Pre_CPUSetHuge_NA : 1;
0128   uint16_t Pre_CPUSet_NA : 1;
0129   uint16_t Pre_CanSetAffinity_NA : 1;
0130   uint16_t Post_Status : 3;
0131   uint16_t Post_SetAffinity : 2;
0132 } RtemsIntrReqSetAffinity_Entry;
0133 
0134 /**
0135  * @brief Test context for spec:/rtems/intr/req/set-affinity test case.
0136  */
0137 typedef struct {
0138   /**
0139    * @brief This member contains the current vector number.
0140    */
0141   rtems_vector_number vector;
0142 
0143   /**
0144    * @brief This member contains some valid vector number.
0145    */
0146   rtems_vector_number some_vector;
0147 
0148   /**
0149    * @brief This member provides the object referenced by the ``affinity``
0150    *   parameter.
0151    */
0152   cpu_set_t cpuset_obj[ 2 ];
0153 
0154   /**
0155    * @brief This member contains the return value of the
0156    *   rtems_interrupt_set_affinity() call.
0157    */
0158   rtems_status_code status;
0159 
0160   /**
0161    * @brief If this member is true, then the ``vector`` parameter shall be
0162    *   valid.
0163    */
0164   bool valid_vector;
0165 
0166   /**
0167    * @brief This member specifies if the ``affinity_size`` parameter value.
0168    */
0169   size_t cpusetsize;
0170 
0171   /**
0172    * @brief This member specifies if the ``affinity`` parameter value.
0173    */
0174   cpu_set_t *cpuset;
0175 
0176   struct {
0177     /**
0178      * @brief This member defines the pre-condition indices for the next
0179      *   action.
0180      */
0181     size_t pci[ 6 ];
0182 
0183     /**
0184      * @brief This member defines the pre-condition states for the next action.
0185      */
0186     size_t pcs[ 6 ];
0187 
0188     /**
0189      * @brief If this member is true, then the test action loop is executed.
0190      */
0191     bool in_action_loop;
0192 
0193     /**
0194      * @brief This member contains the next transition map index.
0195      */
0196     size_t index;
0197 
0198     /**
0199      * @brief This member contains the current transition map entry.
0200      */
0201     RtemsIntrReqSetAffinity_Entry entry;
0202 
0203     /**
0204      * @brief If this member is true, then the current transition variant
0205      *   should be skipped.
0206      */
0207     bool skip;
0208   } Map;
0209 } RtemsIntrReqSetAffinity_Context;
0210 
0211 static RtemsIntrReqSetAffinity_Context
0212   RtemsIntrReqSetAffinity_Instance;
0213 
0214 static const char * const RtemsIntrReqSetAffinity_PreDesc_Vector[] = {
0215   "Valid",
0216   "Invalid",
0217   "NA"
0218 };
0219 
0220 static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetSize[] = {
0221   "Askew",
0222   "Normal",
0223   "Huge",
0224   "NA"
0225 };
0226 
0227 static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetOnline[] = {
0228   "Valid",
0229   "Empty",
0230   "NA"
0231 };
0232 
0233 static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetHuge[] = {
0234   "NotZero",
0235   "Zero",
0236   "NA"
0237 };
0238 
0239 static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSet[] = {
0240   "Valid",
0241   "Null",
0242   "NA"
0243 };
0244 
0245 static const char * const RtemsIntrReqSetAffinity_PreDesc_CanSetAffinity[] = {
0246   "Yes",
0247   "No",
0248   "NA"
0249 };
0250 
0251 static const char * const * const RtemsIntrReqSetAffinity_PreDesc[] = {
0252   RtemsIntrReqSetAffinity_PreDesc_Vector,
0253   RtemsIntrReqSetAffinity_PreDesc_CPUSetSize,
0254   RtemsIntrReqSetAffinity_PreDesc_CPUSetOnline,
0255   RtemsIntrReqSetAffinity_PreDesc_CPUSetHuge,
0256   RtemsIntrReqSetAffinity_PreDesc_CPUSet,
0257   RtemsIntrReqSetAffinity_PreDesc_CanSetAffinity,
0258   NULL
0259 };
0260 
0261 typedef RtemsIntrReqSetAffinity_Context Context;
0262 
0263 static void CheckSetAffinity(
0264   Context                          *ctx,
0265   const rtems_interrupt_attributes *attr
0266 )
0267 {
0268   rtems_status_code sc;
0269   cpu_set_t         set;
0270   cpu_set_t         set2;
0271 
0272   CPU_ZERO( &set );
0273 
0274   if ( attr->can_get_affinity ) {
0275     sc = rtems_interrupt_get_affinity( ctx->vector, sizeof( set ), &set );
0276     T_rsc_success( sc );
0277   } else {
0278     CPU_SET( 0, &set );
0279   }
0280 
0281   CPU_COPY( &set, &ctx->cpuset_obj[ 0 ] );
0282 
0283   sc = rtems_interrupt_set_affinity(
0284     ctx->vector,
0285     ctx->cpusetsize,
0286     ctx->cpuset
0287   );
0288 
0289   if ( attr->can_set_affinity ) {
0290     T_rsc_success( sc );
0291   } else {
0292     T_rsc( sc, RTEMS_UNSATISFIED );
0293   }
0294 
0295   if ( attr->can_get_affinity ) {
0296     CPU_FILL( &set2 );
0297     sc = rtems_interrupt_get_affinity( ctx->vector, sizeof( set2 ), &set2 );
0298     T_rsc_success( sc );
0299     T_eq_int( CPU_CMP( &set, &set2 ), 0 );
0300   }
0301 }
0302 
0303 static void RtemsIntrReqSetAffinity_Pre_Vector_Prepare(
0304   RtemsIntrReqSetAffinity_Context   *ctx,
0305   RtemsIntrReqSetAffinity_Pre_Vector state
0306 )
0307 {
0308   switch ( state ) {
0309     case RtemsIntrReqSetAffinity_Pre_Vector_Valid: {
0310       /*
0311        * While the ``vector`` parameter is associated with an interrupt vector.
0312        */
0313       ctx->valid_vector = true;
0314       break;
0315     }
0316 
0317     case RtemsIntrReqSetAffinity_Pre_Vector_Invalid: {
0318       /*
0319        * While the ``vector`` parameter is not associated with an interrupt
0320        * vector.
0321        */
0322       ctx->valid_vector = false;
0323       break;
0324     }
0325 
0326     case RtemsIntrReqSetAffinity_Pre_Vector_NA:
0327       break;
0328   }
0329 }
0330 
0331 static void RtemsIntrReqSetAffinity_Pre_CPUSetSize_Prepare(
0332   RtemsIntrReqSetAffinity_Context       *ctx,
0333   RtemsIntrReqSetAffinity_Pre_CPUSetSize state
0334 )
0335 {
0336   switch ( state ) {
0337     case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew: {
0338       /*
0339        * While the ``affinity_size`` parameter is not an integral multiple of
0340        * the size of long.
0341        */
0342       ctx->cpusetsize = SIZE_MAX;
0343       break;
0344     }
0345 
0346     case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Normal: {
0347       /*
0348        * While the ``affinity_size`` parameter is an integral multiple of the
0349        * size of long, while the ``affinity_size`` parameter is less than or
0350        * equal to the maximum processor set size storable in the system.
0351        */
0352       ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
0353       break;
0354     }
0355 
0356     case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Huge: {
0357       /*
0358        * While the ``affinity_size`` parameter is an integral multiple of the
0359        * size of long, while the ``affinity_size`` parameter is greater than
0360        * the maximum processor set size storable in the system.
0361        */
0362       ctx->cpusetsize = sizeof( ctx->cpuset_obj );
0363       break;
0364     }
0365 
0366     case RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA:
0367       break;
0368   }
0369 }
0370 
0371 static void RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Prepare(
0372   RtemsIntrReqSetAffinity_Context         *ctx,
0373   RtemsIntrReqSetAffinity_Pre_CPUSetOnline state
0374 )
0375 {
0376   switch ( state ) {
0377     case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid: {
0378       /*
0379        * While the intersection of the processor set specified by the
0380        * ``affinity_size`` and ``affinity`` parameters and the set of online
0381        * processors is not empty, while the intersection of the processor set
0382        * specified by the ``affinity_size`` and ``affinity`` parameters and the
0383        * set of online processors is a processor affinity set supported by the
0384        * interrupt vector.
0385        */
0386       /* Already prepared */
0387       break;
0388     }
0389 
0390     case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Empty: {
0391       /*
0392        * While the intersection of the processor set specified by the
0393        * ``affinity_size`` and ``affinity`` parameters and the set of online
0394        * processors is empty.
0395        */
0396       CPU_ZERO( &ctx->cpuset_obj[ 0 ] );
0397       break;
0398     }
0399 
0400     case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA:
0401       break;
0402   }
0403 }
0404 
0405 static void RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Prepare(
0406   RtemsIntrReqSetAffinity_Context       *ctx,
0407   RtemsIntrReqSetAffinity_Pre_CPUSetHuge state
0408 )
0409 {
0410   switch ( state ) {
0411     case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero: {
0412       /*
0413        * While the processor set specified by the ``affinity_size`` and
0414        * ``affinity`` parameters contains at least one processor which is not
0415        * storable in a processor set supported by the system.
0416        */
0417       /* Already prepared */
0418       break;
0419     }
0420 
0421     case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Zero: {
0422       /*
0423        * While the processor set specified by the ``affinity_size`` and
0424        * ``affinity`` parameters contains no processor which is not storable in
0425        * a processor set supported by the system.
0426        */
0427       CPU_ZERO( &ctx->cpuset_obj[ 1 ] );
0428       break;
0429     }
0430 
0431     case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA:
0432       break;
0433   }
0434 }
0435 
0436 static void RtemsIntrReqSetAffinity_Pre_CPUSet_Prepare(
0437   RtemsIntrReqSetAffinity_Context   *ctx,
0438   RtemsIntrReqSetAffinity_Pre_CPUSet state
0439 )
0440 {
0441   switch ( state ) {
0442     case RtemsIntrReqSetAffinity_Pre_CPUSet_Valid: {
0443       /*
0444        * While the ``affinity`` parameter references an object of type
0445        * cpu_set_t.
0446        */
0447       ctx->cpuset = &ctx->cpuset_obj[ 0 ];
0448       break;
0449     }
0450 
0451     case RtemsIntrReqSetAffinity_Pre_CPUSet_Null: {
0452       /*
0453        * While the ``affinity`` parameter is equal to NULL.
0454        */
0455       ctx->cpuset = NULL;
0456       break;
0457     }
0458 
0459     case RtemsIntrReqSetAffinity_Pre_CPUSet_NA:
0460       break;
0461   }
0462 }
0463 
0464 static void RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Prepare(
0465   RtemsIntrReqSetAffinity_Context           *ctx,
0466   RtemsIntrReqSetAffinity_Pre_CanSetAffinity state
0467 )
0468 {
0469   switch ( state ) {
0470     case RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Yes: {
0471       /*
0472        * While setting the affinity for the interrupt vector specified by
0473        * ``vector`` parameter is supported.
0474        */
0475       /* Validation done by CheckSetAffinity() for each interrupt vector */
0476       break;
0477     }
0478 
0479     case RtemsIntrReqSetAffinity_Pre_CanSetAffinity_No: {
0480       /*
0481        * While setting the affinity for the interrupt vector specified by
0482        * ``vector`` parameter is not supported.
0483        */
0484       /* Validation done by CheckSetAffinity() for each interrupt vector */
0485       break;
0486     }
0487 
0488     case RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA:
0489       break;
0490   }
0491 }
0492 
0493 static void RtemsIntrReqSetAffinity_Post_Status_Check(
0494   RtemsIntrReqSetAffinity_Context    *ctx,
0495   RtemsIntrReqSetAffinity_Post_Status state
0496 )
0497 {
0498   switch ( state ) {
0499     case RtemsIntrReqSetAffinity_Post_Status_Ok: {
0500       /*
0501        * The return status of rtems_interrupt_set_affinity() shall be
0502        * RTEMS_SUCCESSFUL.
0503        */
0504       /* Validation done by CheckSetAffinity() for each interrupt vector */
0505       break;
0506     }
0507 
0508     case RtemsIntrReqSetAffinity_Post_Status_InvAddr: {
0509       /*
0510        * The return status of rtems_interrupt_set_affinity() shall be
0511        * RTEMS_INVALID_ADDRESS.
0512        */
0513       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0514       break;
0515     }
0516 
0517     case RtemsIntrReqSetAffinity_Post_Status_InvId: {
0518       /*
0519        * The return status of rtems_interrupt_set_affinity() shall be
0520        * RTEMS_INVALID_ID.
0521        */
0522       T_rsc( ctx->status, RTEMS_INVALID_ID );
0523       break;
0524     }
0525 
0526     case RtemsIntrReqSetAffinity_Post_Status_InvNum: {
0527       /*
0528        * The return status of rtems_interrupt_set_affinity() shall be
0529        * RTEMS_INVALID_NUMBER.
0530        */
0531       T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
0532       break;
0533     }
0534 
0535     case RtemsIntrReqSetAffinity_Post_Status_Unsat: {
0536       /*
0537        * The return status of rtems_interrupt_set_affinity() shall be
0538        * RTEMS_UNSATISFIED.
0539        */
0540       /* Validation done by CheckSetAffinity() for each interrupt vector */
0541       break;
0542     }
0543 
0544     case RtemsIntrReqSetAffinity_Post_Status_NA:
0545       break;
0546   }
0547 }
0548 
0549 static void RtemsIntrReqSetAffinity_Post_SetAffinity_Check(
0550   RtemsIntrReqSetAffinity_Context         *ctx,
0551   RtemsIntrReqSetAffinity_Post_SetAffinity state
0552 )
0553 {
0554   switch ( state ) {
0555     case RtemsIntrReqSetAffinity_Post_SetAffinity_Set: {
0556       /*
0557        * The affinity set of the interrupt specified by ``vector`` shall be set
0558        * to the processor set specified by ``affinity_size`` and ``affinity``
0559        * at some point during the rtems_interrupt_set_affinity() call.
0560        */
0561       /* Validation done by CheckSetAffinity() for each interrupt vector */
0562       break;
0563     }
0564 
0565     case RtemsIntrReqSetAffinity_Post_SetAffinity_Nop: {
0566       /*
0567        * The affinity set of the interrupt specified by ``vector`` shall not be
0568        * modified by the rtems_interrupt_set_affinity() call.
0569        */
0570       /*
0571        * Validation done by CheckSetAffinity() for each interrupt vector and in
0572        * the action code.
0573        */
0574       break;
0575     }
0576 
0577     case RtemsIntrReqSetAffinity_Post_SetAffinity_NA:
0578       break;
0579   }
0580 }
0581 
0582 static void RtemsIntrReqSetAffinity_Setup(
0583   RtemsIntrReqSetAffinity_Context *ctx
0584 )
0585 {
0586   ctx->some_vector = GetValidInterruptVectorNumber( NULL );
0587 }
0588 
0589 static void RtemsIntrReqSetAffinity_Setup_Wrap( void *arg )
0590 {
0591   RtemsIntrReqSetAffinity_Context *ctx;
0592 
0593   ctx = arg;
0594   ctx->Map.in_action_loop = false;
0595   RtemsIntrReqSetAffinity_Setup( ctx );
0596 }
0597 
0598 static void RtemsIntrReqSetAffinity_Prepare(
0599   RtemsIntrReqSetAffinity_Context *ctx
0600 )
0601 {
0602   CPU_FILL_S( sizeof( ctx->cpuset_obj ), &ctx->cpuset_obj[ 0 ] );
0603 }
0604 
0605 static void RtemsIntrReqSetAffinity_Action(
0606   RtemsIntrReqSetAffinity_Context *ctx
0607 )
0608 {
0609   rtems_status_code sc;
0610 
0611   if (
0612     ctx->valid_vector && ctx->cpusetsize == sizeof( ctx->cpuset_obj[ 0 ] ) &&
0613     ctx->cpuset == &ctx->cpuset_obj[ 0 ] && !CPU_EMPTY( &ctx->cpuset_obj[ 0 ] )
0614   ) {
0615     for (
0616       ctx->vector = 0;
0617       ctx->vector < BSP_INTERRUPT_VECTOR_COUNT;
0618       ++ctx->vector
0619     ) {
0620       rtems_interrupt_attributes attr;
0621 
0622       memset( &attr, 0, sizeof( attr ) );
0623       sc = rtems_interrupt_get_attributes( ctx->vector, &attr );
0624 
0625       if ( sc == RTEMS_INVALID_ID ) {
0626         continue;
0627       }
0628 
0629       T_rsc_success( sc );
0630 
0631       CheckSetAffinity( ctx, &attr );
0632       ctx->status = RTEMS_SUCCESSFUL;
0633     }
0634   } else {
0635     cpu_set_t set;
0636     cpu_set_t set2;
0637 
0638     CPU_ZERO( &set );
0639     CPU_ZERO( &set2 );
0640     CPU_SET( 0, &set );
0641     CPU_SET( 0, &set2 );
0642 
0643     if ( ctx->valid_vector ) {
0644       ctx->vector = ctx->some_vector;
0645 
0646       sc = rtems_interrupt_get_affinity( ctx->vector, sizeof( set ), &set );
0647       T_true( sc == RTEMS_SUCCESSFUL || sc == RTEMS_UNSATISFIED );
0648     } else {
0649       ctx->vector = BSP_INTERRUPT_VECTOR_COUNT;
0650     }
0651 
0652     if ( !CPU_EMPTY( &ctx->cpuset_obj[ 0 ] ) ) {
0653       CPU_COPY( &set, &ctx->cpuset_obj[ 0 ] );
0654     }
0655 
0656     ctx->status = rtems_interrupt_set_affinity(
0657       ctx->vector,
0658       ctx->cpusetsize,
0659       ctx->cpuset
0660     );
0661 
0662     if ( ctx->valid_vector ) {
0663       sc = rtems_interrupt_get_affinity( ctx->vector, sizeof( set2 ), &set2 );
0664       T_true( sc == RTEMS_SUCCESSFUL || sc == RTEMS_UNSATISFIED );
0665       T_eq_int( CPU_CMP( &set, &set2 ), 0 );
0666     }
0667   }
0668 }
0669 
0670 static const RtemsIntrReqSetAffinity_Entry
0671 RtemsIntrReqSetAffinity_Entries[] = {
0672   { 0, 0, 0, 1, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvAddr,
0673     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
0674   { 0, 0, 0, 1, 1, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvAddr,
0675     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
0676   { 0, 0, 0, 1, 1, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId,
0677     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
0678   { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum,
0679     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
0680   { 0, 0, 0, 1, 0, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId,
0681     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
0682   { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum,
0683     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
0684   { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok,
0685     RtemsIntrReqSetAffinity_Post_SetAffinity_Set },
0686   { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat,
0687     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
0688   { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok,
0689     RtemsIntrReqSetAffinity_Post_SetAffinity_Set },
0690   { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat,
0691     RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }
0692 };
0693 
0694 static const uint8_t
0695 RtemsIntrReqSetAffinity_Map[] = {
0696   3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 6, 7, 0, 0, 6, 7, 0, 0, 3, 3,
0697   0, 0, 3, 3, 0, 0, 8, 9, 0, 0, 8, 9, 0, 0, 5, 5, 0, 0, 5, 5, 0, 0, 2, 2, 1, 1,
0698   2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2,
0699   1, 1, 4, 4, 1, 1, 4, 4, 1, 1, 4, 4, 1, 1, 4, 4, 1, 1
0700 };
0701 
0702 static size_t RtemsIntrReqSetAffinity_Scope( void *arg, char *buf, size_t n )
0703 {
0704   RtemsIntrReqSetAffinity_Context *ctx;
0705 
0706   ctx = arg;
0707 
0708   if ( ctx->Map.in_action_loop ) {
0709     return T_get_scope(
0710       RtemsIntrReqSetAffinity_PreDesc,
0711       buf,
0712       n,
0713       ctx->Map.pcs
0714     );
0715   }
0716 
0717   return 0;
0718 }
0719 
0720 static T_fixture RtemsIntrReqSetAffinity_Fixture = {
0721   .setup = RtemsIntrReqSetAffinity_Setup_Wrap,
0722   .stop = NULL,
0723   .teardown = NULL,
0724   .scope = RtemsIntrReqSetAffinity_Scope,
0725   .initial_context = &RtemsIntrReqSetAffinity_Instance
0726 };
0727 
0728 static inline RtemsIntrReqSetAffinity_Entry RtemsIntrReqSetAffinity_PopEntry(
0729   RtemsIntrReqSetAffinity_Context *ctx
0730 )
0731 {
0732   size_t index;
0733 
0734   index = ctx->Map.index;
0735   ctx->Map.index = index + 1;
0736   return RtemsIntrReqSetAffinity_Entries[
0737     RtemsIntrReqSetAffinity_Map[ index ]
0738   ];
0739 }
0740 
0741 static void RtemsIntrReqSetAffinity_SetPreConditionStates(
0742   RtemsIntrReqSetAffinity_Context *ctx
0743 )
0744 {
0745   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0746   ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0747 
0748   if ( ctx->Map.entry.Pre_CPUSetOnline_NA ) {
0749     ctx->Map.pcs[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA;
0750   } else {
0751     ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0752   }
0753 
0754   if ( ctx->Map.entry.Pre_CPUSetHuge_NA ) {
0755     ctx->Map.pcs[ 3 ] = RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA;
0756   } else {
0757     ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
0758   }
0759 
0760   ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
0761 
0762   if ( ctx->Map.entry.Pre_CanSetAffinity_NA ) {
0763     ctx->Map.pcs[ 5 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA;
0764   } else {
0765     ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
0766   }
0767 }
0768 
0769 static void RtemsIntrReqSetAffinity_TestVariant(
0770   RtemsIntrReqSetAffinity_Context *ctx
0771 )
0772 {
0773   RtemsIntrReqSetAffinity_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0774   RtemsIntrReqSetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0775   RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0776   RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0777   RtemsIntrReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 4 ] );
0778   RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Prepare( ctx, ctx->Map.pcs[ 5 ] );
0779   RtemsIntrReqSetAffinity_Action( ctx );
0780   RtemsIntrReqSetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0781   RtemsIntrReqSetAffinity_Post_SetAffinity_Check(
0782     ctx,
0783     ctx->Map.entry.Post_SetAffinity
0784   );
0785 }
0786 
0787 /**
0788  * @fn void T_case_body_RtemsIntrReqSetAffinity( void )
0789  */
0790 T_TEST_CASE_FIXTURE(
0791   RtemsIntrReqSetAffinity,
0792   &RtemsIntrReqSetAffinity_Fixture
0793 )
0794 {
0795   RtemsIntrReqSetAffinity_Context *ctx;
0796 
0797   ctx = T_fixture_context();
0798   ctx->Map.in_action_loop = true;
0799   ctx->Map.index = 0;
0800 
0801   for (
0802     ctx->Map.pci[ 0 ] = RtemsIntrReqSetAffinity_Pre_Vector_Valid;
0803     ctx->Map.pci[ 0 ] < RtemsIntrReqSetAffinity_Pre_Vector_NA;
0804     ++ctx->Map.pci[ 0 ]
0805   ) {
0806     for (
0807       ctx->Map.pci[ 1 ] = RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew;
0808       ctx->Map.pci[ 1 ] < RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA;
0809       ++ctx->Map.pci[ 1 ]
0810     ) {
0811       for (
0812         ctx->Map.pci[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid;
0813         ctx->Map.pci[ 2 ] < RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA;
0814         ++ctx->Map.pci[ 2 ]
0815       ) {
0816         for (
0817           ctx->Map.pci[ 3 ] = RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero;
0818           ctx->Map.pci[ 3 ] < RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA;
0819           ++ctx->Map.pci[ 3 ]
0820         ) {
0821           for (
0822             ctx->Map.pci[ 4 ] = RtemsIntrReqSetAffinity_Pre_CPUSet_Valid;
0823             ctx->Map.pci[ 4 ] < RtemsIntrReqSetAffinity_Pre_CPUSet_NA;
0824             ++ctx->Map.pci[ 4 ]
0825           ) {
0826             for (
0827               ctx->Map.pci[ 5 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Yes;
0828               ctx->Map.pci[ 5 ] < RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA;
0829               ++ctx->Map.pci[ 5 ]
0830             ) {
0831               ctx->Map.entry = RtemsIntrReqSetAffinity_PopEntry( ctx );
0832               RtemsIntrReqSetAffinity_SetPreConditionStates( ctx );
0833               RtemsIntrReqSetAffinity_Prepare( ctx );
0834               RtemsIntrReqSetAffinity_TestVariant( ctx );
0835             }
0836           }
0837         }
0838       }
0839     }
0840   }
0841 }
0842 
0843 /** @} */