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 RtemsIntrReqGetPriority
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 RtemsIntrReqGetPriority spec:/rtems/intr/req/get-priority
0064  *
0065  * @ingroup TestsuitesValidationIntr
0066  *
0067  * @{
0068  */
0069 
0070 typedef enum {
0071   RtemsIntrReqGetPriority_Pre_Vector_Valid,
0072   RtemsIntrReqGetPriority_Pre_Vector_Invalid,
0073   RtemsIntrReqGetPriority_Pre_Vector_NA
0074 } RtemsIntrReqGetPriority_Pre_Vector;
0075 
0076 typedef enum {
0077   RtemsIntrReqGetPriority_Pre_Priority_Valid,
0078   RtemsIntrReqGetPriority_Pre_Priority_Null,
0079   RtemsIntrReqGetPriority_Pre_Priority_NA
0080 } RtemsIntrReqGetPriority_Pre_Priority;
0081 
0082 typedef enum {
0083   RtemsIntrReqGetPriority_Pre_CanGetPriority_Yes,
0084   RtemsIntrReqGetPriority_Pre_CanGetPriority_No,
0085   RtemsIntrReqGetPriority_Pre_CanGetPriority_NA
0086 } RtemsIntrReqGetPriority_Pre_CanGetPriority;
0087 
0088 typedef enum {
0089   RtemsIntrReqGetPriority_Post_Status_Ok,
0090   RtemsIntrReqGetPriority_Post_Status_InvAddr,
0091   RtemsIntrReqGetPriority_Post_Status_InvId,
0092   RtemsIntrReqGetPriority_Post_Status_Unsat,
0093   RtemsIntrReqGetPriority_Post_Status_NA
0094 } RtemsIntrReqGetPriority_Post_Status;
0095 
0096 typedef enum {
0097   RtemsIntrReqGetPriority_Post_PriorityObj_Set,
0098   RtemsIntrReqGetPriority_Post_PriorityObj_Nop,
0099   RtemsIntrReqGetPriority_Post_PriorityObj_NA
0100 } RtemsIntrReqGetPriority_Post_PriorityObj;
0101 
0102 typedef struct {
0103   uint16_t Skip : 1;
0104   uint16_t Pre_Vector_NA : 1;
0105   uint16_t Pre_Priority_NA : 1;
0106   uint16_t Pre_CanGetPriority_NA : 1;
0107   uint16_t Post_Status : 3;
0108   uint16_t Post_PriorityObj : 2;
0109 } RtemsIntrReqGetPriority_Entry;
0110 
0111 /**
0112  * @brief Test context for spec:/rtems/intr/req/get-priority test case.
0113  */
0114 typedef struct {
0115   /**
0116    * @brief This member provides the object referenced by the ``priority``
0117    *   parameter.
0118    */
0119   uint32_t priority_obj;
0120 
0121   /**
0122    * @brief If this member is true, then the ``vector`` parameter shall be
0123    *   valid.
0124    */
0125   bool valid_vector;
0126 
0127   /**
0128    * @brief If this member is true, then getting the priority shall be
0129    *   supported.
0130    */
0131   bool can_get_priority;
0132 
0133   /**
0134    * @brief This member specifies the ``priority`` parameter value.
0135    */
0136   uint32_t *priority;
0137 
0138   /**
0139    * @brief This member specifies the expected status.
0140    */
0141   rtems_status_code expected_status;
0142 
0143   /**
0144    * @brief This member specifies the expected value of the priority object.
0145    */
0146   void (*expected_priority)(uint32_t);
0147 
0148   struct {
0149     /**
0150      * @brief This member defines the pre-condition indices for the next
0151      *   action.
0152      */
0153     size_t pci[ 3 ];
0154 
0155     /**
0156      * @brief This member defines the pre-condition states for the next action.
0157      */
0158     size_t pcs[ 3 ];
0159 
0160     /**
0161      * @brief If this member is true, then the test action loop is executed.
0162      */
0163     bool in_action_loop;
0164 
0165     /**
0166      * @brief This member contains the next transition map index.
0167      */
0168     size_t index;
0169 
0170     /**
0171      * @brief This member contains the current transition map entry.
0172      */
0173     RtemsIntrReqGetPriority_Entry entry;
0174 
0175     /**
0176      * @brief If this member is true, then the current transition variant
0177      *   should be skipped.
0178      */
0179     bool skip;
0180   } Map;
0181 } RtemsIntrReqGetPriority_Context;
0182 
0183 static RtemsIntrReqGetPriority_Context
0184   RtemsIntrReqGetPriority_Instance;
0185 
0186 static const char * const RtemsIntrReqGetPriority_PreDesc_Vector[] = {
0187   "Valid",
0188   "Invalid",
0189   "NA"
0190 };
0191 
0192 static const char * const RtemsIntrReqGetPriority_PreDesc_Priority[] = {
0193   "Valid",
0194   "Null",
0195   "NA"
0196 };
0197 
0198 static const char * const RtemsIntrReqGetPriority_PreDesc_CanGetPriority[] = {
0199   "Yes",
0200   "No",
0201   "NA"
0202 };
0203 
0204 static const char * const * const RtemsIntrReqGetPriority_PreDesc[] = {
0205   RtemsIntrReqGetPriority_PreDesc_Vector,
0206   RtemsIntrReqGetPriority_PreDesc_Priority,
0207   RtemsIntrReqGetPriority_PreDesc_CanGetPriority,
0208   NULL
0209 };
0210 
0211 typedef RtemsIntrReqGetPriority_Context Context;
0212 
0213 #define PRIORITY_UNSET (UINT32_MAX - 1234)
0214 
0215 static void PriorityIsSet( uint32_t priority )
0216 {
0217   T_lt_u32( priority, PRIORITY_UNSET );
0218 }
0219 
0220 static void PriorityIsNotSet( uint32_t priority )
0221 {
0222   T_eq_u32( priority, PRIORITY_UNSET );
0223 }
0224 
0225 static void CheckGetPriority( Context *ctx, rtems_vector_number vector )
0226 {
0227   rtems_status_code sc;
0228 
0229   ctx->priority_obj = PRIORITY_UNSET;
0230   sc = rtems_interrupt_get_priority( vector, ctx->priority );
0231   T_rsc( sc, ctx->expected_status );
0232   (*ctx->expected_priority)( ctx->priority_obj );
0233 }
0234 
0235 static void RtemsIntrReqGetPriority_Pre_Vector_Prepare(
0236   RtemsIntrReqGetPriority_Context   *ctx,
0237   RtemsIntrReqGetPriority_Pre_Vector state
0238 )
0239 {
0240   switch ( state ) {
0241     case RtemsIntrReqGetPriority_Pre_Vector_Valid: {
0242       /*
0243        * While the ``vector`` parameter is associated with an interrupt vector.
0244        */
0245       ctx->valid_vector = true;
0246       break;
0247     }
0248 
0249     case RtemsIntrReqGetPriority_Pre_Vector_Invalid: {
0250       /*
0251        * While the ``vector`` parameter is not associated with an interrupt
0252        * vector.
0253        */
0254       ctx->valid_vector = false;
0255       break;
0256     }
0257 
0258     case RtemsIntrReqGetPriority_Pre_Vector_NA:
0259       break;
0260   }
0261 }
0262 
0263 static void RtemsIntrReqGetPriority_Pre_Priority_Prepare(
0264   RtemsIntrReqGetPriority_Context     *ctx,
0265   RtemsIntrReqGetPriority_Pre_Priority state
0266 )
0267 {
0268   switch ( state ) {
0269     case RtemsIntrReqGetPriority_Pre_Priority_Valid: {
0270       /*
0271        * While the ``priority`` parameter references an object of type
0272        * uint32_t.
0273        */
0274       ctx->priority = &ctx->priority_obj;
0275       break;
0276     }
0277 
0278     case RtemsIntrReqGetPriority_Pre_Priority_Null: {
0279       /*
0280        * While the ``priority`` parameter is equal to NULL.
0281        */
0282       ctx->priority = NULL;
0283       break;
0284     }
0285 
0286     case RtemsIntrReqGetPriority_Pre_Priority_NA:
0287       break;
0288   }
0289 }
0290 
0291 static void RtemsIntrReqGetPriority_Pre_CanGetPriority_Prepare(
0292   RtemsIntrReqGetPriority_Context           *ctx,
0293   RtemsIntrReqGetPriority_Pre_CanGetPriority state
0294 )
0295 {
0296   switch ( state ) {
0297     case RtemsIntrReqGetPriority_Pre_CanGetPriority_Yes: {
0298       /*
0299        * While getting the priority for the interrupt vector specified by
0300        * ``vector`` parameter is supported.
0301        */
0302       ctx->can_get_priority = true;
0303       break;
0304     }
0305 
0306     case RtemsIntrReqGetPriority_Pre_CanGetPriority_No: {
0307       /*
0308        * While getting the priority for the interrupt vector specified by
0309        * ``vector`` parameter is not supported.
0310        */
0311       ctx->can_get_priority = false;
0312       break;
0313     }
0314 
0315     case RtemsIntrReqGetPriority_Pre_CanGetPriority_NA:
0316       break;
0317   }
0318 }
0319 
0320 static void RtemsIntrReqGetPriority_Post_Status_Check(
0321   RtemsIntrReqGetPriority_Context    *ctx,
0322   RtemsIntrReqGetPriority_Post_Status state
0323 )
0324 {
0325   switch ( state ) {
0326     case RtemsIntrReqGetPriority_Post_Status_Ok: {
0327       /*
0328        * The return status of rtems_interrupt_get_priority() shall be
0329        * RTEMS_SUCCESSFUL.
0330        */
0331       ctx->expected_status = RTEMS_SUCCESSFUL;
0332       break;
0333     }
0334 
0335     case RtemsIntrReqGetPriority_Post_Status_InvAddr: {
0336       /*
0337        * The return status of rtems_interrupt_get_priority() shall be
0338        * RTEMS_INVALID_ADDRESS.
0339        */
0340       ctx->expected_status = RTEMS_INVALID_ADDRESS;
0341       break;
0342     }
0343 
0344     case RtemsIntrReqGetPriority_Post_Status_InvId: {
0345       /*
0346        * The return status of rtems_interrupt_get_priority() shall be
0347        * RTEMS_INVALID_ID.
0348        */
0349       ctx->expected_status = RTEMS_INVALID_ID;
0350       break;
0351     }
0352 
0353     case RtemsIntrReqGetPriority_Post_Status_Unsat: {
0354       /*
0355        * The return status of rtems_interrupt_get_priority() shall be
0356        * RTEMS_UNSATISFIED.
0357        */
0358       ctx->expected_status = RTEMS_UNSATISFIED;
0359       break;
0360     }
0361 
0362     case RtemsIntrReqGetPriority_Post_Status_NA:
0363       break;
0364   }
0365 }
0366 
0367 static void RtemsIntrReqGetPriority_Post_PriorityObj_Check(
0368   RtemsIntrReqGetPriority_Context         *ctx,
0369   RtemsIntrReqGetPriority_Post_PriorityObj state
0370 )
0371 {
0372   ctx->expected_priority = PriorityIsNotSet;
0373 
0374   switch ( state ) {
0375     case RtemsIntrReqGetPriority_Post_PriorityObj_Set: {
0376       /*
0377        * The value of the object referenced by the ``priority`` parameter shall
0378        * be set by the directive call to a priority which the interrupt
0379        * specified by the ``vector`` parameter had at some time point during
0380        * the directive call.
0381        */
0382       ctx->expected_priority = PriorityIsSet;
0383       break;
0384     }
0385 
0386     case RtemsIntrReqGetPriority_Post_PriorityObj_Nop: {
0387       /*
0388        * The value of the object referenced by the ``priority`` parameter shall
0389        * not be changed by the directive call.
0390        */
0391       ctx->expected_priority = PriorityIsNotSet;
0392       break;
0393     }
0394 
0395     case RtemsIntrReqGetPriority_Post_PriorityObj_NA:
0396       break;
0397   }
0398 }
0399 
0400 static void RtemsIntrReqGetPriority_Action(
0401   RtemsIntrReqGetPriority_Context *ctx
0402 )
0403 {
0404   /* Action carried out by CheckGetPriority() */
0405 }
0406 
0407 static void RtemsIntrReqGetPriority_Cleanup(
0408   RtemsIntrReqGetPriority_Context *ctx
0409 )
0410 {
0411   if ( ctx->valid_vector ) {
0412     rtems_vector_number vector;
0413 
0414     for (
0415       vector = 0;
0416       vector < BSP_INTERRUPT_VECTOR_COUNT;
0417       ++vector
0418     ) {
0419       rtems_interrupt_attributes attr;
0420       rtems_status_code          sc;
0421 
0422       memset( &attr, 0, sizeof( attr ) );
0423       sc = rtems_interrupt_get_attributes( vector, &attr );
0424 
0425       if ( sc == RTEMS_INVALID_ID ) {
0426         continue;
0427       }
0428 
0429       T_rsc_success( sc );
0430 
0431       if ( attr.can_get_priority != ctx->can_get_priority ) {
0432         continue;
0433       }
0434 
0435       CheckGetPriority( ctx, vector );
0436     }
0437   } else {
0438     CheckGetPriority( ctx, BSP_INTERRUPT_VECTOR_COUNT );
0439   }
0440 }
0441 
0442 static const RtemsIntrReqGetPriority_Entry
0443 RtemsIntrReqGetPriority_Entries[] = {
0444   { 0, 0, 0, 0, RtemsIntrReqGetPriority_Post_Status_InvAddr,
0445     RtemsIntrReqGetPriority_Post_PriorityObj_NA },
0446   { 0, 0, 0, 1, RtemsIntrReqGetPriority_Post_Status_InvId,
0447     RtemsIntrReqGetPriority_Post_PriorityObj_Nop },
0448   { 0, 0, 0, 1, RtemsIntrReqGetPriority_Post_Status_InvAddr,
0449     RtemsIntrReqGetPriority_Post_PriorityObj_NA },
0450   { 0, 0, 0, 0, RtemsIntrReqGetPriority_Post_Status_Ok,
0451     RtemsIntrReqGetPriority_Post_PriorityObj_Set },
0452   { 0, 0, 0, 0, RtemsIntrReqGetPriority_Post_Status_Unsat,
0453     RtemsIntrReqGetPriority_Post_PriorityObj_Nop }
0454 };
0455 
0456 static const uint8_t
0457 RtemsIntrReqGetPriority_Map[] = {
0458   3, 4, 0, 0, 1, 1, 2, 2
0459 };
0460 
0461 static size_t RtemsIntrReqGetPriority_Scope( void *arg, char *buf, size_t n )
0462 {
0463   RtemsIntrReqGetPriority_Context *ctx;
0464 
0465   ctx = arg;
0466 
0467   if ( ctx->Map.in_action_loop ) {
0468     return T_get_scope(
0469       RtemsIntrReqGetPriority_PreDesc,
0470       buf,
0471       n,
0472       ctx->Map.pcs
0473     );
0474   }
0475 
0476   return 0;
0477 }
0478 
0479 static T_fixture RtemsIntrReqGetPriority_Fixture = {
0480   .setup = NULL,
0481   .stop = NULL,
0482   .teardown = NULL,
0483   .scope = RtemsIntrReqGetPriority_Scope,
0484   .initial_context = &RtemsIntrReqGetPriority_Instance
0485 };
0486 
0487 static inline RtemsIntrReqGetPriority_Entry RtemsIntrReqGetPriority_PopEntry(
0488   RtemsIntrReqGetPriority_Context *ctx
0489 )
0490 {
0491   size_t index;
0492 
0493   index = ctx->Map.index;
0494   ctx->Map.index = index + 1;
0495   return RtemsIntrReqGetPriority_Entries[
0496     RtemsIntrReqGetPriority_Map[ index ]
0497   ];
0498 }
0499 
0500 static void RtemsIntrReqGetPriority_SetPreConditionStates(
0501   RtemsIntrReqGetPriority_Context *ctx
0502 )
0503 {
0504   ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0505   ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0506 
0507   if ( ctx->Map.entry.Pre_CanGetPriority_NA ) {
0508     ctx->Map.pcs[ 2 ] = RtemsIntrReqGetPriority_Pre_CanGetPriority_NA;
0509   } else {
0510     ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0511   }
0512 }
0513 
0514 static void RtemsIntrReqGetPriority_TestVariant(
0515   RtemsIntrReqGetPriority_Context *ctx
0516 )
0517 {
0518   RtemsIntrReqGetPriority_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0519   RtemsIntrReqGetPriority_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0520   RtemsIntrReqGetPriority_Pre_CanGetPriority_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0521   RtemsIntrReqGetPriority_Action( ctx );
0522   RtemsIntrReqGetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0523   RtemsIntrReqGetPriority_Post_PriorityObj_Check(
0524     ctx,
0525     ctx->Map.entry.Post_PriorityObj
0526   );
0527 }
0528 
0529 /**
0530  * @fn void T_case_body_RtemsIntrReqGetPriority( void )
0531  */
0532 T_TEST_CASE_FIXTURE(
0533   RtemsIntrReqGetPriority,
0534   &RtemsIntrReqGetPriority_Fixture
0535 )
0536 {
0537   RtemsIntrReqGetPriority_Context *ctx;
0538 
0539   ctx = T_fixture_context();
0540   ctx->Map.in_action_loop = true;
0541   ctx->Map.index = 0;
0542 
0543   for (
0544     ctx->Map.pci[ 0 ] = RtemsIntrReqGetPriority_Pre_Vector_Valid;
0545     ctx->Map.pci[ 0 ] < RtemsIntrReqGetPriority_Pre_Vector_NA;
0546     ++ctx->Map.pci[ 0 ]
0547   ) {
0548     for (
0549       ctx->Map.pci[ 1 ] = RtemsIntrReqGetPriority_Pre_Priority_Valid;
0550       ctx->Map.pci[ 1 ] < RtemsIntrReqGetPriority_Pre_Priority_NA;
0551       ++ctx->Map.pci[ 1 ]
0552     ) {
0553       for (
0554         ctx->Map.pci[ 2 ] = RtemsIntrReqGetPriority_Pre_CanGetPriority_Yes;
0555         ctx->Map.pci[ 2 ] < RtemsIntrReqGetPriority_Pre_CanGetPriority_NA;
0556         ++ctx->Map.pci[ 2 ]
0557       ) {
0558         ctx->Map.entry = RtemsIntrReqGetPriority_PopEntry( ctx );
0559         RtemsIntrReqGetPriority_SetPreConditionStates( ctx );
0560         RtemsIntrReqGetPriority_TestVariant( ctx );
0561         RtemsIntrReqGetPriority_Cleanup( ctx );
0562       }
0563     }
0564   }
0565 }
0566 
0567 /** @} */