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 ScoreSmpValFatal
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 <setjmp.h>
0056 #include <rtems/sysinit.h>
0057 #include <rtems/score/atomic.h>
0058 #include <rtems/score/percpu.h>
0059 #include <rtems/score/smpimpl.h>
0060 
0061 #include "tr-fatal-smp.h"
0062 #include "tx-support.h"
0063 
0064 #include <rtems/test.h>
0065 
0066 /**
0067  * @defgroup ScoreSmpValFatal spec:/score/smp/val/fatal
0068  *
0069  * @ingroup TestsuitesFatalSmp
0070  *
0071  * @brief Tests four fatal errors.
0072  *
0073  * This test case performs the following actions:
0074  *
0075  * - The test action is carried out by TriggerTestCase().
0076  *
0077  *   - Check that the expected fatal source is present.
0078  *
0079  *   - Check that the expected fatal code is present.
0080  *
0081  *   - Check that the processor state is shutdown.
0082  *
0083  *   - Check that a second shutdown request does not end in a recursive
0084  *     shutdown response.
0085  *
0086  * - Issue a job on a processor in the shutdown state.  Check that the right
0087  *   fatal error occurs if we try to wait for this job to complete.
0088  *
0089  * - Start multitasking on an invalid processor.  Check that the right fatal
0090  *   error occurs.
0091  *
0092  * - Start multitasking on an unassigned processor.  Check that the right fatal
0093  *   error occurs.
0094  *
0095  * @{
0096  */
0097 
0098 /**
0099  * @brief Test context for spec:/score/smp/val/fatal test case.
0100  */
0101 typedef struct {
0102   /**
0103    * @brief This member contains a copy of the corresponding
0104    *   ScoreSmpValFatal_Run() parameter.
0105    */
0106   rtems_fatal_source source;
0107 
0108   /**
0109    * @brief This member contains a copy of the corresponding
0110    *   ScoreSmpValFatal_Run() parameter.
0111    */
0112   rtems_fatal_code code;
0113 } ScoreSmpValFatal_Context;
0114 
0115 static ScoreSmpValFatal_Context
0116   ScoreSmpValFatal_Instance;
0117 
0118 static void TriggerTestCase( void )
0119 {
0120   _SMP_Request_shutdown();
0121   (void) _CPU_Thread_Idle_body( 0 );
0122 }
0123 
0124 RTEMS_SYSINIT_ITEM(
0125   TriggerTestCase,
0126   RTEMS_SYSINIT_DEVICE_DRIVERS,
0127   RTEMS_SYSINIT_ORDER_MIDDLE
0128 );
0129 
0130 static jmp_buf fatal_before;
0131 
0132 static Atomic_Uint fatal_counter;
0133 
0134 static rtems_fatal_source fatal_source;
0135 
0136 static rtems_fatal_code fatal_code;
0137 
0138 static void FatalRecordAndJump(
0139   rtems_fatal_source source,
0140   rtems_fatal_code   code,
0141   void              *arg
0142 )
0143 {
0144   (void) arg;
0145 
0146   fatal_source = source;
0147   fatal_code = code;
0148   _Atomic_Fetch_add_uint( &fatal_counter, 1, ATOMIC_ORDER_RELAXED );
0149   _ISR_Set_level( 0 );
0150   longjmp( fatal_before, 1 );
0151 }
0152 
0153 static void DoNothing( void *arg )
0154 {
0155   (void) arg;
0156 }
0157 
0158 static const Per_CPU_Job_context job_context = {
0159   .handler = DoNothing
0160 };
0161 
0162 Per_CPU_Job job = {
0163   .context = &job_context
0164 };
0165 
0166 static T_fixture ScoreSmpValFatal_Fixture = {
0167   .setup = NULL,
0168   .stop = NULL,
0169   .teardown = NULL,
0170   .scope = NULL,
0171   .initial_context = &ScoreSmpValFatal_Instance
0172 };
0173 
0174 /**
0175  * @brief The test action is carried out by TriggerTestCase().
0176  */
0177 static void ScoreSmpValFatal_Action_0( ScoreSmpValFatal_Context *ctx )
0178 {
0179   /* Nothing to do */
0180 
0181   /*
0182    * Check that the expected fatal source is present.
0183    */
0184   T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
0185 
0186   /*
0187    * Check that the expected fatal code is present.
0188    */
0189   T_step_eq_ulong( 1, ctx->code, SMP_FATAL_SHUTDOWN_RESPONSE );
0190 
0191   /*
0192    * Check that the processor state is shutdown.
0193    */
0194   T_step_eq_int(
0195     2,
0196     _Per_CPU_Get_state( _Per_CPU_Get() ),
0197     PER_CPU_STATE_SHUTDOWN
0198   );
0199 
0200   /*
0201    * Check that a second shutdown request does not end in a recursive shutdown
0202    * response.
0203    */
0204   _SMP_Process_message( _Per_CPU_Get(), SMP_MESSAGE_SHUTDOWN );
0205 }
0206 
0207 /**
0208  * @brief Issue a job on a processor in the shutdown state.  Check that the
0209  *   right fatal error occurs if we try to wait for this job to complete.
0210  */
0211 static void ScoreSmpValFatal_Action_1( ScoreSmpValFatal_Context *ctx )
0212 {
0213   Per_CPU_Control *cpu;
0214 
0215   SetFatalHandler( FatalRecordAndJump, ctx );
0216   cpu = _Per_CPU_Get_by_index( 0 );
0217   _Per_CPU_Submit_job( cpu, &job );
0218 
0219   if ( setjmp( fatal_before ) == 0 ) {
0220     _Per_CPU_Wait_for_job( cpu, &job );
0221   }
0222 
0223   T_step_eq_uint(
0224     3,
0225     _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
0226     1
0227   );
0228   T_step_eq_int( 4, fatal_source, RTEMS_FATAL_SOURCE_SMP );
0229   T_step_eq_ulong(
0230     5,
0231     fatal_code,
0232     SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS
0233   );
0234   SetFatalHandler( NULL, NULL );
0235 }
0236 
0237 /**
0238  * @brief Start multitasking on an invalid processor.  Check that the right
0239  *   fatal error occurs.
0240  */
0241 static void ScoreSmpValFatal_Action_2( ScoreSmpValFatal_Context *ctx )
0242 {
0243   Per_CPU_Control *cpu;
0244 
0245   SetFatalHandler( FatalRecordAndJump, ctx );
0246 
0247   /*
0248    * This element is outside the array.  This is not an issue since
0249    * _SMP_Start_multitasking_on_secondary_processor() does not access the
0250    * structure.
0251    */
0252   cpu = _Per_CPU_Get_by_index( 3 );
0253 
0254   if ( setjmp( fatal_before ) == 0 ) {
0255     _SMP_Start_multitasking_on_secondary_processor( cpu );
0256   }
0257 
0258   T_step_eq_uint(
0259     6,
0260     _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
0261     2
0262   );
0263   T_step_eq_int( 7, fatal_source, RTEMS_FATAL_SOURCE_SMP );
0264   T_step_eq_ulong(
0265     8,
0266     fatal_code,
0267     SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR
0268   );
0269   SetFatalHandler( NULL, NULL );
0270 }
0271 
0272 /**
0273  * @brief Start multitasking on an unassigned processor.  Check that the right
0274  *   fatal error occurs.
0275  */
0276 static void ScoreSmpValFatal_Action_3( ScoreSmpValFatal_Context *ctx )
0277 {
0278   Per_CPU_Control *cpu;
0279 
0280   SetFatalHandler( FatalRecordAndJump, ctx );
0281   cpu = _Per_CPU_Get_by_index( 2 );
0282 
0283   if ( setjmp( fatal_before ) == 0 ) {
0284     _SMP_Start_multitasking_on_secondary_processor( cpu );
0285   }
0286 
0287   T_step_eq_uint(
0288     9,
0289     _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
0290     3
0291   );
0292   T_step_eq_int( 10, fatal_source, RTEMS_FATAL_SOURCE_SMP );
0293   T_step_eq_ulong(
0294     11,
0295     fatal_code,
0296     SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR
0297   );
0298   SetFatalHandler( NULL, NULL );
0299 }
0300 
0301 void ScoreSmpValFatal_Run( rtems_fatal_source source, rtems_fatal_code code )
0302 {
0303   ScoreSmpValFatal_Context *ctx;
0304 
0305   ctx = &ScoreSmpValFatal_Instance;
0306   ctx->source = source;
0307   ctx->code = code;
0308 
0309   ctx = T_case_begin( "ScoreSmpValFatal", &ScoreSmpValFatal_Fixture );
0310 
0311   T_plan( 12 );
0312 
0313   ScoreSmpValFatal_Action_0( ctx );
0314   ScoreSmpValFatal_Action_1( ctx );
0315   ScoreSmpValFatal_Action_2( ctx );
0316   ScoreSmpValFatal_Action_3( ctx );
0317 
0318   T_case_end();
0319 }
0320 
0321 /** @} */