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 RtemsIntrReqGetAttributes
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021 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 <string.h>
0056 #include <bsp/irq-generic.h>
0057 #include <rtems/irq-extension.h>
0058 
0059 #include <rtems/test.h>
0060 
0061 /**
0062  * @defgroup RtemsIntrReqGetAttributes spec:/rtems/intr/req/get-attributes
0063  *
0064  * @ingroup TestsuitesValidationIntr
0065  *
0066  * @{
0067  */
0068 
0069 typedef enum {
0070   RtemsIntrReqGetAttributes_Pre_Vector_Valid,
0071   RtemsIntrReqGetAttributes_Pre_Vector_Invalid,
0072   RtemsIntrReqGetAttributes_Pre_Vector_NA
0073 } RtemsIntrReqGetAttributes_Pre_Vector;
0074 
0075 typedef enum {
0076   RtemsIntrReqGetAttributes_Pre_Attributes_Obj,
0077   RtemsIntrReqGetAttributes_Pre_Attributes_Null,
0078   RtemsIntrReqGetAttributes_Pre_Attributes_NA
0079 } RtemsIntrReqGetAttributes_Pre_Attributes;
0080 
0081 typedef enum {
0082   RtemsIntrReqGetAttributes_Post_Status_Ok,
0083   RtemsIntrReqGetAttributes_Post_Status_InvAddr,
0084   RtemsIntrReqGetAttributes_Post_Status_InvId,
0085   RtemsIntrReqGetAttributes_Post_Status_NA
0086 } RtemsIntrReqGetAttributes_Post_Status;
0087 
0088 typedef enum {
0089   RtemsIntrReqGetAttributes_Post_Attributes_Nop,
0090   RtemsIntrReqGetAttributes_Post_Attributes_Zero,
0091   RtemsIntrReqGetAttributes_Post_Attributes_Set,
0092   RtemsIntrReqGetAttributes_Post_Attributes_NA
0093 } RtemsIntrReqGetAttributes_Post_Attributes;
0094 
0095 typedef struct {
0096   uint8_t Skip : 1;
0097   uint8_t Pre_Vector_NA : 1;
0098   uint8_t Pre_Attributes_NA : 1;
0099   uint8_t Post_Status : 2;
0100   uint8_t Post_Attributes : 2;
0101 } RtemsIntrReqGetAttributes_Entry;
0102 
0103 /**
0104  * @brief Test context for spec:/rtems/intr/req/get-attributes test case.
0105  */
0106 typedef struct {
0107   /**
0108    * @brief This member provides the rtems_interrupt_attributes object.
0109    */
0110   rtems_interrupt_attributes attributes_obj;
0111 
0112   /**
0113    * @brief If this member is true, then the ``vector`` parameter shall be
0114    *   valid.
0115    */
0116   bool valid_vector;
0117 
0118   /**
0119    * @brief This member specifies if the ``attributes`` parameter value.
0120    */
0121   rtems_interrupt_attributes *attributes;
0122 
0123   /**
0124    * @brief This member contains the return value of the
0125    *   rtems_interrupt_get_attributes() call.
0126    */
0127   rtems_status_code status;
0128 
0129   struct {
0130     /**
0131      * @brief This member defines the pre-condition states for the next action.
0132      */
0133     size_t pcs[ 2 ];
0134 
0135     /**
0136      * @brief If this member is true, then the test action loop is executed.
0137      */
0138     bool in_action_loop;
0139 
0140     /**
0141      * @brief This member contains the next transition map index.
0142      */
0143     size_t index;
0144 
0145     /**
0146      * @brief This member contains the current transition map entry.
0147      */
0148     RtemsIntrReqGetAttributes_Entry entry;
0149 
0150     /**
0151      * @brief If this member is true, then the current transition variant
0152      *   should be skipped.
0153      */
0154     bool skip;
0155   } Map;
0156 } RtemsIntrReqGetAttributes_Context;
0157 
0158 static RtemsIntrReqGetAttributes_Context
0159   RtemsIntrReqGetAttributes_Instance;
0160 
0161 static const char * const RtemsIntrReqGetAttributes_PreDesc_Vector[] = {
0162   "Valid",
0163   "Invalid",
0164   "NA"
0165 };
0166 
0167 static const char * const RtemsIntrReqGetAttributes_PreDesc_Attributes[] = {
0168   "Obj",
0169   "Null",
0170   "NA"
0171 };
0172 
0173 static const char * const * const RtemsIntrReqGetAttributes_PreDesc[] = {
0174   RtemsIntrReqGetAttributes_PreDesc_Vector,
0175   RtemsIntrReqGetAttributes_PreDesc_Attributes,
0176   NULL
0177 };
0178 
0179 static void RtemsIntrReqGetAttributes_Pre_Vector_Prepare(
0180   RtemsIntrReqGetAttributes_Context   *ctx,
0181   RtemsIntrReqGetAttributes_Pre_Vector state
0182 )
0183 {
0184   switch ( state ) {
0185     case RtemsIntrReqGetAttributes_Pre_Vector_Valid: {
0186       /*
0187        * While the ``vector`` parameter is associated with an interrupt vector.
0188        */
0189       ctx->valid_vector = true;
0190       break;
0191     }
0192 
0193     case RtemsIntrReqGetAttributes_Pre_Vector_Invalid: {
0194       /*
0195        * While the ``vector`` parameter is not associated with an interrupt
0196        * vector.
0197        */
0198       ctx->valid_vector = false;
0199       break;
0200     }
0201 
0202     case RtemsIntrReqGetAttributes_Pre_Vector_NA:
0203       break;
0204   }
0205 }
0206 
0207 static void RtemsIntrReqGetAttributes_Pre_Attributes_Prepare(
0208   RtemsIntrReqGetAttributes_Context       *ctx,
0209   RtemsIntrReqGetAttributes_Pre_Attributes state
0210 )
0211 {
0212   switch ( state ) {
0213     case RtemsIntrReqGetAttributes_Pre_Attributes_Obj: {
0214       /*
0215        * While the ``attributes`` parameter references an object of type
0216        * rtems_interrupt_attributes.
0217        */
0218       ctx->attributes = &ctx->attributes_obj;
0219       break;
0220     }
0221 
0222     case RtemsIntrReqGetAttributes_Pre_Attributes_Null: {
0223       /*
0224        * While the ``attributes`` parameter is equal to NULL.
0225        */
0226       ctx->attributes = NULL;
0227       break;
0228     }
0229 
0230     case RtemsIntrReqGetAttributes_Pre_Attributes_NA:
0231       break;
0232   }
0233 }
0234 
0235 static void RtemsIntrReqGetAttributes_Post_Status_Check(
0236   RtemsIntrReqGetAttributes_Context    *ctx,
0237   RtemsIntrReqGetAttributes_Post_Status state
0238 )
0239 {
0240   switch ( state ) {
0241     case RtemsIntrReqGetAttributes_Post_Status_Ok: {
0242       /*
0243        * The return status of rtems_interrupt_get_attributes() shall be
0244        * RTEMS_SUCCESSFUL.
0245        */
0246       T_rsc_success( ctx->status );
0247       break;
0248     }
0249 
0250     case RtemsIntrReqGetAttributes_Post_Status_InvAddr: {
0251       /*
0252        * The return status of rtems_interrupt_get_attributes() shall be
0253        * RTEMS_INVALID_ADDRESS.
0254        */
0255       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0256       break;
0257     }
0258 
0259     case RtemsIntrReqGetAttributes_Post_Status_InvId: {
0260       /*
0261        * The return status of rtems_interrupt_get_attributes() shall be
0262        * RTEMS_INVALID_ID.
0263        */
0264       T_rsc( ctx->status, RTEMS_INVALID_ID );
0265       break;
0266     }
0267 
0268     case RtemsIntrReqGetAttributes_Post_Status_NA:
0269       break;
0270   }
0271 }
0272 
0273 static void RtemsIntrReqGetAttributes_Post_Attributes_Check(
0274   RtemsIntrReqGetAttributes_Context        *ctx,
0275   RtemsIntrReqGetAttributes_Post_Attributes state
0276 )
0277 {
0278   rtems_interrupt_attributes attr;
0279 
0280   switch ( state ) {
0281     case RtemsIntrReqGetAttributes_Post_Attributes_Nop: {
0282       /*
0283        * Objects referenced by the ``attributes`` parameter in past calls to
0284        * rtems_interrupt_get_attributes() shall not be accessed by the
0285        * rtems_interrupt_get_attributes() call.
0286        */
0287       memset( &attr, 0xa5, sizeof( attr ) );
0288       T_eq_mem( &ctx->attributes_obj, &attr, sizeof( attr ) );
0289       break;
0290     }
0291 
0292     case RtemsIntrReqGetAttributes_Post_Attributes_Zero: {
0293       /*
0294        * The object referenced by the ``attributes`` parameter shall cleared to
0295        * zero.
0296        */
0297       memset( &attr, 0, sizeof( attr ) );
0298       T_eq_mem( &ctx->attributes_obj, &attr, sizeof( attr ) );
0299       break;
0300     }
0301 
0302     case RtemsIntrReqGetAttributes_Post_Attributes_Set: {
0303       /*
0304        * The members of the object referenced by the ``attributes`` parameter
0305        * shall be set to the attributes of the interrupt vector specified by
0306        * ``vector``.
0307        */
0308       memset( &attr, 0xa5, sizeof( attr ) );
0309       T_ne_mem( &ctx->attributes_obj, &attr, sizeof( attr ) );
0310       break;
0311     }
0312 
0313     case RtemsIntrReqGetAttributes_Post_Attributes_NA:
0314       break;
0315   }
0316 }
0317 
0318 static void RtemsIntrReqGetAttributes_Prepare(
0319   RtemsIntrReqGetAttributes_Context *ctx
0320 )
0321 {
0322   memset( &ctx->attributes_obj, 0xa5, sizeof( ctx->attributes_obj ) );
0323 }
0324 
0325 static void RtemsIntrReqGetAttributes_Action(
0326   RtemsIntrReqGetAttributes_Context *ctx
0327 )
0328 {
0329   rtems_vector_number vector;
0330 
0331   if ( ctx->valid_vector && ctx->attributes != NULL ) {
0332     ctx->status = RTEMS_INTERNAL_ERROR;
0333 
0334     for ( vector = 0; vector < BSP_INTERRUPT_VECTOR_COUNT; ++vector ) {
0335       rtems_status_code sc;
0336 
0337       memset( &ctx->attributes_obj, 0xff, sizeof( ctx->attributes_obj ) );
0338       sc = rtems_interrupt_get_attributes( vector, ctx->attributes );
0339 
0340       if ( sc == RTEMS_INVALID_ID ) {
0341         continue;
0342       }
0343 
0344       T_rsc_success( sc );
0345       ctx->status = sc;
0346 
0347       if ( ctx->attributes_obj.can_enable ) {
0348         T_true( ctx->attributes_obj.maybe_enable );
0349       }
0350 
0351       if ( ctx->attributes_obj.can_disable ) {
0352         T_true( ctx->attributes_obj.maybe_disable );
0353         T_true(
0354           ctx->attributes_obj.can_enable || ctx->attributes_obj.maybe_enable
0355         );
0356       }
0357     }
0358   } else {
0359     if ( ctx->valid_vector ) {
0360       vector = 0;
0361     } else {
0362       vector = BSP_INTERRUPT_VECTOR_COUNT;
0363     }
0364 
0365     ctx->status = rtems_interrupt_get_attributes( vector, ctx->attributes );
0366   }
0367 }
0368 
0369 static const RtemsIntrReqGetAttributes_Entry
0370 RtemsIntrReqGetAttributes_Entries[] = {
0371   { 0, 0, 0, RtemsIntrReqGetAttributes_Post_Status_InvAddr,
0372     RtemsIntrReqGetAttributes_Post_Attributes_Nop },
0373   { 0, 0, 0, RtemsIntrReqGetAttributes_Post_Status_Ok,
0374     RtemsIntrReqGetAttributes_Post_Attributes_Set },
0375   { 0, 0, 0, RtemsIntrReqGetAttributes_Post_Status_InvId,
0376     RtemsIntrReqGetAttributes_Post_Attributes_Zero }
0377 };
0378 
0379 static const uint8_t
0380 RtemsIntrReqGetAttributes_Map[] = {
0381   1, 0, 2, 0
0382 };
0383 
0384 static size_t RtemsIntrReqGetAttributes_Scope( void *arg, char *buf, size_t n )
0385 {
0386   RtemsIntrReqGetAttributes_Context *ctx;
0387 
0388   ctx = arg;
0389 
0390   if ( ctx->Map.in_action_loop ) {
0391     return T_get_scope(
0392       RtemsIntrReqGetAttributes_PreDesc,
0393       buf,
0394       n,
0395       ctx->Map.pcs
0396     );
0397   }
0398 
0399   return 0;
0400 }
0401 
0402 static T_fixture RtemsIntrReqGetAttributes_Fixture = {
0403   .setup = NULL,
0404   .stop = NULL,
0405   .teardown = NULL,
0406   .scope = RtemsIntrReqGetAttributes_Scope,
0407   .initial_context = &RtemsIntrReqGetAttributes_Instance
0408 };
0409 
0410 static inline RtemsIntrReqGetAttributes_Entry
0411 RtemsIntrReqGetAttributes_PopEntry( RtemsIntrReqGetAttributes_Context *ctx )
0412 {
0413   size_t index;
0414 
0415   index = ctx->Map.index;
0416   ctx->Map.index = index + 1;
0417   return RtemsIntrReqGetAttributes_Entries[
0418     RtemsIntrReqGetAttributes_Map[ index ]
0419   ];
0420 }
0421 
0422 static void RtemsIntrReqGetAttributes_TestVariant(
0423   RtemsIntrReqGetAttributes_Context *ctx
0424 )
0425 {
0426   RtemsIntrReqGetAttributes_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0427   RtemsIntrReqGetAttributes_Pre_Attributes_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0428   RtemsIntrReqGetAttributes_Action( ctx );
0429   RtemsIntrReqGetAttributes_Post_Status_Check(
0430     ctx,
0431     ctx->Map.entry.Post_Status
0432   );
0433   RtemsIntrReqGetAttributes_Post_Attributes_Check(
0434     ctx,
0435     ctx->Map.entry.Post_Attributes
0436   );
0437 }
0438 
0439 /**
0440  * @fn void T_case_body_RtemsIntrReqGetAttributes( void )
0441  */
0442 T_TEST_CASE_FIXTURE(
0443   RtemsIntrReqGetAttributes,
0444   &RtemsIntrReqGetAttributes_Fixture
0445 )
0446 {
0447   RtemsIntrReqGetAttributes_Context *ctx;
0448 
0449   ctx = T_fixture_context();
0450   ctx->Map.in_action_loop = true;
0451   ctx->Map.index = 0;
0452 
0453   for (
0454     ctx->Map.pcs[ 0 ] = RtemsIntrReqGetAttributes_Pre_Vector_Valid;
0455     ctx->Map.pcs[ 0 ] < RtemsIntrReqGetAttributes_Pre_Vector_NA;
0456     ++ctx->Map.pcs[ 0 ]
0457   ) {
0458     for (
0459       ctx->Map.pcs[ 1 ] = RtemsIntrReqGetAttributes_Pre_Attributes_Obj;
0460       ctx->Map.pcs[ 1 ] < RtemsIntrReqGetAttributes_Pre_Attributes_NA;
0461       ++ctx->Map.pcs[ 1 ]
0462     ) {
0463       ctx->Map.entry = RtemsIntrReqGetAttributes_PopEntry( ctx );
0464       RtemsIntrReqGetAttributes_Prepare( ctx );
0465       RtemsIntrReqGetAttributes_TestVariant( ctx );
0466     }
0467   }
0468 }
0469 
0470 /** @} */