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 RtemsIntrReqSetPriority
0007  */
0008 
0009 /*
0010  * Copyright (C) 2024 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 <rtems.h>
0056 #include <bsp/irq-generic.h>
0057 
0058 #include "tx-support.h"
0059 
0060 #include <rtems/test.h>
0061 
0062 /**
0063  * @defgroup RtemsIntrReqSetPriority spec:/rtems/intr/req/set-priority
0064  *
0065  * @ingroup TestsuitesValidationIntr
0066  *
0067  * @{
0068  */
0069 
0070 typedef enum {
0071   RtemsIntrReqSetPriority_Pre_Vector_Valid,
0072   RtemsIntrReqSetPriority_Pre_Vector_Invalid,
0073   RtemsIntrReqSetPriority_Pre_Vector_NA
0074 } RtemsIntrReqSetPriority_Pre_Vector;
0075 
0076 typedef enum {
0077   RtemsIntrReqSetPriority_Pre_Priority_Valid,
0078   RtemsIntrReqSetPriority_Pre_Priority_Invalid,
0079   RtemsIntrReqSetPriority_Pre_Priority_NA
0080 } RtemsIntrReqSetPriority_Pre_Priority;
0081 
0082 typedef enum {
0083   RtemsIntrReqSetPriority_Pre_CanSetPriority_Yes,
0084   RtemsIntrReqSetPriority_Pre_CanSetPriority_No,
0085   RtemsIntrReqSetPriority_Pre_CanSetPriority_NA
0086 } RtemsIntrReqSetPriority_Pre_CanSetPriority;
0087 
0088 typedef enum {
0089   RtemsIntrReqSetPriority_Post_Status_Ok,
0090   RtemsIntrReqSetPriority_Post_Status_InvId,
0091   RtemsIntrReqSetPriority_Post_Status_InvPrio,
0092   RtemsIntrReqSetPriority_Post_Status_Unsat,
0093   RtemsIntrReqSetPriority_Post_Status_NA
0094 } RtemsIntrReqSetPriority_Post_Status;
0095 
0096 typedef struct {
0097   uint8_t Skip : 1;
0098   uint8_t Pre_Vector_NA : 1;
0099   uint8_t Pre_Priority_NA : 1;
0100   uint8_t Pre_CanSetPriority_NA : 1;
0101   uint8_t Post_Status : 3;
0102 } RtemsIntrReqSetPriority_Entry;
0103 
0104 /**
0105  * @brief Test context for spec:/rtems/intr/req/set-priority test case.
0106  */
0107 typedef struct {
0108   /**
0109    * @brief If this member is true, then the ``vector`` parameter shall be
0110    *   valid.
0111    */
0112   bool valid_vector;
0113 
0114   /**
0115    * @brief If this member is true, then the ``priority`` parameter shall be
0116    *   valid.
0117    */
0118   bool valid_priority;
0119 
0120   /**
0121    * @brief If this member is true, then setting the priority shall be
0122    *   supported.
0123    */
0124   bool can_set_priority;
0125 
0126   /**
0127    * @brief This member specifies the expected status.
0128    */
0129   rtems_status_code expected_status;
0130 
0131   struct {
0132     /**
0133      * @brief This member defines the pre-condition indices for the next
0134      *   action.
0135      */
0136     size_t pci[ 3 ];
0137 
0138     /**
0139      * @brief This member defines the pre-condition states for the next action.
0140      */
0141     size_t pcs[ 3 ];
0142 
0143     /**
0144      * @brief If this member is true, then the test action loop is executed.
0145      */
0146     bool in_action_loop;
0147 
0148     /**
0149      * @brief This member contains the next transition map index.
0150      */
0151     size_t index;
0152 
0153     /**
0154      * @brief This member contains the current transition map entry.
0155      */
0156     RtemsIntrReqSetPriority_Entry entry;
0157 
0158     /**
0159      * @brief If this member is true, then the current transition variant
0160      *   should be skipped.
0161      */
0162     bool skip;
0163   } Map;
0164 } RtemsIntrReqSetPriority_Context;
0165 
0166 static RtemsIntrReqSetPriority_Context
0167   RtemsIntrReqSetPriority_Instance;
0168 
0169 static const char * const RtemsIntrReqSetPriority_PreDesc_Vector[] = {
0170   "Valid",
0171   "Invalid",
0172   "NA"
0173 };
0174 
0175 static const char * const RtemsIntrReqSetPriority_PreDesc_Priority[] = {
0176   "Valid",
0177   "Invalid",
0178   "NA"
0179 };
0180 
0181 static const char * const RtemsIntrReqSetPriority_PreDesc_CanSetPriority[] = {
0182   "Yes",
0183   "No",
0184   "NA"
0185 };
0186 
0187 static const char * const * const RtemsIntrReqSetPriority_PreDesc[] = {
0188   RtemsIntrReqSetPriority_PreDesc_Vector,
0189   RtemsIntrReqSetPriority_PreDesc_Priority,
0190   RtemsIntrReqSetPriority_PreDesc_CanSetPriority,
0191   NULL
0192 };
0193 
0194 typedef RtemsIntrReqSetPriority_Context Context;
0195 
0196 static void CheckSetPriority( Context *ctx, rtems_vector_number vector )
0197 {
0198   rtems_status_code sc;
0199   uint32_t          priority;
0200 
0201   if ( ctx->valid_priority ) {
0202     (void) rtems_interrupt_get_priority( vector, &priority );
0203   } else {
0204     priority = UINT32_MAX;
0205   }
0206 
0207   sc = rtems_interrupt_set_priority( vector, priority );
0208   T_rsc( sc, ctx->expected_status );
0209 }
0210 
0211 static void RtemsIntrReqSetPriority_Pre_Vector_Prepare(
0212   RtemsIntrReqSetPriority_Context   *ctx,
0213   RtemsIntrReqSetPriority_Pre_Vector state
0214 )
0215 {
0216   switch ( state ) {
0217     case RtemsIntrReqSetPriority_Pre_Vector_Valid: {
0218       /*
0219        * While the ``vector`` parameter is associated with an interrupt vector.
0220        */
0221       ctx->valid_vector = true;
0222       break;
0223     }
0224 
0225     case RtemsIntrReqSetPriority_Pre_Vector_Invalid: {
0226       /*
0227        * While the ``vector`` parameter is not associated with an interrupt
0228        * vector.
0229        */
0230       ctx->valid_vector = false;
0231       break;
0232     }
0233 
0234     case RtemsIntrReqSetPriority_Pre_Vector_NA:
0235       break;
0236   }
0237 }
0238 
0239 static void RtemsIntrReqSetPriority_Pre_Priority_Prepare(
0240   RtemsIntrReqSetPriority_Context     *ctx,
0241   RtemsIntrReqSetPriority_Pre_Priority state
0242 )
0243 {
0244   switch ( state ) {
0245     case RtemsIntrReqSetPriority_Pre_Priority_Valid: {
0246       /*
0247        * While the ``priority`` parameter is a valid priority value.
0248        */
0249       ctx->valid_priority = true;
0250       break;
0251     }
0252 
0253     case RtemsIntrReqSetPriority_Pre_Priority_Invalid: {
0254       /*
0255        * While the ``priority`` parameter is an invalid priority value.
0256        */
0257       ctx->valid_priority = false;
0258       break;
0259     }
0260 
0261     case RtemsIntrReqSetPriority_Pre_Priority_NA:
0262       break;
0263   }
0264 }
0265 
0266 static void RtemsIntrReqSetPriority_Pre_CanSetPriority_Prepare(
0267   RtemsIntrReqSetPriority_Context           *ctx,
0268   RtemsIntrReqSetPriority_Pre_CanSetPriority state
0269 )
0270 {
0271   switch ( state ) {
0272     case RtemsIntrReqSetPriority_Pre_CanSetPriority_Yes: {
0273       /*
0274        * While setting the priority for the interrupt vector specified by
0275        * ``vector`` parameter is supported.
0276        */
0277       ctx->can_set_priority = true;
0278       break;
0279     }
0280 
0281     case RtemsIntrReqSetPriority_Pre_CanSetPriority_No: {
0282       /*
0283        * While setting the priority for the interrupt vector specified by
0284        * ``vector`` parameter is not supported.
0285        */
0286       ctx->can_set_priority = false;
0287       break;
0288     }
0289 
0290     case RtemsIntrReqSetPriority_Pre_CanSetPriority_NA:
0291       break;
0292   }
0293 }
0294 
0295 static void RtemsIntrReqSetPriority_Post_Status_Check(
0296   RtemsIntrReqSetPriority_Context    *ctx,
0297   RtemsIntrReqSetPriority_Post_Status state
0298 )
0299 {
0300   switch ( state ) {
0301     case RtemsIntrReqSetPriority_Post_Status_Ok: {
0302       /*
0303        * The return status of rtems_interrupt_set_priority() shall be
0304        * RTEMS_SUCCESSFUL.
0305        */
0306       ctx->expected_status = RTEMS_SUCCESSFUL;
0307       break;
0308     }
0309 
0310     case RtemsIntrReqSetPriority_Post_Status_InvId: {
0311       /*
0312        * The return status of rtems_interrupt_set_priority() shall be
0313        * RTEMS_INVALID_ID.
0314        */
0315       ctx->expected_status = RTEMS_INVALID_ID;
0316       break;
0317     }
0318 
0319     case RtemsIntrReqSetPriority_Post_Status_InvPrio: {
0320       /*
0321        * The return status of rtems_interrupt_set_priority() shall be
0322        * RTEMS_INVALID_PRIORITY.
0323        */
0324       ctx->expected_status = RTEMS_INVALID_PRIORITY;
0325       break;
0326     }
0327 
0328     case RtemsIntrReqSetPriority_Post_Status_Unsat: {
0329       /*
0330        * The return status of rtems_interrupt_set_priority() shall be
0331        * RTEMS_UNSATISFIED.
0332        */
0333       ctx->expected_status = RTEMS_UNSATISFIED;
0334       break;
0335     }
0336 
0337     case RtemsIntrReqSetPriority_Post_Status_NA:
0338       break;
0339   }
0340 }
0341 
0342 static void RtemsIntrReqSetPriority_Action(
0343   RtemsIntrReqSetPriority_Context *ctx
0344 )
0345 {
0346   /* Action carried out by CheckSetPriority() */
0347 }
0348 
0349 static void RtemsIntrReqSetPriority_Cleanup(
0350   RtemsIntrReqSetPriority_Context *ctx
0351 )
0352 {
0353   if ( ctx->valid_vector ) {
0354     rtems_vector_number vector;
0355 
0356     for (
0357       vector = 0;
0358       vector < BSP_INTERRUPT_VECTOR_COUNT;
0359       ++vector
0360     ) {
0361       rtems_interrupt_attributes attr;
0362       rtems_status_code          sc;
0363 
0364       memset( &attr, 0, sizeof( attr ) );
0365       sc = rtems_interrupt_get_attributes( vector, &attr );
0366 
0367       if ( sc == RTEMS_INVALID_ID ) {
0368         continue;
0369       }
0370 
0371       T_rsc_success( sc );
0372 
0373       if ( attr.can_set_priority != ctx->can_set_priority ) {
0374         continue;
0375       }
0376 
0377       CheckSetPriority( ctx, vector );
0378     }
0379   } else {
0380     CheckSetPriority( ctx, BSP_INTERRUPT_VECTOR_COUNT );
0381   }
0382 }
0383 
0384 static const RtemsIntrReqSetPriority_Entry
0385 RtemsIntrReqSetPriority_Entries[] = {
0386   { 0, 0, 1, 1, RtemsIntrReqSetPriority_Post_Status_InvId },
0387   { 0, 0, 1, 0, RtemsIntrReqSetPriority_Post_Status_Unsat },
0388   { 0, 0, 0, 0, RtemsIntrReqSetPriority_Post_Status_Ok },
0389   { 0, 0, 0, 0, RtemsIntrReqSetPriority_Post_Status_InvPrio }
0390 };
0391 
0392 static const uint8_t
0393 RtemsIntrReqSetPriority_Map[] = {
0394   2, 1, 3, 1, 0, 0, 0, 0
0395 };
0396 
0397 static size_t RtemsIntrReqSetPriority_Scope( void *arg, char *buf, size_t n )
0398 {
0399   RtemsIntrReqSetPriority_Context *ctx;
0400 
0401   ctx = arg;
0402 
0403   if ( ctx->Map.in_action_loop ) {
0404     return T_get_scope(
0405       RtemsIntrReqSetPriority_PreDesc,
0406       buf,
0407       n,
0408       ctx->Map.pcs
0409     );
0410   }
0411 
0412   return 0;
0413 }
0414 
0415 static T_fixture RtemsIntrReqSetPriority_Fixture = {
0416   .setup = NULL,
0417   .stop = NULL,
0418   .teardown = NULL,
0419   .scope = RtemsIntrReqSetPriority_Scope,
0420   .initial_context = &RtemsIntrReqSetPriority_Instance
0421 };
0422 
0423 static inline RtemsIntrReqSetPriority_Entry RtemsIntrReqSetPriority_PopEntry(
0424   RtemsIntrReqSetPriority_Context *ctx
0425 )
0426 {
0427   size_t index;
0428 
0429   index = ctx->Map.index;
0430   ctx->Map.index = index + 1;
0431   return RtemsIntrReqSetPriority_Entries[
0432     RtemsIntrReqSetPriority_Map[ index ]
0433   ];
0434 }
0435 
0436 static void RtemsIntrReqSetPriority_SetPreConditionStates(
0437   RtemsIntrReqSetPriority_Context *ctx
0438 )
0439 {
0440   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0441 
0442   if ( ctx->Map.entry.Pre_Priority_NA ) {
0443     ctx->Map.pcs[ 1 ] = RtemsIntrReqSetPriority_Pre_Priority_NA;
0444   } else {
0445     ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0446   }
0447 
0448   if ( ctx->Map.entry.Pre_CanSetPriority_NA ) {
0449     ctx->Map.pcs[ 2 ] = RtemsIntrReqSetPriority_Pre_CanSetPriority_NA;
0450   } else {
0451     ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0452   }
0453 }
0454 
0455 static void RtemsIntrReqSetPriority_TestVariant(
0456   RtemsIntrReqSetPriority_Context *ctx
0457 )
0458 {
0459   RtemsIntrReqSetPriority_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0460   RtemsIntrReqSetPriority_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0461   RtemsIntrReqSetPriority_Pre_CanSetPriority_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0462   RtemsIntrReqSetPriority_Action( ctx );
0463   RtemsIntrReqSetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0464 }
0465 
0466 /**
0467  * @fn void T_case_body_RtemsIntrReqSetPriority( void )
0468  */
0469 T_TEST_CASE_FIXTURE(
0470   RtemsIntrReqSetPriority,
0471   &RtemsIntrReqSetPriority_Fixture
0472 )
0473 {
0474   RtemsIntrReqSetPriority_Context *ctx;
0475 
0476   ctx = T_fixture_context();
0477   ctx->Map.in_action_loop = true;
0478   ctx->Map.index = 0;
0479 
0480   for (
0481     ctx->Map.pci[ 0 ] = RtemsIntrReqSetPriority_Pre_Vector_Valid;
0482     ctx->Map.pci[ 0 ] < RtemsIntrReqSetPriority_Pre_Vector_NA;
0483     ++ctx->Map.pci[ 0 ]
0484   ) {
0485     for (
0486       ctx->Map.pci[ 1 ] = RtemsIntrReqSetPriority_Pre_Priority_Valid;
0487       ctx->Map.pci[ 1 ] < RtemsIntrReqSetPriority_Pre_Priority_NA;
0488       ++ctx->Map.pci[ 1 ]
0489     ) {
0490       for (
0491         ctx->Map.pci[ 2 ] = RtemsIntrReqSetPriority_Pre_CanSetPriority_Yes;
0492         ctx->Map.pci[ 2 ] < RtemsIntrReqSetPriority_Pre_CanSetPriority_NA;
0493         ++ctx->Map.pci[ 2 ]
0494       ) {
0495         ctx->Map.entry = RtemsIntrReqSetPriority_PopEntry( ctx );
0496         RtemsIntrReqSetPriority_SetPreConditionStates( ctx );
0497         RtemsIntrReqSetPriority_TestVariant( ctx );
0498         RtemsIntrReqSetPriority_Cleanup( ctx );
0499       }
0500     }
0501   }
0502 }
0503 
0504 /** @} */