Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup ScoreInterrValTerminate
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021, 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 <bsp.h>
0056 #include <setjmp.h>
0057 #include <string.h>
0058 #include <rtems/bspIo.h>
0059 #include <rtems/test-info.h>
0060 #include <rtems/score/atomic.h>
0061 #include <rtems/score/isrlevel.h>
0062 
0063 #include "tc-userext.h"
0064 
0065 #include <rtems/test.h>
0066 
0067 /**
0068  * @defgroup ScoreInterrValTerminate spec:/score/interr/val/terminate
0069  *
0070  * @ingroup TestsuitesTerminate
0071  *
0072  * @brief Tests system termination procedure.
0073  *
0074  * This test case performs the following actions:
0075  *
0076  * - Create five dynamic extensions.  Call the system termination procedure.
0077  *   Delete three dynamic extension during the fatal extension invocation.
0078  *   Delete the two remaining dynamic extensions.
0079  *
0080  *   - Delete the dynamic extension sets.
0081  *
0082  *   - Check that the fatal extensions were invoked with the expected source.
0083  *
0084  *   - Check that the fatal extensions were invoked with the expected always
0085  *     set to false argument.
0086  *
0087  *   - Check that the fatal extensions were invoked with the expected code.
0088  *
0089  *   - Check that the fatal extensions were invoked in forward order.
0090  *
0091  *   - Check that the fatal extension in the deleted extension set was not
0092  *     invoked.
0093  *
0094  *   - Check that maskable interrupts were enabled for the user extensions.
0095  *     Check that the idle loop executes with maskable interrupts disabled.
0096  *
0097  *   - Check that an idle loop executed after invocation of the user
0098  *     extensions.
0099  *
0100  * @{
0101  */
0102 
0103 typedef struct {
0104   unsigned int       counter;
0105   rtems_fatal_source source;
0106   bool               always_set_to_false;
0107   rtems_fatal_code   code;
0108 } FatalInfo;
0109 
0110 static Atomic_Uint counter;
0111 
0112 static FatalInfo info[ 7 ];
0113 
0114 static bool test_case_active;
0115 
0116 static const rtems_extensions_table bsp = BSP_INITIAL_EXTENSION;
0117 
0118 static jmp_buf before_terminate;
0119 
0120 static unsigned int idle_counter;
0121 
0122 static uint32_t extension_isr_level;
0123 
0124 static uint32_t idle_isr_level;
0125 
0126 static rtems_id extension_ids[ 7 ];
0127 
0128 static unsigned int GetCounter( void )
0129 {
0130   return _Atomic_Fetch_add_uint( &counter, 1, ATOMIC_ORDER_RELAXED ) + 1;
0131 }
0132 
0133 void *__real__CPU_Thread_Idle_body( void *arg );
0134 
0135 void *__wrap__CPU_Thread_Idle_body( void *arg );
0136 
0137 void *__wrap__CPU_Thread_Idle_body( void *arg )
0138 {
0139   if ( test_case_active ) {
0140     idle_counter = GetCounter();
0141     idle_isr_level = _ISR_Get_level();
0142     _ISR_Set_level( 0 );
0143     longjmp( before_terminate, 1 );
0144   } else {
0145 #if defined(RTEMS_GCOV_COVERAGE)
0146     rtems_test_gcov_dump_info();
0147 #endif
0148     return __real__CPU_Thread_Idle_body( arg );
0149   }
0150 }
0151 
0152 static void FatalExtension(
0153   rtems_fatal_source source,
0154   bool               always_set_to_false,
0155   rtems_fatal_code   code,
0156   size_t             index
0157 )
0158 {
0159   if ( test_case_active ) {
0160     info[ index ].counter = GetCounter();
0161     info[ index ].source = source;
0162     info[ index ].always_set_to_false = always_set_to_false;
0163     info[ index ].code = code;
0164   } else {
0165     ( *bsp.fatal )( source, always_set_to_false, code );
0166   }
0167 }
0168 
0169 void FatalExtension0(
0170   rtems_fatal_source source,
0171   bool               always_set_to_false,
0172   rtems_fatal_code   code
0173 )
0174 {
0175   extension_isr_level = _ISR_Get_level();
0176   FatalExtension( source, always_set_to_false, code, 0 );
0177 }
0178 
0179 void FatalExtension1(
0180   rtems_fatal_source source,
0181   bool               always_set_to_false,
0182   rtems_fatal_code   code
0183 )
0184 {
0185   FatalExtension( source, always_set_to_false, code, 1 );
0186 }
0187 
0188 static void FatalExtension2(
0189   rtems_fatal_source source,
0190   bool               always_set_to_false,
0191   rtems_fatal_code   code
0192 )
0193 {
0194   rtems_status_code     sc;
0195   rtems_interrupt_level level;
0196 
0197   FatalExtension( source, always_set_to_false, code, 2 );
0198 
0199   _ISR_Set_level( 0 );
0200   sc = rtems_extension_delete( extension_ids[ 3 ] );
0201   T_quiet_rsc_success( sc );
0202   rtems_interrupt_local_disable( level );
0203   (void) level;
0204 }
0205 
0206 static void FatalExtension3(
0207   rtems_fatal_source source,
0208   bool               always_set_to_false,
0209   rtems_fatal_code   code
0210 )
0211 {
0212   FatalExtension( source, always_set_to_false, code, 3 );
0213 }
0214 
0215 static void FatalExtension4(
0216   rtems_fatal_source source,
0217   bool               always_set_to_false,
0218   rtems_fatal_code   code
0219 )
0220 {
0221   FatalExtension( source, always_set_to_false, code, 4 );
0222 }
0223 
0224 static void FatalExtension5(
0225   rtems_fatal_source source,
0226   bool               always_set_to_false,
0227   rtems_fatal_code   code
0228 )
0229 {
0230   rtems_status_code     sc;
0231   rtems_interrupt_level level;
0232 
0233   FatalExtension( source, always_set_to_false, code, 5 );
0234 
0235   _ISR_Set_level( 0 );
0236   sc = rtems_extension_delete( extension_ids[ 5 ] );
0237   T_quiet_rsc_success( sc );
0238   rtems_interrupt_local_disable( level );
0239   (void) level;
0240 }
0241 
0242 static void FatalExtension6(
0243   rtems_fatal_source source,
0244   bool               always_set_to_false,
0245   rtems_fatal_code   code
0246 )
0247 {
0248   rtems_status_code     sc;
0249   rtems_interrupt_level level;
0250 
0251   FatalExtension( source, always_set_to_false, code, 6 );
0252 
0253   _ISR_Set_level( 0 );
0254   sc = rtems_extension_delete( extension_ids[ 4 ] );
0255   T_quiet_rsc_success( sc );
0256   rtems_interrupt_local_disable( level );
0257   (void) level;
0258 }
0259 
0260 /**
0261  * @brief Create five dynamic extensions.  Call the system termination
0262  *   procedure. Delete three dynamic extension during the fatal extension
0263  *   invocation. Delete the two remaining dynamic extensions.
0264  */
0265 static void ScoreInterrValTerminate_Action_0( void )
0266 {
0267   rtems_status_code      sc;
0268   rtems_extensions_table table;
0269   uint32_t               test_case_isr_level;
0270 
0271   memset( &table, 0, sizeof( table ) );
0272 
0273   table.fatal = FatalExtension2;
0274   sc = rtems_extension_create(
0275     rtems_build_name( ' ', ' ', ' ', '2' ),
0276     &table,
0277     &extension_ids[ 2 ]
0278   );
0279   T_step_rsc_success( 0, sc );
0280 
0281   table.fatal = FatalExtension3;
0282   sc = rtems_extension_create(
0283     rtems_build_name( ' ', ' ', ' ', '3' ),
0284     &table,
0285     &extension_ids[ 3 ]
0286   );
0287   T_step_rsc_success( 1, sc );
0288 
0289   table.fatal = FatalExtension4;
0290   sc = rtems_extension_create(
0291     rtems_build_name( ' ', ' ', ' ', '4' ),
0292     &table,
0293     &extension_ids[ 4 ]
0294   );
0295   T_step_rsc_success( 2, sc );
0296 
0297   table.fatal = FatalExtension5;
0298   sc = rtems_extension_create(
0299     rtems_build_name( ' ', ' ', ' ', '5' ),
0300     &table,
0301     &extension_ids[ 5 ]
0302   );
0303   T_step_rsc_success( 3, sc );
0304 
0305   table.fatal = FatalExtension6;
0306   sc = rtems_extension_create(
0307     rtems_build_name( ' ', ' ', ' ', '6' ),
0308     &table,
0309     &extension_ids[ 6 ]
0310   );
0311   T_step_rsc_success( 4, sc );
0312 
0313   test_case_isr_level = _ISR_Get_level();
0314   test_case_active = true;
0315 
0316   if ( setjmp( before_terminate ) == 0 ) {
0317     _Terminate( RTEMS_FATAL_SOURCE_APPLICATION, 123456 );
0318   }
0319 
0320   test_case_active = false;
0321 
0322   /*
0323    * Delete the dynamic extension sets.
0324    */
0325   sc = rtems_extension_delete( extension_ids[ 2 ] );
0326   T_step_rsc_success( 5, sc );
0327 
0328   sc = rtems_extension_delete( extension_ids[ 6 ] );
0329   T_step_rsc_success( 6, sc );
0330 
0331   /*
0332    * Check that the fatal extensions were invoked with the expected source.
0333    */
0334   T_step_eq_int(
0335     7,
0336     info[ 0 ].source,
0337     RTEMS_FATAL_SOURCE_APPLICATION
0338   );
0339   T_step_eq_int(
0340     8,
0341     info[ 1 ].source,
0342     RTEMS_FATAL_SOURCE_APPLICATION
0343   );
0344   T_step_eq_int(
0345     9,
0346     info[ 2 ].source,
0347     RTEMS_FATAL_SOURCE_APPLICATION
0348   );
0349   T_step_eq_int(
0350     10,
0351     info[ 4 ].source,
0352     RTEMS_FATAL_SOURCE_APPLICATION
0353   );
0354   T_step_eq_int(
0355     11,
0356     info[ 5 ].source,
0357     RTEMS_FATAL_SOURCE_APPLICATION
0358   );
0359   T_step_eq_int(
0360     12,
0361     info[ 6 ].source,
0362     RTEMS_FATAL_SOURCE_APPLICATION
0363   );
0364 
0365   /*
0366    * Check that the fatal extensions were invoked with the expected always set
0367    * to false argument.
0368    */
0369   T_step_false( 13, info[ 0 ].always_set_to_false );
0370   T_step_false( 14, info[ 1 ].always_set_to_false );
0371   T_step_false( 15, info[ 2 ].always_set_to_false );
0372   T_step_false( 16, info[ 4 ].always_set_to_false );
0373   T_step_false( 17, info[ 5 ].always_set_to_false );
0374   T_step_false( 18, info[ 6 ].always_set_to_false );
0375 
0376   /*
0377    * Check that the fatal extensions were invoked with the expected code.
0378    */
0379   T_step_eq_ulong( 19, info[ 0 ].code, 123456 );
0380   T_step_eq_ulong( 20, info[ 1 ].code, 123456 );
0381   T_step_eq_ulong( 21, info[ 2 ].code, 123456 );
0382   T_step_eq_ulong( 22, info[ 4 ].code, 123456 );
0383   T_step_eq_ulong( 23, info[ 5 ].code, 123456 );
0384   T_step_eq_ulong( 24, info[ 6 ].code, 123456 );
0385 
0386   /*
0387    * Check that the fatal extensions were invoked in forward order.
0388    */
0389   T_step_eq_uint( 25, info[ 0 ].counter, 1 );
0390   T_step_eq_uint( 26, info[ 1 ].counter, 2 );
0391   T_step_eq_uint( 27, info[ 2 ].counter, 3 );
0392   T_step_eq_uint( 28, info[ 4 ].counter, 4 );
0393   T_step_eq_uint( 29, info[ 5 ].counter, 5 );
0394   T_step_eq_uint( 30, info[ 6 ].counter, 6 );
0395 
0396   /*
0397    * Check that the fatal extension in the deleted extension set was not
0398    * invoked.
0399    */
0400   T_step_eq_int( 31, info[ 3 ].source, 0 );
0401   T_step_false( 32, info[ 3 ].always_set_to_false );
0402   T_step_eq_ulong( 33, info[ 3 ].code, 0 );
0403   T_step_eq_uint( 34, info[ 3 ].counter, 0 );
0404 
0405   /*
0406    * Check that maskable interrupts were enabled for the user extensions. Check
0407    * that the idle loop executes with maskable interrupts disabled.
0408    */
0409   T_step_eq_u32( 35, test_case_isr_level, 0 );
0410   T_step_ne_u32( 36, extension_isr_level, 0 );
0411   T_step_ne_u32( 37, idle_isr_level, 0 );
0412 
0413   /*
0414    * Check that an idle loop executed after invocation of the user extensions.
0415    */
0416   T_step_eq_uint( 38, idle_counter, 7 );
0417   T_step_eq_uint(
0418     39,
0419     _Atomic_Load_uint( &counter, ATOMIC_ORDER_RELAXED ),
0420     7
0421   );
0422 }
0423 
0424 /**
0425  * @fn void T_case_body_ScoreInterrValTerminate( void )
0426  */
0427 T_TEST_CASE( ScoreInterrValTerminate )
0428 {
0429   T_plan( 40 );
0430 
0431   ScoreInterrValTerminate_Action_0();
0432 }
0433 
0434 /** @} */