diff --git a/cpukit/include/rtems/score/interr.h b/cpukit/include/rtems/score/interr.h index dcf77e99c6..2fcf241607 100644 --- a/cpukit/include/rtems/score/interr.h +++ b/cpukit/include/rtems/score/interr.h @@ -238,37 +238,68 @@ typedef enum { typedef CPU_Uint32ptr Internal_errors_t; /** - * @brief Initiates system termination. + * @brief Initiates the system termination. * - * This routine is invoked when the application or the executive itself - * determines that a fatal error has occurred or a final system state is - * reached (for example after exit()). + * This handler is invoked to terminate the system. It is called by all + * services which determine that a system termination is required. For + * example, it is called by all higher level directives which announce a fatal + * error like rtems_fatal() and exit(). + * + * The first action of the system termination handler is to disable maskable + * interrupts. This ensures that interrupts on this processor do not interfere + * with the system termination procedure. This reduces the likelihood to end + * up in a recursive system termination procedure. + * + * The second action of the system termination handler is to call the fatal + * extensions of the user extensions. + * + * The fatal extensions are called with three parameters: + * + * - the fatal source, + * + * - a legacy parameter which is always set to false, and + * + * - an error code with a fatal source dependent content. + * + * The fatal extensions of the initial extension sets are invoked first. For + * them, the following execution environment is required * - * The first action of this function is to call the fatal handler of the user - * extensions. For the initial extensions the following conditions are - * required * - a valid stack pointer and enough stack space, + * * - a valid code memory, and + * * - valid read-only data. * - * For the initial extensions the read-write data (including BSS segment) is - * not required on single processor configurations. On SMP configurations - * however the read-write data must be initialized since this function must - * determine the state of the other processors and request them to shut-down if - * necessary. + * In uniprocessor configurations, the read-write data (including ``.bss`` + * segment) is not required. In SMP configurations, however, the read-write + * data must have been initialized to determine the state of the other + * processors and request them to shut-down if necessary. The board support + * package (BSP) may install an initial extension that performs a system reset. + * See the BSP documentation in the *RTEMS User Manual* for more information + * how the system reset is done. The BSP provided fatal extension can be + * disabled by the #CONFIGURE_DISABLE_BSP_SETTINGS application configuration + * option. It is recommended to provide an application-specific fatal + * extension using the #CONFIGURE_INITIAL_EXTENSIONS application configuration + * option. * - * Non-initial extensions require in addition valid read-write data. The BSP - * may install an initial extension that performs a system reset. In this case - * the non-initial extensions will be not called. + * In certain error conditions, it may be unreliable to carry out the + * following steps of the termination procedure since the read-write data may + * be corrupt. One of the fatal extensions of the initial extension set should + * reset the system to stop the system termination procedure. * - * Once all fatal handler executed the system state is set to - * SYSTEM_STATE_TERMINATED. + * After invoking the fatal extensions of the initial extension sets, the fatal + * extensions of the dynamic extension sets are invoked. For this procedure + * valid read-write data is required. * - * The final step is to call the CPU specific _CPU_Fatal_halt(). + * The last action of the system termination handler is to execute the CPU port + * provided idle loop _CPU_Thread_Idle_body() with maskable interrupts + * disabled. Please note, that properly configured applications should not + * reach this point. * - * @param the_source The fatal source indicating the subsystem the fatal - * condition originated in. - * @param the_error The fatal error code. This value must be interpreted + * @param the_source is the fatal source indicating the subsystem the fatal + * condition originated in. + * + * @param the_error is the fatal error code. This value must be interpreted * with respect to the source. * * @see rtems_fatal() and _Internal_error(). diff --git a/cpukit/score/src/interr.c b/cpukit/score/src/interr.c index 4f180a048a..b3105c6a4d 100644 --- a/cpukit/score/src/interr.c +++ b/cpukit/score/src/interr.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -52,10 +53,21 @@ void _Terminate( Internal_errors_t the_error ) { + ISR_Level level; + _User_extensions_Fatal( the_source, the_error ); - _System_state_Set( SYSTEM_STATE_TERMINATED ); - _SMP_Request_shutdown(); - _CPU_Fatal_halt( the_source, the_error ); + + /* + * Everything after invoking the fatal extensions is essentially dead code. + * At least one fatal extension of the initial extension sets should not + * return and for example reset the system. See section "System Termination + * Procedure" in the RTEMS Classic API Guide. + * + * The following code is only executed in badly configured applications. + */ + _ISR_Local_disable( level ); + (void) level; + _CPU_Thread_Idle_body( 0 ); } void _Internal_error( Internal_errors_Core_list core_error ) diff --git a/spec/build/cpukit/optcoverageldflags.yml b/spec/build/cpukit/optcoverageldflags.yml index db5f9b85c2..ae288ac033 100644 --- a/spec/build/cpukit/optcoverageldflags.yml +++ b/spec/build/cpukit/optcoverageldflags.yml @@ -9,7 +9,6 @@ copyrights: default: - enabled-by: true value: - - -Wl,--wrap=_CPU_Fatal_halt - -Wl,--wrap=bsp_reset - -Wl,--start-group - -lrtemsbsp diff --git a/spec/build/testsuites/validation/bsps/fatal-extension.yml b/spec/build/testsuites/validation/bsps/fatal-extension.yml new file mode 100644 index 0000000000..94ed341c3b --- /dev/null +++ b/spec/build/testsuites/validation/bsps/fatal-extension.yml @@ -0,0 +1,25 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause +build-type: test-program +cflags: [] +copyrights: +- Copyright (C) 2022, 2024 embedded brains GmbH & Co. KG +cppflags: [] +cxxflags: [] +enabled-by: true +features: c cprogram +includes: [] +ldflags: +- -Wl,--wrap=bsp_reset +- -Wl,--wrap=_CPU_Thread_Idle_body +links: +- role: build-dependency + uid: objsmpshutdown +source: +- testsuites/validation/bsps/tc-fatal-extension-reset.c +- testsuites/validation/bsps/ts-fatal-extension.c +stlib: [] +target: testsuites/validation/bsps/ts-fatal-extension.exe +type: build +use-after: +- validation +use-before: [] diff --git a/spec/build/testsuites/validation/bsps/fatal-sparc-leon3-shutdown.yml b/spec/build/testsuites/validation/bsps/fatal-sparc-leon3-shutdown.yml deleted file mode 100644 index a23409a4b5..0000000000 --- a/spec/build/testsuites/validation/bsps/fatal-sparc-leon3-shutdown.yml +++ /dev/null @@ -1,24 +0,0 @@ -SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause -build-type: test-program -cflags: [] -copyrights: -- Copyright (C) 2022 embedded brains GmbH & Co. KG -cppflags: [] -cxxflags: [] -enabled-by: bsps/sparc/leon3 -features: c cprogram -includes: [] -ldflags: -- -Wl,--wrap=_CPU_Fatal_halt -links: -- role: build-dependency - uid: objsparcleon3shutdown -source: -- testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c -- testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c -stlib: [] -target: testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.exe -type: build -use-after: -- validation -use-before: [] diff --git a/spec/build/testsuites/validation/bsps/objsparcleon3shutdown.yml b/spec/build/testsuites/validation/bsps/objsmpshutdown.yml similarity index 65% rename from spec/build/testsuites/validation/bsps/objsparcleon3shutdown.yml rename to spec/build/testsuites/validation/bsps/objsmpshutdown.yml index d6da0eafdc..6450760710 100644 --- a/spec/build/testsuites/validation/bsps/objsparcleon3shutdown.yml +++ b/spec/build/testsuites/validation/bsps/objsmpshutdown.yml @@ -5,13 +5,10 @@ copyrights: - Copyright (C) 2023 embedded brains GmbH & Co. KG cppflags: [] cxxflags: [] -enabled-by: - and: - - RTEMS_SMP - - bsps/sparc/leon3 +enabled-by: RTEMS_SMP includes: [] install: [] links: [] source: -- testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c +- testsuites/validation/bsps/tc-fatal-smp-shutdown.c type: build diff --git a/spec/build/testsuites/validation/grp.yml b/spec/build/testsuites/validation/grp.yml index f10c6a9823..acf9bd2a64 100644 --- a/spec/build/testsuites/validation/grp.yml +++ b/spec/build/testsuites/validation/grp.yml @@ -80,14 +80,14 @@ links: uid: validation-tls-1 - role: build-dependency uid: bsps/fatal-clock-xil-ttc-irq-install +- role: build-dependency + uid: bsps/fatal-extension - role: build-dependency uid: bsps/fatal-sparc-leon3-cache-snooping-disabled-boot - role: build-dependency uid: bsps/fatal-sparc-leon3-cache-snooping-disabled-secondary - role: build-dependency uid: bsps/fatal-sparc-leon3-clock-initialization -- role: build-dependency - uid: bsps/fatal-sparc-leon3-shutdown - role: build-dependency uid: bsps/validation-bsp-0 type: build diff --git a/spec/build/testsuites/validation/terminate.yml b/spec/build/testsuites/validation/terminate.yml index 8b1cf12f1c..e438e1d9bc 100644 --- a/spec/build/testsuites/validation/terminate.yml +++ b/spec/build/testsuites/validation/terminate.yml @@ -9,7 +9,7 @@ enabled-by: true features: c cprogram includes: [] ldflags: -- -Wl,--wrap=_CPU_Fatal_halt +- -Wl,--wrap=_CPU_Thread_Idle_body links: [] source: - testsuites/validation/tc-terminate.c diff --git a/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c b/testsuites/validation/bsps/tc-fatal-extension-reset.c similarity index 76% rename from testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c rename to testsuites/validation/bsps/tc-fatal-extension-reset.c index 0b0b5cf5b7..d2ffd12046 100644 --- a/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c +++ b/testsuites/validation/bsps/tc-fatal-extension-reset.c @@ -3,11 +3,11 @@ /** * @file * - * @ingroup BspSparcLeon3ValFatalShutdownHalt + * @ingroup BspValFatalExtensionReset */ /* - * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG + * Copyright (C) 2021, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -59,20 +59,19 @@ #include /** - * @defgroup BspSparcLeon3ValFatalShutdownHalt \ - * spec:/bsp/sparc/leon3/val/fatal-shutdown-halt + * @defgroup BspValFatalExtensionReset spec:/bsp/val/fatal-extension-reset * - * @ingroup TestsuitesBspsFatalSparcLeon3Shutdown + * @ingroup TestsuitesBspsFatalExtension * - * @brief Tests the leon3 BSP family shutdown procedure. + * @brief Tests the BSP-specific fatal extension. * * This test case performs the following actions: * - * - Check the effects of the leon3 BSP family shutdown procedure. + * - Check the effects of the BSP-specific fatal extension. * * - Check that no dynamic fatal error extension was invoked. This shows - * that the leon3 BSP family shutdown procedure called the wrapped - * _CPU_Fatal_halt() function of the test suite. + * that the BSP-specific fatal extension called the wrapped bsp_reset() + * function of the test suite. * * @{ */ @@ -98,7 +97,7 @@ static void DynamicFatalHandler( (void) Add( &dynamic_fatal_extension_counter, 1 ); } -static void InitBspSparcLeon3ValFatalShutdownHalt( void ) +static void InitBspValFatalExtensionReset( void ) { rtems_extensions_table table = { .fatal = DynamicFatalHandler }; rtems_id id; @@ -107,22 +106,22 @@ static void InitBspSparcLeon3ValFatalShutdownHalt( void ) } RTEMS_SYSINIT_ITEM( - InitBspSparcLeon3ValFatalShutdownHalt, + InitBspValFatalExtensionReset, RTEMS_SYSINIT_DEVICE_DRIVERS, RTEMS_SYSINIT_ORDER_MIDDLE ); /** - * @brief Check the effects of the leon3 BSP family shutdown procedure. + * @brief Check the effects of the BSP-specific fatal extension. */ -static void BspSparcLeon3ValFatalShutdownHalt_Action_0( void ) +static void BspValFatalExtensionReset_Action_0( void ) { uint32_t counter; /* * Check that no dynamic fatal error extension was invoked. This shows that - * the leon3 BSP family shutdown procedure called the wrapped - * _CPU_Fatal_halt() function of the test suite. + * the BSP-specific fatal extension called the wrapped bsp_reset() function + * of the test suite. */ T_step_rsc_success( 0, status ); counter = Add( &dynamic_fatal_extension_counter, 0 ); @@ -130,13 +129,13 @@ static void BspSparcLeon3ValFatalShutdownHalt_Action_0( void ) } /** - * @fn void T_case_body_BspSparcLeon3ValFatalShutdownHalt( void ) + * @fn void T_case_body_BspValFatalExtensionReset( void ) */ -T_TEST_CASE( BspSparcLeon3ValFatalShutdownHalt ) +T_TEST_CASE( BspValFatalExtensionReset ) { T_plan( 2 ); - BspSparcLeon3ValFatalShutdownHalt_Action_0(); + BspValFatalExtensionReset_Action_0(); } /** @} */ diff --git a/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c b/testsuites/validation/bsps/tc-fatal-smp-shutdown.c similarity index 68% rename from testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c rename to testsuites/validation/bsps/tc-fatal-smp-shutdown.c index 46bc44e7cb..5a87a67f82 100644 --- a/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c +++ b/testsuites/validation/bsps/tc-fatal-smp-shutdown.c @@ -3,11 +3,11 @@ /** * @file * - * @ingroup BspSparcLeon3ValFatalShutdownRequest + * @ingroup BspValFatalSmpShutdown */ /* - * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG + * Copyright (C) 2021, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -52,7 +52,6 @@ #include "config.h" #endif -#include #include #include @@ -61,21 +60,17 @@ #include /** - * @defgroup BspSparcLeon3ValFatalShutdownRequest \ - * spec:/bsp/sparc/leon3/val/fatal-shutdown-request + * @defgroup BspValFatalSmpShutdown spec:/bsp/val/fatal-smp-shutdown * - * @ingroup TestsuitesBspsFatalSparcLeon3Shutdown + * @ingroup TestsuitesBspsFatalExtension * - * @brief Tests the leon3 BSP family SMP-specific shutdown procedure. + * @brief Tests the BSP-specific fatal extension shutdown procedure. * * This test case performs the following actions: * - * - Check the effects of the leon3 BSP family shutdown procedure. + * - Check the effects of the BSP-specific fatal extension. * - * - Check that the second processor was not powered down during system - * initialization. - * - * - Wait until the second processor is powered down. + * - Wait until the second processor is idle. * * - Check that the RTEMS_FATAL_SOURCE_SMP with SMP_FATAL_SHUTDOWN_RESPONSE * fatal error occurred exactly once. @@ -86,8 +81,6 @@ * @{ */ -static uint32_t mpstat_during_sysinit; - static Atomic_Uint shutdown_response_counter; static uint32_t shutdown_response_cpu_index = UINT32_MAX; @@ -114,66 +107,65 @@ static void ShutdownFatalHandler( } } -static void InitBspSparcLeon3ValFatalShutdownRequest( void ) +static void InitBspValFatalSmpShutdown( void ) { - irqamp *regs; - - regs = LEON3_IrqCtrl_Regs; - mpstat_during_sysinit = grlib_load_32( ®s->mpstat ); SetFatalHandler( ShutdownFatalHandler, NULL ); } RTEMS_SYSINIT_ITEM( - InitBspSparcLeon3ValFatalShutdownRequest, + InitBspValFatalSmpShutdown, RTEMS_SYSINIT_DEVICE_DRIVERS, RTEMS_SYSINIT_ORDER_MIDDLE ); -/** - * @brief Check the effects of the leon3 BSP family shutdown procedure. - */ -static void BspSparcLeon3ValFatalShutdownRequest_Action_0( void ) +static Atomic_Uint idle_counter; + +void *__real__CPU_Thread_Idle_body( void *arg ); + +void *__wrap__CPU_Thread_Idle_body( void *arg ); + +void *__wrap__CPU_Thread_Idle_body( void *arg ) { - irqamp *regs; - uint32_t counter; + (void) Add( &idle_counter, 1 ); + return __real__CPU_Thread_Idle_body( arg ); +} - regs = LEON3_IrqCtrl_Regs; +/** + * @brief Check the effects of the BSP-specific fatal extension. + */ +static void BspValFatalSmpShutdown_Action_0( void ) +{ + unsigned int counter; /* - * Check that the second processor was not powered down during system - * initialization. + * Wait until the second processor is idle. */ - T_step_eq_u32( 0, mpstat_during_sysinit & 0x2, 0 ); - - /* - * Wait until the second processor is powered down. - */ - while ( ( grlib_load_32( ®s->mpstat ) & 0x2 ) != 0x2U ) { - /* Wait */ - } + do { + counter = _Atomic_Load_uint( &idle_counter, ATOMIC_ORDER_RELAXED ); + } while ( counter != 2U ); /* * Check that the RTEMS_FATAL_SOURCE_SMP with SMP_FATAL_SHUTDOWN_RESPONSE * fatal error occurred exactly once. */ counter = Add( &shutdown_response_counter, 0 ); - T_step_eq_uint( 1, counter, 1 ); + T_step_eq_uint( 0, counter, 1 ); /* * Check that the RTEMS_FATAL_SOURCE_SMP with SMP_FATAL_SHUTDOWN_RESPONSE * fatal error occurred on the second processor. */ - T_step_eq_u32( 2, shutdown_response_cpu_index, 1 ); + T_step_eq_u32( 1, shutdown_response_cpu_index, 1 ); } /** - * @fn void T_case_body_BspSparcLeon3ValFatalShutdownRequest( void ) + * @fn void T_case_body_BspValFatalSmpShutdown( void ) */ -T_TEST_CASE( BspSparcLeon3ValFatalShutdownRequest ) +T_TEST_CASE( BspValFatalSmpShutdown ) { - T_plan( 3 ); + T_plan( 2 ); - BspSparcLeon3ValFatalShutdownRequest_Action_0(); + BspValFatalSmpShutdown_Action_0(); } /** @} */ diff --git a/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c b/testsuites/validation/bsps/ts-fatal-extension.c similarity index 87% rename from testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c rename to testsuites/validation/bsps/ts-fatal-extension.c index bc229e7824..395b001af5 100644 --- a/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c +++ b/testsuites/validation/bsps/ts-fatal-extension.c @@ -3,7 +3,7 @@ /** * @file * - * @ingroup TestsuitesBspsFatalSparcLeon3Shutdown + * @ingroup TestsuitesBspsFatalExtension */ /* @@ -65,8 +65,7 @@ #include /** - * @defgroup TestsuitesBspsFatalSparcLeon3Shutdown \ - * spec:/testsuites/bsps/fatal-sparc-leon3-shutdown + * @defgroup TestsuitesBspsFatalExtension spec:/testsuites/bsps/fatal-extension * * @ingroup RTEMSTestSuitesValidation * @@ -76,7 +75,7 @@ * @{ */ -const char rtems_test_name[] = "TestsuitesBspsFatalSparcLeon3Shutdown"; +const char rtems_test_name[] = "TestsuitesBspsFatalExtension"; static char buffer[ 512 ]; @@ -97,11 +96,11 @@ static const T_config test_config = { .actions = actions }; -void __real__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code ); +void __real_bsp_reset( rtems_fatal_source source, rtems_fatal_code code ); -void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code ); +void __wrap_bsp_reset( rtems_fatal_source source, rtems_fatal_code code ); -void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code ) +void __wrap_bsp_reset( rtems_fatal_source source, rtems_fatal_code code ) { int exit_code; @@ -115,9 +114,20 @@ void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code ) #if defined(RTEMS_GCOV_COVERAGE) rtems_test_gcov_dump_info(); #endif - __real__CPU_Fatal_halt( source, code ); + __real_bsp_reset( source, code ); } +#if !defined(RTEMS_SMP) +void *__real__CPU_Thread_Idle_body( void *arg ); + +void *__wrap__CPU_Thread_Idle_body( void *arg ); + +void *__wrap__CPU_Thread_Idle_body( void *arg ) +{ + return __real__CPU_Thread_Idle_body( arg ); +} +#endif + #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER #if defined(RTEMS_SMP) diff --git a/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown-response.c b/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown-response.c deleted file mode 100644 index d730b6d027..0000000000 --- a/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown-response.c +++ /dev/null @@ -1,94 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ - -/** - * @file - * - * @ingroup RTEMSTestSuiteTestsuitesFatalBspSparcLeon3ShutdownResponse - */ - -/* - * Copyright (C) 2021 embedded brains GmbH & Co. KG - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This file is part of the RTEMS quality process and was automatically - * generated. If you find something that needs to be fixed or - * worded better please post a report or patch to an RTEMS mailing list - * or raise a bug report: - * - * https://www.rtems.org/bugs.html - * - * For information on updating and regenerating please refer to the How-To - * section in the Software Requirements Engineering chapter of the - * RTEMS Software Engineering manual. The manual is provided as a part of - * a release. For development sources please refer to the online - * documentation at: - * - * https://docs.rtems.org - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "tr-fatal-sparc-leon3-shutdown-response.h" - -#include - -/** - * @defgroup RTEMSTestSuiteTestsuitesFatalBspSparcLeon3ShutdownResponse \ - * spec:/testsuites/fatal-sparc-leon3-shutdown-response - * - * @ingroup RTEMSTestSuitesValidation - * - * @brief This validation test suite contains a test case which performs a - * system shutdown. - * - * @{ - */ - -const char rtems_test_name[] = "FatalBspSparcLeon3ShutdownResponse"; - -#define FATAL_SYSINIT_RUN BspSparcLeon3ValFatalShutdownResponse_Run - -static void FatalSysinitExit( rtems_fatal_code exit_code ) -{ - if ( exit_code == 0 ) { - rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN ); - } else { - rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, exit_code ); - } -} - -#define FATAL_SYSINIT_EXIT( exit_code ) FatalSysinitExit( exit_code ) - -#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER - -#define CONFIGURE_MAXIMUM_PROCESSORS 2 - -#include "ts-fatal-sysinit.h" - -/** @} */ diff --git a/testsuites/validation/tc-terminate.c b/testsuites/validation/tc-terminate.c index b533092c19..f26aae3e6d 100644 --- a/testsuites/validation/tc-terminate.c +++ b/testsuites/validation/tc-terminate.c @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2021, 2024 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -58,8 +58,7 @@ #include #include #include -#include -#include +#include #include "tc-userext.h" @@ -78,9 +77,6 @@ * Delete three dynamic extension during the fatal extension invocation. * Delete the two remaining dynamic extensions. * - * - Where the system was built with SMP support enabled, check that a - * shutdown request was issued. - * * - Delete the dynamic extension sets. * * - Check that the fatal extensions were invoked with the expected source. @@ -95,13 +91,11 @@ * - Check that the fatal extension in the deleted extension set was not * invoked. * - * - Check that the system state is terminated. + * - Check that maskable interrupts were enabled for the user extensions. + * Check that the idle loop executes with maskable interrupts disabled. * - * - Check that the system was halted with the expected fatal source. - * - * - Check that the system was halted with the expected fatal code. - * - * - Check that the system was finally halted. + * - Check that an idle loop executed after invocation of the user + * extensions. * * @{ */ @@ -123,11 +117,11 @@ static const rtems_extensions_table bsp = BSP_INITIAL_EXTENSION; static jmp_buf before_terminate; -static unsigned int halt_counter; +static unsigned int idle_counter; -static rtems_fatal_source halt_source; +static uint32_t extension_isr_level; -static rtems_fatal_code halt_code; +static uint32_t idle_isr_level; static rtems_id extension_ids[ 7 ]; @@ -136,22 +130,22 @@ static unsigned int GetCounter( void ) return _Atomic_Fetch_add_uint( &counter, 1, ATOMIC_ORDER_RELAXED ) + 1; } -void __real__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code ); +void *__real__CPU_Thread_Idle_body( void *arg ); -void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code ); +void *__wrap__CPU_Thread_Idle_body( void *arg ); -void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code ) +void *__wrap__CPU_Thread_Idle_body( void *arg ) { if ( test_case_active ) { - halt_counter = GetCounter(); - halt_source = source; - halt_code = code; + idle_counter = GetCounter(); + idle_isr_level = _ISR_Get_level(); + _ISR_Set_level( 0 ); longjmp( before_terminate, 1 ); } else { #if defined(RTEMS_GCOV_COVERAGE) rtems_test_gcov_dump_info(); #endif - __real__CPU_Fatal_halt( source, code ); + return __real__CPU_Thread_Idle_body( arg ); } } @@ -178,6 +172,7 @@ void FatalExtension0( rtems_fatal_code code ) { + extension_isr_level = _ISR_Get_level(); FatalExtension( source, always_set_to_false, code, 0 ); } @@ -259,14 +254,6 @@ static void ScoreInterrValTerminate_Action_0( void ) { rtems_status_code sc; rtems_extensions_table table; - bool shutdown_ok; - - #if defined(RTEMS_SMP) - shutdown_ok = - ( _Per_CPU_Get_state( _Per_CPU_Get_snapshot() ) == PER_CPU_STATE_UP ); - #else - shutdown_ok = true; - #endif memset( &table, 0, sizeof( table ) ); @@ -318,56 +305,45 @@ static void ScoreInterrValTerminate_Action_0( void ) test_case_active = false; - /* - * Where the system was built with SMP support enabled, check that a shutdown - * request was issued. - */ - #if defined(RTEMS_SMP) - shutdown_ok = ( shutdown_ok && _ISR_Get_level() != 0 && - _Per_CPU_Get_state( _Per_CPU_Get() ) == PER_CPU_STATE_SHUTDOWN ); - _ISR_Set_level( 0 ); - #endif - T_step_true( 5, shutdown_ok ); - /* * Delete the dynamic extension sets. */ sc = rtems_extension_delete( extension_ids[ 2 ] ); - T_step_rsc_success( 6, sc ); + T_step_rsc_success( 5, sc ); sc = rtems_extension_delete( extension_ids[ 6 ] ); - T_step_rsc_success( 7, sc ); + T_step_rsc_success( 6, sc ); /* * Check that the fatal extensions were invoked with the expected source. */ T_step_eq_int( - 8, + 7, info[ 0 ].source, RTEMS_FATAL_SOURCE_APPLICATION ); T_step_eq_int( - 9, + 8, info[ 1 ].source, RTEMS_FATAL_SOURCE_APPLICATION ); T_step_eq_int( - 10, + 9, info[ 2 ].source, RTEMS_FATAL_SOURCE_APPLICATION ); T_step_eq_int( - 11, + 10, info[ 4 ].source, RTEMS_FATAL_SOURCE_APPLICATION ); T_step_eq_int( - 12, + 11, info[ 5 ].source, RTEMS_FATAL_SOURCE_APPLICATION ); T_step_eq_int( - 13, + 12, info[ 6 ].source, RTEMS_FATAL_SOURCE_APPLICATION ); @@ -376,61 +352,58 @@ static void ScoreInterrValTerminate_Action_0( void ) * Check that the fatal extensions were invoked with the expected always set * to false argument. */ - T_step_false( 14, info[ 0 ].always_set_to_false ); - T_step_false( 15, info[ 1 ].always_set_to_false ); - T_step_false( 16, info[ 2 ].always_set_to_false ); - T_step_false( 17, info[ 4 ].always_set_to_false ); - T_step_false( 18, info[ 5 ].always_set_to_false ); - T_step_false( 19, info[ 6 ].always_set_to_false ); + T_step_false( 13, info[ 0 ].always_set_to_false ); + T_step_false( 14, info[ 1 ].always_set_to_false ); + T_step_false( 15, info[ 2 ].always_set_to_false ); + T_step_false( 16, info[ 4 ].always_set_to_false ); + T_step_false( 17, info[ 5 ].always_set_to_false ); + T_step_false( 18, info[ 6 ].always_set_to_false ); /* * Check that the fatal extensions were invoked with the expected code. */ - T_step_eq_ulong( 20, info[ 0 ].code, 123456 ); - T_step_eq_ulong( 21, info[ 1 ].code, 123456 ); - T_step_eq_ulong( 22, info[ 2 ].code, 123456 ); - T_step_eq_ulong( 23, info[ 4 ].code, 123456 ); - T_step_eq_ulong( 24, info[ 5 ].code, 123456 ); - T_step_eq_ulong( 25, info[ 6 ].code, 123456 ); + T_step_eq_ulong( 19, info[ 0 ].code, 123456 ); + T_step_eq_ulong( 20, info[ 1 ].code, 123456 ); + T_step_eq_ulong( 21, info[ 2 ].code, 123456 ); + T_step_eq_ulong( 22, info[ 4 ].code, 123456 ); + T_step_eq_ulong( 23, info[ 5 ].code, 123456 ); + T_step_eq_ulong( 24, info[ 6 ].code, 123456 ); /* * Check that the fatal extensions were invoked in forward order. */ - T_step_eq_uint( 26, info[ 0 ].counter, 1 ); - T_step_eq_uint( 27, info[ 1 ].counter, 2 ); - T_step_eq_uint( 28, info[ 2 ].counter, 3 ); - T_step_eq_uint( 29, info[ 4 ].counter, 4 ); - T_step_eq_uint( 30, info[ 5 ].counter, 5 ); - T_step_eq_uint( 31, info[ 6 ].counter, 6 ); + T_step_eq_uint( 25, info[ 0 ].counter, 1 ); + T_step_eq_uint( 26, info[ 1 ].counter, 2 ); + T_step_eq_uint( 27, info[ 2 ].counter, 3 ); + T_step_eq_uint( 28, info[ 4 ].counter, 4 ); + T_step_eq_uint( 29, info[ 5 ].counter, 5 ); + T_step_eq_uint( 30, info[ 6 ].counter, 6 ); /* * Check that the fatal extension in the deleted extension set was not * invoked. */ - T_step_eq_int( 32, info[ 3 ].source, 0 ); - T_step_false( 33, info[ 3 ].always_set_to_false ); - T_step_eq_ulong( 34, info[ 3 ].code, 0 ); - T_step_eq_uint( 35, info[ 3 ].counter, 0 ); + T_step_eq_int( 31, info[ 3 ].source, 0 ); + T_step_false( 32, info[ 3 ].always_set_to_false ); + T_step_eq_ulong( 33, info[ 3 ].code, 0 ); + T_step_eq_uint( 34, info[ 3 ].counter, 0 ); /* - * Check that the system state is terminated. + * Check that maskable interrupts were enabled for the user extensions. Check + * that the idle loop executes with maskable interrupts disabled. */ - T_step_eq_int( 36, _System_state_Get(), SYSTEM_STATE_TERMINATED ); + T_step_eq_u32( 35, extension_isr_level, 0 ); + T_step_ne_u32( 36, idle_isr_level, 0 ); /* - * Check that the system was halted with the expected fatal source. + * Check that an idle loop executed after invocation of the user extensions. */ - T_step_eq_int( 37, halt_source, RTEMS_FATAL_SOURCE_APPLICATION ); - - /* - * Check that the system was halted with the expected fatal code. - */ - T_step_eq_ulong( 38, halt_code, 123456 ); - - /* - * Check that the system was finally halted. - */ - T_step_eq_uint( 39, counter, 7 ); + T_step_eq_uint( 37, idle_counter, 7 ); + T_step_eq_uint( + 38, + _Atomic_Load_uint( &counter, ATOMIC_ORDER_RELAXED ), + 7 + ); } /** @@ -438,7 +411,7 @@ static void ScoreInterrValTerminate_Action_0( void ) */ T_TEST_CASE( ScoreInterrValTerminate ) { - T_plan( 40 ); + T_plan( 39 ); ScoreInterrValTerminate_Action_0(); }