From aebf6b661954b4b0ca65342af504b41631bdef78 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 2 Sep 2021 15:29:10 +0200 Subject: validation: Test Interrupt Manager The test source code is generated from specification items by the "./spec2modules.py" script contained in the git://git.rtems.org/rtems-central.git Git repository. Please read the "How-To" section in the "Software Requirements Engineering" chapter of the RTEMS Software Engineering manual to get more information about the process. Update #3716. --- testsuites/validation/tc-bsp-interrupt-spurious.c | 538 ++++++++++++++++++++++ testsuites/validation/tc-intr-clear.c | 39 +- testsuites/validation/tc-intr-entry-install.c | 226 ++++++--- testsuites/validation/tc-intr-entry-remove.c | 133 ++++-- testsuites/validation/tc-intr-get-affinity.c | 53 ++- testsuites/validation/tc-intr-get-attributes.c | 2 +- testsuites/validation/tc-intr-handler-iterate.c | 2 +- testsuites/validation/tc-intr-is-pending.c | 87 ++-- testsuites/validation/tc-intr-non-smp.c | 171 +++++++ testsuites/validation/tc-intr-raise-on.c | 70 +-- testsuites/validation/tc-intr-raise.c | 63 ++- testsuites/validation/tc-intr-set-affinity.c | 276 ++++++++--- testsuites/validation/tc-intr-smp-only.c | 226 +++++++++ testsuites/validation/tc-intr-vector-disable.c | 56 ++- testsuites/validation/tc-intr-vector-enable.c | 56 ++- testsuites/validation/tc-intr-vector-is-enabled.c | 46 +- testsuites/validation/tc-intr.c | 286 ++++++++++++ testsuites/validation/ts-validation-intr.c | 81 ++++ 18 files changed, 2081 insertions(+), 330 deletions(-) create mode 100644 testsuites/validation/tc-bsp-interrupt-spurious.c create mode 100644 testsuites/validation/tc-intr-non-smp.c create mode 100644 testsuites/validation/tc-intr-smp-only.c create mode 100644 testsuites/validation/tc-intr.c create mode 100644 testsuites/validation/ts-validation-intr.c (limited to 'testsuites/validation') diff --git a/testsuites/validation/tc-bsp-interrupt-spurious.c b/testsuites/validation/tc-bsp-interrupt-spurious.c new file mode 100644 index 0000000000..de139337da --- /dev/null +++ b/testsuites/validation/tc-bsp-interrupt-spurious.c @@ -0,0 +1,538 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseBspReqInterruptSpurious + */ + +/* + * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * + * 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 + +#include "tx-support.h" + +#include + +/** + * @defgroup RTEMSTestCaseBspReqInterruptSpurious \ + * spec:/bsp/req/interrupt-spurious + * + * @ingroup RTEMSTestSuiteTestsuitesValidationSmpOnly0 + * + * @{ + */ + +typedef enum { + BspReqInterruptSpurious_Pre_First_Null, + BspReqInterruptSpurious_Pre_First_Entry, + BspReqInterruptSpurious_Pre_First_NA +} BspReqInterruptSpurious_Pre_First; + +typedef enum { + BspReqInterruptSpurious_Post_Result_FatalError, + BspReqInterruptSpurious_Post_Result_Dispatch, + BspReqInterruptSpurious_Post_Result_NA +} BspReqInterruptSpurious_Post_Result; + +typedef enum { + BspReqInterruptSpurious_Post_FatalSource_SpuriousInterrupt, + BspReqInterruptSpurious_Post_FatalSource_NA +} BspReqInterruptSpurious_Post_FatalSource; + +typedef enum { + BspReqInterruptSpurious_Post_FatalCode_Vector, + BspReqInterruptSpurious_Post_FatalCode_NA +} BspReqInterruptSpurious_Post_FatalCode; + +typedef struct { + uint8_t Skip : 1; + uint8_t Pre_First_NA : 1; + uint8_t Post_Result : 2; + uint8_t Post_FatalSource : 1; + uint8_t Post_FatalCode : 1; +} BspReqInterruptSpurious_Entry; + +/** + * @brief Test context for spec:/bsp/req/interrupt-spurious test case. + */ +typedef struct { + /** + * @brief This member provides a jump buffer to return from the fatal error. + */ + jmp_buf before_call; + + /** + * @brief This member provides an interrupt entry to be dispatched. + */ + rtems_interrupt_entry entry; + + /** + * @brief If this member is true, then the interrupt shall be cleared. + */ + bool do_clear; + + /** + * @brief This member is true, then an interrupt occurred. + */ + volatile bool interrupt_occurred; + + /** + * @brief This member provides an entry dispatch counter. + */ + uint32_t entry_counter; + + /** + * @brief This member provides a fatal error counter. + */ + uint32_t fatal_counter; + + /** + * @brief This member contains the fatal source. + */ + rtems_fatal_source fatal_source; + + /** + * @brief This member contains a fatal code. + */ + rtems_fatal_code fatal_code; + + /** + * @brief This member contains the vector number of a testable interrupt. + */ + rtems_vector_number test_vector; + + /** + * @brief This member references the pointer to the first entry of the + * interrupt vector. + */ + rtems_interrupt_entry **first; + + struct { + /** + * @brief This member defines the pre-condition states for the next action. + */ + size_t pcs[ 1 ]; + + /** + * @brief If this member is true, then the test action loop is executed. + */ + bool in_action_loop; + + /** + * @brief This member contains the next transition map index. + */ + size_t index; + + /** + * @brief This member contains the current transition map entry. + */ + BspReqInterruptSpurious_Entry entry; + + /** + * @brief If this member is true, then the current transition variant + * should be skipped. + */ + bool skip; + } Map; +} BspReqInterruptSpurious_Context; + +static BspReqInterruptSpurious_Context + BspReqInterruptSpurious_Instance; + +static const char * const BspReqInterruptSpurious_PreDesc_First[] = { + "Null", + "Entry", + "NA" +}; + +static const char * const * const BspReqInterruptSpurious_PreDesc[] = { + BspReqInterruptSpurious_PreDesc_First, + NULL +}; + +typedef BspReqInterruptSpurious_Context Context; + +static bool test_case_active; + +static void Disable( const Context *ctx ) +{ + (void) rtems_interrupt_vector_disable( ctx->test_vector ); +} + +static void ProcessInterrupt( Context *ctx ) +{ + ctx->interrupt_occurred = true; + + if ( ctx->do_clear ) { + rtems_status_code sc; + + sc = rtems_interrupt_clear( ctx->test_vector ); + T_rsc_success( sc ); + } + + Disable( ctx ); +} + +static void EntryRoutine( void *arg ) +{ + Context *ctx; + + ctx = arg; + ++ctx->entry_counter; + ProcessInterrupt( ctx ); +} + +static void Fatal( + rtems_fatal_source source, + rtems_fatal_code code, + void *arg +) +{ + Context *ctx; + + ctx = arg; + ctx->fatal_source = source; + ctx->fatal_code = code; + ++ctx->fatal_counter; + longjmp( ctx->before_call, 1 ); +} + +void __real_bsp_interrupt_handler_default( rtems_vector_number vector ); + +void __wrap_bsp_interrupt_handler_default( rtems_vector_number vector ); + +void __wrap_bsp_interrupt_handler_default( rtems_vector_number vector ) +{ + if ( test_case_active ) { + Context *ctx; + + ctx = T_fixture_context(); + ProcessInterrupt( ctx ); + + if ( setjmp( ctx->before_call ) == 0 ) { + __real_bsp_interrupt_handler_default( vector ); + } + } else { + __real_bsp_interrupt_handler_default( vector ); + } +} + +static void BspReqInterruptSpurious_Pre_First_Prepare( + BspReqInterruptSpurious_Context *ctx, + BspReqInterruptSpurious_Pre_First state +) +{ + switch ( state ) { + case BspReqInterruptSpurious_Pre_First_Null: { + /* + * While the pointer to the first interrupt entry of the interrupt vector + * specified by the ``vector`` parameter is equal to NULL. + */ + *ctx->first = NULL; + break; + } + + case BspReqInterruptSpurious_Pre_First_Entry: { + /* + * While the pointer to the first interrupt entry of the interrupt vector + * specified by the ``vector`` parameter references an object of type + * rtems_interrupt_entry. + */ + *ctx->first = &ctx->entry; + break; + } + + case BspReqInterruptSpurious_Pre_First_NA: + break; + } +} + +static void BspReqInterruptSpurious_Post_Result_Check( + BspReqInterruptSpurious_Context *ctx, + BspReqInterruptSpurious_Post_Result state +) +{ + switch ( state ) { + case BspReqInterruptSpurious_Post_Result_FatalError: { + /* + * A fatal error shall occur. + */ + T_eq_u32( ctx->entry_counter, 0 ); + T_eq_u32( ctx->fatal_counter, 1 ); + break; + } + + case BspReqInterruptSpurious_Post_Result_Dispatch: { + /* + * The interrupt entries installed at the interrupt vector specified by + * the ``vector`` parameter shall be dispatched. + */ + T_eq_u32( ctx->entry_counter, 1 ); + T_eq_u32( ctx->fatal_counter, 0 ); + break; + } + + case BspReqInterruptSpurious_Post_Result_NA: + break; + } +} + +static void BspReqInterruptSpurious_Post_FatalSource_Check( + BspReqInterruptSpurious_Context *ctx, + BspReqInterruptSpurious_Post_FatalSource state +) +{ + switch ( state ) { + case BspReqInterruptSpurious_Post_FatalSource_SpuriousInterrupt: { + /* + * The fatal source shall be equal to + * RTEMS_FATAL_SOURCE_SPURIOUS_INTERRUPT. + */ + T_eq_int( ctx->fatal_source, RTEMS_FATAL_SOURCE_SPURIOUS_INTERRUPT ); + break; + } + + case BspReqInterruptSpurious_Post_FatalSource_NA: + break; + } +} + +static void BspReqInterruptSpurious_Post_FatalCode_Check( + BspReqInterruptSpurious_Context *ctx, + BspReqInterruptSpurious_Post_FatalCode state +) +{ + switch ( state ) { + case BspReqInterruptSpurious_Post_FatalCode_Vector: { + /* + * The fatal code shall be equal to the ``vector`` parameter. + */ + T_eq_ulong( ctx->fatal_code, ctx->test_vector ); + break; + } + + case BspReqInterruptSpurious_Post_FatalCode_NA: + break; + } +} + +static void BspReqInterruptSpurious_Setup( + BspReqInterruptSpurious_Context *ctx +) +{ + rtems_interrupt_attributes attr = { + .can_raise = true + }; + rtems_status_code sc; + + ctx->test_vector = GetTestableInterruptVector( &attr ); + T_assert_lt_u32( ctx->test_vector, BSP_INTERRUPT_VECTOR_COUNT ); + ctx->first = &bsp_interrupt_handler_table[ + bsp_interrupt_handler_index( ctx->test_vector ) + ]; + + sc = rtems_interrupt_get_attributes( ctx->test_vector, &attr ); + T_rsc_success( sc ); + ctx->do_clear = attr.can_clear && !attr.cleared_by_acknowledge; + + rtems_interrupt_entry_initialize( &ctx->entry, EntryRoutine, ctx, "Info" ); + test_case_active = true; + SetFatalHandler( Fatal, ctx ); +} + +static void BspReqInterruptSpurious_Setup_Wrap( void *arg ) +{ + BspReqInterruptSpurious_Context *ctx; + + ctx = arg; + ctx->Map.in_action_loop = false; + BspReqInterruptSpurious_Setup( ctx ); +} + +static void BspReqInterruptSpurious_Teardown( + BspReqInterruptSpurious_Context *ctx +) +{ + SetFatalHandler( NULL, NULL ); + test_case_active = false; +} + +static void BspReqInterruptSpurious_Teardown_Wrap( void *arg ) +{ + BspReqInterruptSpurious_Context *ctx; + + ctx = arg; + ctx->Map.in_action_loop = false; + BspReqInterruptSpurious_Teardown( ctx ); +} + +static void BspReqInterruptSpurious_Action( + BspReqInterruptSpurious_Context *ctx +) +{ + ctx->interrupt_occurred = false; + ctx->entry_counter = 0; + ctx->fatal_counter = 0; + ctx->fatal_source = RTEMS_FATAL_SOURCE_LAST; + ctx->fatal_code = UINT32_MAX; + + if ( *ctx->first == NULL ) { + rtems_status_code sc; + + (void) rtems_interrupt_vector_enable( ctx->test_vector ); + + sc = rtems_interrupt_raise( ctx->test_vector ); + T_rsc_success( sc ); + + while ( !ctx->interrupt_occurred ) { + /* Wait */ + } + + Disable( ctx ); + } else { + bsp_interrupt_spurious( ctx->test_vector ); + } +} + +static const BspReqInterruptSpurious_Entry +BspReqInterruptSpurious_Entries[] = { + { 0, 0, BspReqInterruptSpurious_Post_Result_FatalError, + BspReqInterruptSpurious_Post_FatalSource_SpuriousInterrupt, + BspReqInterruptSpurious_Post_FatalCode_Vector }, + { 0, 0, BspReqInterruptSpurious_Post_Result_Dispatch, + BspReqInterruptSpurious_Post_FatalSource_NA, + BspReqInterruptSpurious_Post_FatalCode_NA } +}; + +static const uint8_t +BspReqInterruptSpurious_Map[] = { + 0, 1 +}; + +static size_t BspReqInterruptSpurious_Scope( void *arg, char *buf, size_t n ) +{ + BspReqInterruptSpurious_Context *ctx; + + ctx = arg; + + if ( ctx->Map.in_action_loop ) { + return T_get_scope( + BspReqInterruptSpurious_PreDesc, + buf, + n, + ctx->Map.pcs + ); + } + + return 0; +} + +static T_fixture BspReqInterruptSpurious_Fixture = { + .setup = BspReqInterruptSpurious_Setup_Wrap, + .stop = NULL, + .teardown = BspReqInterruptSpurious_Teardown_Wrap, + .scope = BspReqInterruptSpurious_Scope, + .initial_context = &BspReqInterruptSpurious_Instance +}; + +static inline BspReqInterruptSpurious_Entry BspReqInterruptSpurious_PopEntry( + BspReqInterruptSpurious_Context *ctx +) +{ + size_t index; + + index = ctx->Map.index; + ctx->Map.index = index + 1; + return BspReqInterruptSpurious_Entries[ + BspReqInterruptSpurious_Map[ index ] + ]; +} + +static void BspReqInterruptSpurious_TestVariant( + BspReqInterruptSpurious_Context *ctx +) +{ + BspReqInterruptSpurious_Pre_First_Prepare( ctx, ctx->Map.pcs[ 0 ] ); + BspReqInterruptSpurious_Action( ctx ); + BspReqInterruptSpurious_Post_Result_Check( ctx, ctx->Map.entry.Post_Result ); + BspReqInterruptSpurious_Post_FatalSource_Check( + ctx, + ctx->Map.entry.Post_FatalSource + ); + BspReqInterruptSpurious_Post_FatalCode_Check( + ctx, + ctx->Map.entry.Post_FatalCode + ); +} + +/** + * @fn void T_case_body_BspReqInterruptSpurious( void ) + */ +T_TEST_CASE_FIXTURE( + BspReqInterruptSpurious, + &BspReqInterruptSpurious_Fixture +) +{ + BspReqInterruptSpurious_Context *ctx; + + ctx = T_fixture_context(); + ctx->Map.in_action_loop = true; + ctx->Map.index = 0; + + for ( + ctx->Map.pcs[ 0 ] = BspReqInterruptSpurious_Pre_First_Null; + ctx->Map.pcs[ 0 ] < BspReqInterruptSpurious_Pre_First_NA; + ++ctx->Map.pcs[ 0 ] + ) { + ctx->Map.entry = BspReqInterruptSpurious_PopEntry( ctx ); + BspReqInterruptSpurious_TestVariant( ctx ); + } +} + +/** @} */ diff --git a/testsuites/validation/tc-intr-clear.c b/testsuites/validation/tc-intr-clear.c index 8c4e1e1deb..1c6c451a39 100644 --- a/testsuites/validation/tc-intr-clear.c +++ b/testsuites/validation/tc-intr-clear.c @@ -63,7 +63,7 @@ /** * @defgroup RTEMSTestCaseRtemsIntrReqClear spec:/rtems/intr/req/clear * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -133,6 +133,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 2 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -560,13 +566,23 @@ static inline RtemsIntrReqClear_Entry RtemsIntrReqClear_PopEntry( ]; } +static void RtemsIntrReqClear_SetPreConditionStates( + RtemsIntrReqClear_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + + if ( ctx->Map.entry.Pre_CanClear_NA ) { + ctx->Map.pcs[ 1 ] = RtemsIntrReqClear_Pre_CanClear_NA; + } else { + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + } +} + static void RtemsIntrReqClear_TestVariant( RtemsIntrReqClear_Context *ctx ) { RtemsIntrReqClear_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); - RtemsIntrReqClear_Pre_CanClear_Prepare( - ctx, - ctx->Map.entry.Pre_CanClear_NA ? RtemsIntrReqClear_Pre_CanClear_NA : ctx->Map.pcs[ 1 ] - ); + RtemsIntrReqClear_Pre_CanClear_Prepare( ctx, ctx->Map.pcs[ 1 ] ); RtemsIntrReqClear_Action( ctx ); RtemsIntrReqClear_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); RtemsIntrReqClear_Post_Cleared_Check( ctx, ctx->Map.entry.Post_Cleared ); @@ -584,16 +600,17 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqClear, &RtemsIntrReqClear_Fixture ) ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqClear_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqClear_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqClear_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqClear_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqClear_Pre_CanClear_Yes; - ctx->Map.pcs[ 1 ] < RtemsIntrReqClear_Pre_CanClear_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqClear_Pre_CanClear_Yes; + ctx->Map.pci[ 1 ] < RtemsIntrReqClear_Pre_CanClear_NA; + ++ctx->Map.pci[ 1 ] ) { ctx->Map.entry = RtemsIntrReqClear_PopEntry( ctx ); + RtemsIntrReqClear_SetPreConditionStates( ctx ); RtemsIntrReqClear_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr-entry-install.c b/testsuites/validation/tc-intr-entry-install.c index f5280c1e73..714486772a 100644 --- a/testsuites/validation/tc-intr-entry-install.c +++ b/testsuites/validation/tc-intr-entry-install.c @@ -63,7 +63,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqEntryInstall \ * spec:/rtems/intr/req/entry-install * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -174,9 +174,14 @@ typedef struct { bool initialized_during_setup; /** - * @brief If this member is true, then an interrupt occurred. + * @brief This member provides a counter for handler invocations. */ - bool interrupt_occurred; + uint32_t handler_counter; + + /** + * @brief This member provides a counter snapshot for each entry. + */ + uint32_t counter_by_entry[ 3 ];; /** * @brief This member provides the vector number of a testable interrupt @@ -271,6 +276,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 8 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -409,29 +420,66 @@ static void Install( ctx->other_installed = true; } -static void OtherRoutine( void *arg ) +static void Routine( Context *ctx, uint32_t counter ) { - Context *ctx; rtems_status_code sc; - (void) arg; - ctx = T_fixture_context(); - sc = rtems_interrupt_vector_disable( ctx->test_vector ); - T_rsc_success( sc ); + ctx->handler_counter = counter; + + if ( + ctx->attributes.can_clear && + !ctx->attributes.cleared_by_acknowledge + ) { + sc = rtems_interrupt_clear( ctx->test_vector ); + T_rsc_success( sc ); + } - ctx->interrupt_occurred = true; + if ( counter > 3 ) { + sc = rtems_interrupt_vector_disable( ctx->test_vector ); + T_rsc_success( sc ); + } } static void EntryRoutine( void *arg ) { - T_eq_ptr( arg, &entry_arg ); - OtherRoutine( NULL ); + Context *ctx; + uint32_t counter; + + ctx = T_fixture_context(); + counter = ctx->handler_counter + 1; + + if ( arg == &other_arg ) { + ctx->counter_by_entry[ 1 ] = counter; + } else { + ctx->counter_by_entry[ 0 ] = counter; + T_eq_ptr( arg, &entry_arg ); + } + + Routine( ctx, counter ); +} + +static void OtherRoutine( void *arg ) +{ + Context *ctx; + uint32_t counter; + + (void) arg; + ctx = T_fixture_context(); + counter = ctx->handler_counter + 1; + ctx->counter_by_entry[ 1 ] = counter; + Routine( ctx, counter ); } static void ThirdRoutine( void *arg ) { + Context *ctx; + uint32_t counter; + + ctx = T_fixture_context(); + counter = ctx->handler_counter + 1; + ctx->counter_by_entry[ 2 ] = counter; T_eq_ptr( arg, &third_arg ); - OtherRoutine( NULL ); + Routine( ctx, counter ); } static void InstallThird( Context *ctx ) @@ -489,6 +537,11 @@ static void Action( void *arg ) &ctx->enabled_after ); T_rsc_success( sc ); + + if ( ctx->status == RTEMS_SUCCESSFUL ) { + sc = rtems_interrupt_raise( ctx->test_vector ); + T_rsc_success( sc ); + } } static void VisitInstalled( @@ -940,7 +993,7 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check( * The enabled status of the interrupt vector specified by ``vector`` * shall not be modified by the rtems_interrupt_entry_install() call. */ - if ( !ctx->interrupt_occurred ) { + if ( ctx->handler_counter == 0 ) { T_eq( ctx->enabled_before, ctx->enabled_after ); } break; @@ -950,9 +1003,7 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check( /* * The interrupt vector specified by ``vector`` shall be enabled. */ - if ( ctx->attributes.can_enable ) { - T_true( ctx->enabled_after || ctx->interrupt_occurred ); - } + T_true( ctx->enabled_after || ctx->handler_counter > 3 ); break; } @@ -960,10 +1011,13 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check( /* * The interrupt vector specified by ``vector`` may be enabled. */ - /* The comment of pre-condition ``CanEnable`` for the ``Yes`` state. */ - if ( ctx->attributes.can_enable ) { - T_true( ctx->enabled_after || ctx->interrupt_occurred ); - } + /* + * Interrupt vectors which cannot be enabled are not selected as a + * testable interrupt vector by GetTestableInterruptVector(), so this + * path is not validated by this test. See also comment for + * ``CanEnable`` pre-condition state ``Yes``. + */ + T_true( ctx->enabled_after || ctx->handler_counter > 3 ); break; } @@ -973,8 +1027,11 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check( */ /* * Interrupt vectors which cannot be enabled are not selected as a - * testable interrupt vector by GetTestableInterruptVector(). + * testable interrupt vector by GetTestableInterruptVector(), so this + * path is not validated by this test. See also comment for + * ``CanEnable`` pre-condition state ``Yes``. */ + T_true( ctx->enabled_after || ctx->handler_counter > 3 ); break; } @@ -998,6 +1055,24 @@ static void RtemsIntrReqEntryInstall_Post_Installed_Check( ); T_rsc_success( sc ); + if ( ctx->status == RTEMS_SUCCESSFUL ) { + uint32_t counter; + + counter = 1; + + if ( ctx->other_installed ) { + T_eq_u32( ctx->counter_by_entry[ 1 ], counter ); + ++counter; + } + + if ( ctx->third_installed ) { + T_eq_u32( ctx->counter_by_entry[ 2 ], counter ); + ++counter; + } + + T_eq_u32( ctx->counter_by_entry[ 0 ], counter ); + } + switch ( state ) { case RtemsIntrReqEntryInstall_Post_Installed_No: { /* @@ -1038,10 +1113,13 @@ static void RtemsIntrReqEntryInstall_Setup( RtemsIntrReqEntryInstall_Context *ctx ) { + rtems_interrupt_attributes required = { + .can_raise = true + }; rtems_status_code sc; ctx->initialized_during_setup = bsp_interrupt_is_initialized(); - ctx->test_vector = GetTestableInterruptVector( NULL ); + ctx->test_vector = GetTestableInterruptVector( &required ); sc = rtems_interrupt_get_attributes( ctx->test_vector, &ctx->attributes ); T_rsc_success( sc ); } @@ -1059,7 +1137,13 @@ static void RtemsIntrReqEntryInstall_Prepare( RtemsIntrReqEntryInstall_Context *ctx ) { - ctx->interrupt_occurred = false; + size_t i; + + for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->counter_by_entry ); ++i ) { + ctx->counter_by_entry[ i ] = 0; + } + + ctx->handler_counter = 0; ctx->other_installed = false; ctx->third_installed = false; } @@ -1254,6 +1338,36 @@ static inline RtemsIntrReqEntryInstall_Entry RtemsIntrReqEntryInstall_PopEntry( ]; } +static void RtemsIntrReqEntryInstall_SetPreConditionStates( + RtemsIntrReqEntryInstall_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + + if ( ctx->Map.entry.Pre_Routine_NA ) { + ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryInstall_Pre_Routine_NA; + } else { + ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ]; + } + + ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ]; + ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ]; + + if ( ctx->Map.entry.Pre_CanEnable_NA ) { + ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryInstall_Pre_CanEnable_NA; + } else { + ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ]; + } + + if ( ctx->Map.entry.Pre_Installed_NA ) { + ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryInstall_Pre_Installed_NA; + } else { + ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ]; + } +} + static void RtemsIntrReqEntryInstall_TestVariant( RtemsIntrReqEntryInstall_Context *ctx ) @@ -1261,20 +1375,11 @@ static void RtemsIntrReqEntryInstall_TestVariant( RtemsIntrReqEntryInstall_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); RtemsIntrReqEntryInstall_Pre_Options_Prepare( ctx, ctx->Map.pcs[ 1 ] ); RtemsIntrReqEntryInstall_Pre_Entry_Prepare( ctx, ctx->Map.pcs[ 2 ] ); - RtemsIntrReqEntryInstall_Pre_Routine_Prepare( - ctx, - ctx->Map.entry.Pre_Routine_NA ? RtemsIntrReqEntryInstall_Pre_Routine_NA : ctx->Map.pcs[ 3 ] - ); + RtemsIntrReqEntryInstall_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 3 ] ); RtemsIntrReqEntryInstall_Pre_Init_Prepare( ctx, ctx->Map.pcs[ 4 ] ); RtemsIntrReqEntryInstall_Pre_ISR_Prepare( ctx, ctx->Map.pcs[ 5 ] ); - RtemsIntrReqEntryInstall_Pre_CanEnable_Prepare( - ctx, - ctx->Map.entry.Pre_CanEnable_NA ? RtemsIntrReqEntryInstall_Pre_CanEnable_NA : ctx->Map.pcs[ 6 ] - ); - RtemsIntrReqEntryInstall_Pre_Installed_Prepare( - ctx, - ctx->Map.entry.Pre_Installed_NA ? RtemsIntrReqEntryInstall_Pre_Installed_NA : ctx->Map.pcs[ 7 ] - ); + RtemsIntrReqEntryInstall_Pre_CanEnable_Prepare( ctx, ctx->Map.pcs[ 6 ] ); + RtemsIntrReqEntryInstall_Pre_Installed_Prepare( ctx, ctx->Map.pcs[ 7 ] ); RtemsIntrReqEntryInstall_Action( ctx ); RtemsIntrReqEntryInstall_Post_Status_Check( ctx, @@ -1305,46 +1410,47 @@ T_TEST_CASE_FIXTURE( ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqEntryInstall_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqEntryInstall_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqEntryInstall_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqEntryInstall_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqEntryInstall_Pre_Options_Unique; - ctx->Map.pcs[ 1 ] < RtemsIntrReqEntryInstall_Pre_Options_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqEntryInstall_Pre_Options_Unique; + ctx->Map.pci[ 1 ] < RtemsIntrReqEntryInstall_Pre_Options_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqEntryInstall_Pre_Entry_Obj; - ctx->Map.pcs[ 2 ] < RtemsIntrReqEntryInstall_Pre_Entry_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqEntryInstall_Pre_Entry_Obj; + ctx->Map.pci[ 2 ] < RtemsIntrReqEntryInstall_Pre_Entry_NA; + ++ctx->Map.pci[ 2 ] ) { for ( - ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryInstall_Pre_Routine_Valid; - ctx->Map.pcs[ 3 ] < RtemsIntrReqEntryInstall_Pre_Routine_NA; - ++ctx->Map.pcs[ 3 ] + ctx->Map.pci[ 3 ] = RtemsIntrReqEntryInstall_Pre_Routine_Valid; + ctx->Map.pci[ 3 ] < RtemsIntrReqEntryInstall_Pre_Routine_NA; + ++ctx->Map.pci[ 3 ] ) { for ( - ctx->Map.pcs[ 4 ] = RtemsIntrReqEntryInstall_Pre_Init_Yes; - ctx->Map.pcs[ 4 ] < RtemsIntrReqEntryInstall_Pre_Init_NA; - ++ctx->Map.pcs[ 4 ] + ctx->Map.pci[ 4 ] = RtemsIntrReqEntryInstall_Pre_Init_Yes; + ctx->Map.pci[ 4 ] < RtemsIntrReqEntryInstall_Pre_Init_NA; + ++ctx->Map.pci[ 4 ] ) { for ( - ctx->Map.pcs[ 5 ] = RtemsIntrReqEntryInstall_Pre_ISR_Yes; - ctx->Map.pcs[ 5 ] < RtemsIntrReqEntryInstall_Pre_ISR_NA; - ++ctx->Map.pcs[ 5 ] + ctx->Map.pci[ 5 ] = RtemsIntrReqEntryInstall_Pre_ISR_Yes; + ctx->Map.pci[ 5 ] < RtemsIntrReqEntryInstall_Pre_ISR_NA; + ++ctx->Map.pci[ 5 ] ) { for ( - ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryInstall_Pre_CanEnable_Yes; - ctx->Map.pcs[ 6 ] < RtemsIntrReqEntryInstall_Pre_CanEnable_NA; - ++ctx->Map.pcs[ 6 ] + ctx->Map.pci[ 6 ] = RtemsIntrReqEntryInstall_Pre_CanEnable_Yes; + ctx->Map.pci[ 6 ] < RtemsIntrReqEntryInstall_Pre_CanEnable_NA; + ++ctx->Map.pci[ 6 ] ) { for ( - ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryInstall_Pre_Installed_None; - ctx->Map.pcs[ 7 ] < RtemsIntrReqEntryInstall_Pre_Installed_NA; - ++ctx->Map.pcs[ 7 ] + ctx->Map.pci[ 7 ] = RtemsIntrReqEntryInstall_Pre_Installed_None; + ctx->Map.pci[ 7 ] < RtemsIntrReqEntryInstall_Pre_Installed_NA; + ++ctx->Map.pci[ 7 ] ) { ctx->Map.entry = RtemsIntrReqEntryInstall_PopEntry( ctx ); + RtemsIntrReqEntryInstall_SetPreConditionStates( ctx ); RtemsIntrReqEntryInstall_Prepare( ctx ); RtemsIntrReqEntryInstall_TestVariant( ctx ); RtemsIntrReqEntryInstall_Cleanup( ctx ); diff --git a/testsuites/validation/tc-intr-entry-remove.c b/testsuites/validation/tc-intr-entry-remove.c index ad07464de6..c73bcbb3fc 100644 --- a/testsuites/validation/tc-intr-entry-remove.c +++ b/testsuites/validation/tc-intr-entry-remove.c @@ -63,7 +63,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqEntryRemove \ * spec:/rtems/intr/req/entry-remove * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -289,6 +289,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 9 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -1023,7 +1029,7 @@ static void RtemsIntrReqEntryRemove_Post_Installed_Check( if ( expected_entries > 0 ) { ctx->entry_counter = 0; - bsp_interrupt_handler_dispatch( ctx->test_vector ); + bsp_interrupt_handler_dispatch_unchecked( ctx->test_vector ); T_eq_u32( ctx->entry_counter, 0 ); } else { rtems_interrupt_entry *first; @@ -1063,7 +1069,7 @@ static void RtemsIntrReqEntryRemove_Post_Installed_Check( if ( ctx->installed ) { ctx->entry_counter = 0; - bsp_interrupt_handler_dispatch( ctx->test_vector ); + bsp_interrupt_handler_dispatch_unchecked( ctx->test_vector ); T_eq_u32( ctx->entry_counter, 1 ); } break; @@ -1304,34 +1310,60 @@ static inline RtemsIntrReqEntryRemove_Entry RtemsIntrReqEntryRemove_PopEntry( ]; } +static void RtemsIntrReqEntryRemove_SetPreConditionStates( + RtemsIntrReqEntryRemove_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + + if ( ctx->Map.entry.Pre_Routine_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqEntryRemove_Pre_Routine_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } + + if ( ctx->Map.entry.Pre_EntryObj_NA ) { + ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryRemove_Pre_EntryObj_NA; + } else { + ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ]; + } + + ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ]; + ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ]; + + if ( ctx->Map.entry.Pre_CanDisable_NA ) { + ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryRemove_Pre_CanDisable_NA; + } else { + ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ]; + } + + if ( ctx->Map.entry.Pre_First_NA ) { + ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryRemove_Pre_First_NA; + } else { + ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ]; + } + + if ( ctx->Map.entry.Pre_Last_NA ) { + ctx->Map.pcs[ 8 ] = RtemsIntrReqEntryRemove_Pre_Last_NA; + } else { + ctx->Map.pcs[ 8 ] = ctx->Map.pci[ 8 ]; + } +} + static void RtemsIntrReqEntryRemove_TestVariant( RtemsIntrReqEntryRemove_Context *ctx ) { RtemsIntrReqEntryRemove_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); RtemsIntrReqEntryRemove_Pre_Entry_Prepare( ctx, ctx->Map.pcs[ 1 ] ); - RtemsIntrReqEntryRemove_Pre_Routine_Prepare( - ctx, - ctx->Map.entry.Pre_Routine_NA ? RtemsIntrReqEntryRemove_Pre_Routine_NA : ctx->Map.pcs[ 2 ] - ); - RtemsIntrReqEntryRemove_Pre_EntryObj_Prepare( - ctx, - ctx->Map.entry.Pre_EntryObj_NA ? RtemsIntrReqEntryRemove_Pre_EntryObj_NA : ctx->Map.pcs[ 3 ] - ); + RtemsIntrReqEntryRemove_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 2 ] ); + RtemsIntrReqEntryRemove_Pre_EntryObj_Prepare( ctx, ctx->Map.pcs[ 3 ] ); RtemsIntrReqEntryRemove_Pre_Init_Prepare( ctx, ctx->Map.pcs[ 4 ] ); RtemsIntrReqEntryRemove_Pre_ISR_Prepare( ctx, ctx->Map.pcs[ 5 ] ); - RtemsIntrReqEntryRemove_Pre_CanDisable_Prepare( - ctx, - ctx->Map.entry.Pre_CanDisable_NA ? RtemsIntrReqEntryRemove_Pre_CanDisable_NA : ctx->Map.pcs[ 6 ] - ); - RtemsIntrReqEntryRemove_Pre_First_Prepare( - ctx, - ctx->Map.entry.Pre_First_NA ? RtemsIntrReqEntryRemove_Pre_First_NA : ctx->Map.pcs[ 7 ] - ); - RtemsIntrReqEntryRemove_Pre_Last_Prepare( - ctx, - ctx->Map.entry.Pre_Last_NA ? RtemsIntrReqEntryRemove_Pre_Last_NA : ctx->Map.pcs[ 8 ] - ); + RtemsIntrReqEntryRemove_Pre_CanDisable_Prepare( ctx, ctx->Map.pcs[ 6 ] ); + RtemsIntrReqEntryRemove_Pre_First_Prepare( ctx, ctx->Map.pcs[ 7 ] ); + RtemsIntrReqEntryRemove_Pre_Last_Prepare( ctx, ctx->Map.pcs[ 8 ] ); RtemsIntrReqEntryRemove_Action( ctx ); RtemsIntrReqEntryRemove_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); RtemsIntrReqEntryRemove_Post_Disabled_Check( @@ -1359,51 +1391,52 @@ T_TEST_CASE_FIXTURE( ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqEntryRemove_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqEntryRemove_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqEntryRemove_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqEntryRemove_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqEntryRemove_Pre_Entry_Obj; - ctx->Map.pcs[ 1 ] < RtemsIntrReqEntryRemove_Pre_Entry_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqEntryRemove_Pre_Entry_Obj; + ctx->Map.pci[ 1 ] < RtemsIntrReqEntryRemove_Pre_Entry_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqEntryRemove_Pre_Routine_Valid; - ctx->Map.pcs[ 2 ] < RtemsIntrReqEntryRemove_Pre_Routine_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqEntryRemove_Pre_Routine_Valid; + ctx->Map.pci[ 2 ] < RtemsIntrReqEntryRemove_Pre_Routine_NA; + ++ctx->Map.pci[ 2 ] ) { for ( - ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryRemove_Pre_EntryObj_Installed; - ctx->Map.pcs[ 3 ] < RtemsIntrReqEntryRemove_Pre_EntryObj_NA; - ++ctx->Map.pcs[ 3 ] + ctx->Map.pci[ 3 ] = RtemsIntrReqEntryRemove_Pre_EntryObj_Installed; + ctx->Map.pci[ 3 ] < RtemsIntrReqEntryRemove_Pre_EntryObj_NA; + ++ctx->Map.pci[ 3 ] ) { for ( - ctx->Map.pcs[ 4 ] = RtemsIntrReqEntryRemove_Pre_Init_Yes; - ctx->Map.pcs[ 4 ] < RtemsIntrReqEntryRemove_Pre_Init_NA; - ++ctx->Map.pcs[ 4 ] + ctx->Map.pci[ 4 ] = RtemsIntrReqEntryRemove_Pre_Init_Yes; + ctx->Map.pci[ 4 ] < RtemsIntrReqEntryRemove_Pre_Init_NA; + ++ctx->Map.pci[ 4 ] ) { for ( - ctx->Map.pcs[ 5 ] = RtemsIntrReqEntryRemove_Pre_ISR_Yes; - ctx->Map.pcs[ 5 ] < RtemsIntrReqEntryRemove_Pre_ISR_NA; - ++ctx->Map.pcs[ 5 ] + ctx->Map.pci[ 5 ] = RtemsIntrReqEntryRemove_Pre_ISR_Yes; + ctx->Map.pci[ 5 ] < RtemsIntrReqEntryRemove_Pre_ISR_NA; + ++ctx->Map.pci[ 5 ] ) { for ( - ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryRemove_Pre_CanDisable_Yes; - ctx->Map.pcs[ 6 ] < RtemsIntrReqEntryRemove_Pre_CanDisable_NA; - ++ctx->Map.pcs[ 6 ] + ctx->Map.pci[ 6 ] = RtemsIntrReqEntryRemove_Pre_CanDisable_Yes; + ctx->Map.pci[ 6 ] < RtemsIntrReqEntryRemove_Pre_CanDisable_NA; + ++ctx->Map.pci[ 6 ] ) { for ( - ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryRemove_Pre_First_Yes; - ctx->Map.pcs[ 7 ] < RtemsIntrReqEntryRemove_Pre_First_NA; - ++ctx->Map.pcs[ 7 ] + ctx->Map.pci[ 7 ] = RtemsIntrReqEntryRemove_Pre_First_Yes; + ctx->Map.pci[ 7 ] < RtemsIntrReqEntryRemove_Pre_First_NA; + ++ctx->Map.pci[ 7 ] ) { for ( - ctx->Map.pcs[ 8 ] = RtemsIntrReqEntryRemove_Pre_Last_Yes; - ctx->Map.pcs[ 8 ] < RtemsIntrReqEntryRemove_Pre_Last_NA; - ++ctx->Map.pcs[ 8 ] + ctx->Map.pci[ 8 ] = RtemsIntrReqEntryRemove_Pre_Last_Yes; + ctx->Map.pci[ 8 ] < RtemsIntrReqEntryRemove_Pre_Last_NA; + ++ctx->Map.pci[ 8 ] ) { ctx->Map.entry = RtemsIntrReqEntryRemove_PopEntry( ctx ); + RtemsIntrReqEntryRemove_SetPreConditionStates( ctx ); RtemsIntrReqEntryRemove_Prepare( ctx ); RtemsIntrReqEntryRemove_TestVariant( ctx ); RtemsIntrReqEntryRemove_Cleanup( ctx ); diff --git a/testsuites/validation/tc-intr-get-affinity.c b/testsuites/validation/tc-intr-get-affinity.c index 375a131a05..277cb790a3 100644 --- a/testsuites/validation/tc-intr-get-affinity.c +++ b/testsuites/validation/tc-intr-get-affinity.c @@ -64,7 +64,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqGetAffinity \ * spec:/rtems/intr/req/get-affinity * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -164,6 +164,12 @@ typedef struct { cpu_set_t *cpuset; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 4 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -642,6 +648,21 @@ static inline RtemsIntrReqGetAffinity_Entry RtemsIntrReqGetAffinity_PopEntry( ]; } +static void RtemsIntrReqGetAffinity_SetPreConditionStates( + RtemsIntrReqGetAffinity_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + + if ( ctx->Map.entry.Pre_CanGetAffinity_NA ) { + ctx->Map.pcs[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA; + } else { + ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ]; + } +} + static void RtemsIntrReqGetAffinity_TestVariant( RtemsIntrReqGetAffinity_Context *ctx ) @@ -649,10 +670,7 @@ static void RtemsIntrReqGetAffinity_TestVariant( RtemsIntrReqGetAffinity_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); RtemsIntrReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] ); RtemsIntrReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] ); - RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Prepare( - ctx, - ctx->Map.entry.Pre_CanGetAffinity_NA ? RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA : ctx->Map.pcs[ 3 ] - ); + RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Prepare( ctx, ctx->Map.pcs[ 3 ] ); RtemsIntrReqGetAffinity_Action( ctx ); RtemsIntrReqGetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); RtemsIntrReqGetAffinity_Post_CPUSetObj_Check( @@ -676,26 +694,27 @@ T_TEST_CASE_FIXTURE( ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqGetAffinity_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqGetAffinity_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqGetAffinity_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqGetAffinity_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqGetAffinity_Pre_CPUSetSize_Valid; - ctx->Map.pcs[ 1 ] < RtemsIntrReqGetAffinity_Pre_CPUSetSize_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqGetAffinity_Pre_CPUSetSize_Valid; + ctx->Map.pci[ 1 ] < RtemsIntrReqGetAffinity_Pre_CPUSetSize_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqGetAffinity_Pre_CPUSet_Valid; - ctx->Map.pcs[ 2 ] < RtemsIntrReqGetAffinity_Pre_CPUSet_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqGetAffinity_Pre_CPUSet_Valid; + ctx->Map.pci[ 2 ] < RtemsIntrReqGetAffinity_Pre_CPUSet_NA; + ++ctx->Map.pci[ 2 ] ) { for ( - ctx->Map.pcs[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Yes; - ctx->Map.pcs[ 3 ] < RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA; - ++ctx->Map.pcs[ 3 ] + ctx->Map.pci[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Yes; + ctx->Map.pci[ 3 ] < RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA; + ++ctx->Map.pci[ 3 ] ) { ctx->Map.entry = RtemsIntrReqGetAffinity_PopEntry( ctx ); + RtemsIntrReqGetAffinity_SetPreConditionStates( ctx ); RtemsIntrReqGetAffinity_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr-get-attributes.c b/testsuites/validation/tc-intr-get-attributes.c index f64eef1563..713defaa1a 100644 --- a/testsuites/validation/tc-intr-get-attributes.c +++ b/testsuites/validation/tc-intr-get-attributes.c @@ -62,7 +62,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqGetAttributes \ * spec:/rtems/intr/req/get-attributes * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ diff --git a/testsuites/validation/tc-intr-handler-iterate.c b/testsuites/validation/tc-intr-handler-iterate.c index e643eb5e50..77b9b2b7d7 100644 --- a/testsuites/validation/tc-intr-handler-iterate.c +++ b/testsuites/validation/tc-intr-handler-iterate.c @@ -63,7 +63,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqHandlerIterate \ * spec:/rtems/intr/req/handler-iterate * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ diff --git a/testsuites/validation/tc-intr-is-pending.c b/testsuites/validation/tc-intr-is-pending.c index 4963827538..93be686038 100644 --- a/testsuites/validation/tc-intr-is-pending.c +++ b/testsuites/validation/tc-intr-is-pending.c @@ -63,7 +63,7 @@ /** * @defgroup RTEMSTestCaseRtemsIntrReqIsPending spec:/rtems/intr/req/is-pending * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -151,6 +151,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 3 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -284,14 +290,21 @@ static void CheckIsPending( if ( has_installed_entries ) { /* * We cannot test this vector thoroughly, since it is used by a device - * driver. + * driver. It may be pending or not. For example in SMP configurations, + * it may be pending while being serviced right now on another processor. */ - T_false( IsPending( ctx ) ); + (void) IsPending( ctx ); } else if ( !attr->is_maskable ) { /* We can only safely test maskable interrupts */ T_false( IsPending( ctx ) ); + } else if ( IsPending( ctx ) ) { + /* + * If there is already an interrupt pending, then it is probably raised + * by a peripheral which we cannot control. + */ } else if ( - attr->can_disable && ( attr->can_clear || attr->cleared_by_acknowledge ) + attr->can_raise && attr->can_disable && + ( attr->can_clear || attr->cleared_by_acknowledge ) ) { rtems_interrupt_entry entry; rtems_interrupt_level level; @@ -307,19 +320,21 @@ static void CheckIsPending( T_rsc_success( sc ); if ( !IsPending( ctx) && ( attr->can_enable || IsEnabled( ctx ) ) ) { - if ( attr->can_disable ) { - Disable( ctx ); - Raise( ctx ); - T_true( IsPending( ctx ) ); - - sc = rtems_interrupt_vector_enable( ctx->vector ); - T_rsc_success( sc ); - - while ( ctx->interrupt_count < 1 ) { - /* Wait */ - } - } else { - ++ctx->interrupt_count; + Disable( ctx ); + Raise( ctx ); + + /* + * Some interrupt controllers will signal a pending interrupt if it is + * disabled (for example ARM GIC), others will not signal a pending + * interrupt if it is disabled (for example Freescale/NXP MPIC). + */ + (void) IsPending( ctx ); + + sc = rtems_interrupt_vector_enable( ctx->vector ); + T_rsc_success( sc ); + + while ( ctx->interrupt_count < 1 ) { + /* Wait */ } rtems_interrupt_local_disable( level ); @@ -593,16 +608,27 @@ static inline RtemsIntrReqIsPending_Entry RtemsIntrReqIsPending_PopEntry( ]; } +static void RtemsIntrReqIsPending_SetPreConditionStates( + RtemsIntrReqIsPending_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + + if ( ctx->Map.entry.Pre_IsPending_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqIsPending_Pre_IsPending_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } +} + static void RtemsIntrReqIsPending_TestVariant( RtemsIntrReqIsPending_Context *ctx ) { RtemsIntrReqIsPending_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); RtemsIntrReqIsPending_Pre_Pending_Prepare( ctx, ctx->Map.pcs[ 1 ] ); - RtemsIntrReqIsPending_Pre_IsPending_Prepare( - ctx, - ctx->Map.entry.Pre_IsPending_NA ? RtemsIntrReqIsPending_Pre_IsPending_NA : ctx->Map.pcs[ 2 ] - ); + RtemsIntrReqIsPending_Pre_IsPending_Prepare( ctx, ctx->Map.pcs[ 2 ] ); RtemsIntrReqIsPending_Action( ctx ); RtemsIntrReqIsPending_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); RtemsIntrReqIsPending_Post_IsPending_Check( @@ -623,21 +649,22 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqIsPending, &RtemsIntrReqIsPending_Fixture ) ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqIsPending_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqIsPending_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqIsPending_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqIsPending_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqIsPending_Pre_Pending_Obj; - ctx->Map.pcs[ 1 ] < RtemsIntrReqIsPending_Pre_Pending_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqIsPending_Pre_Pending_Obj; + ctx->Map.pci[ 1 ] < RtemsIntrReqIsPending_Pre_Pending_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqIsPending_Pre_IsPending_Yes; - ctx->Map.pcs[ 2 ] < RtemsIntrReqIsPending_Pre_IsPending_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqIsPending_Pre_IsPending_Yes; + ctx->Map.pci[ 2 ] < RtemsIntrReqIsPending_Pre_IsPending_NA; + ++ctx->Map.pci[ 2 ] ) { ctx->Map.entry = RtemsIntrReqIsPending_PopEntry( ctx ); + RtemsIntrReqIsPending_SetPreConditionStates( ctx ); RtemsIntrReqIsPending_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr-non-smp.c b/testsuites/validation/tc-intr-non-smp.c new file mode 100644 index 0000000000..bb75ccc1b6 --- /dev/null +++ b/testsuites/validation/tc-intr-non-smp.c @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsIntrValIntrNonSmp + */ + +/* + * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * + * 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 "tx-support.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsIntrValIntrNonSmp \ + * spec:/rtems/intr/val/intr-non-smp + * + * @ingroup RTEMSTestSuiteTestsuitesValidationNonSmp + * + * @brief Tests some @ref RTEMSAPIClassicIntr interfaces. + * + * This test case performs the following actions: + * + * - Validate some interrupt lock macros. + * + * - Check that RTEMS_INTERRUPT_LOCK_DECLARE() expands to white space only. + * + * - Check that RTEMS_INTERRUPT_LOCK_DEFINE() expands to white space only. + * + * - Check that RTEMS_INTERRUPT_LOCK_MEMBER() expands to white space only. + * + * - Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expands to white space only. + * + * - Check that rtems_interrupt_lock_destroy() expands to white space only. + * + * - Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to an empty + * structure initializer. + * + * - Check that rtems_interrupt_lock_initialize() expands to white space + * only. + * + * - Check that rtems_interrupt_lock_acquire_isr() expands to a code block + * which marks the second parameter as used. + * + * - Check that rtems_interrupt_lock_release_isr() expands to a code block + * which marks the second parameter as used. + * + * @{ + */ + +/** + * @brief Validate some interrupt lock macros. + */ +static void RtemsIntrValIntrNonSmp_Action_0( void ) +{ + const char *s; + + /* + * Check that RTEMS_INTERRUPT_LOCK_DECLARE() expands to white space only. + */ + s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_DECLARE( x, y ) ); + T_true( IsWhiteSpaceOnly( s ) ); + + /* + * Check that RTEMS_INTERRUPT_LOCK_DEFINE() expands to white space only. + */ + s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_DEFINE( x, y, z ) ); + T_true( IsWhiteSpaceOnly( s ) ); + + /* + * Check that RTEMS_INTERRUPT_LOCK_MEMBER() expands to white space only. + */ + s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_MEMBER( x ) ); + T_true( IsWhiteSpaceOnly( s ) ); + + /* + * Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expands to white space only. + */ + s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_REFERENCE( x, y ) ); + T_true( IsWhiteSpaceOnly( s ) ); + + /* + * Check that rtems_interrupt_lock_destroy() expands to white space only. + */ + s = RTEMS_XSTRING( rtems_interrupt_lock_destroy( x ) ); + T_true( IsWhiteSpaceOnly( s ) ); + + /* + * Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to an empty + * structure initializer. + */ + s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_INITIALIZER( x ) ); + T_true( IsEqualIgnoreWhiteSpace( s, "{}" ) ); + + /* + * Check that rtems_interrupt_lock_initialize() expands to white space only. + */ + s = RTEMS_XSTRING( rtems_interrupt_lock_initialize( x, y ) ); + T_true( IsWhiteSpaceOnly( s ) ); + + /* + * Check that rtems_interrupt_lock_acquire_isr() expands to a code block + * which marks the second parameter as used. + */ + s = RTEMS_XSTRING( rtems_interrupt_lock_acquire_isr( x, y ) ); + T_true( IsEqualIgnoreWhiteSpace( s, "do{(void)y;}while(0)" ) ); + + /* + * Check that rtems_interrupt_lock_release_isr() expands to a code block + * which marks the second parameter as used. + */ + s = RTEMS_XSTRING( rtems_interrupt_lock_release_isr( x, y ) ); + T_true( IsEqualIgnoreWhiteSpace( s, "do{(void)y;}while(0)" ) ); +} + +/** + * @fn void T_case_body_RtemsIntrValIntrNonSmp( void ) + */ +T_TEST_CASE( RtemsIntrValIntrNonSmp ) +{ + RtemsIntrValIntrNonSmp_Action_0(); +} + +/** @} */ diff --git a/testsuites/validation/tc-intr-raise-on.c b/testsuites/validation/tc-intr-raise-on.c index efe468aebd..4d305258b3 100644 --- a/testsuites/validation/tc-intr-raise-on.c +++ b/testsuites/validation/tc-intr-raise-on.c @@ -63,7 +63,7 @@ /** * @defgroup RTEMSTestCaseRtemsIntrReqRaiseOn spec:/rtems/intr/req/raise-on * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -153,6 +153,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 3 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -332,21 +338,21 @@ static void CheckRaiseOn( T_rsc_success( sc ); if ( !IsPending( ctx) && ( attr->can_enable || IsEnabled( ctx ) ) ) { - T_false( IsPending( ctx ) ); + Disable( ctx ); + RaiseOn( ctx ); - if ( attr->can_disable ) { - Disable( ctx ); - RaiseOn( ctx ); - T_true( IsPending( ctx ) ); + /* + * Some interrupt controllers will signal a pending interrupt if it is + * disabled (for example ARM GIC), others will not signal a pending + * interrupt if it is disabled (for example Freescale/NXP MPIC). + */ + (void) IsPending( ctx ); - sc = rtems_interrupt_vector_enable( ctx->vector ); - T_rsc_success( sc ); + sc = rtems_interrupt_vector_enable( ctx->vector ); + T_rsc_success( sc ); - while ( ctx->interrupt_count < 1 ) { - /* Wait */ - } - } else { - ++ctx->interrupt_count; + while ( ctx->interrupt_count < 1 ) { + /* Wait */ } T_false( IsPending( ctx ) ); @@ -672,14 +678,25 @@ static inline RtemsIntrReqRaiseOn_Entry RtemsIntrReqRaiseOn_PopEntry( ]; } +static void RtemsIntrReqRaiseOn_SetPreConditionStates( + RtemsIntrReqRaiseOn_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + + if ( ctx->Map.entry.Pre_CanRaiseOn_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } +} + static void RtemsIntrReqRaiseOn_TestVariant( RtemsIntrReqRaiseOn_Context *ctx ) { RtemsIntrReqRaiseOn_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); RtemsIntrReqRaiseOn_Pre_CPU_Prepare( ctx, ctx->Map.pcs[ 1 ] ); - RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Prepare( - ctx, - ctx->Map.entry.Pre_CanRaiseOn_NA ? RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA : ctx->Map.pcs[ 2 ] - ); + RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Prepare( ctx, ctx->Map.pcs[ 2 ] ); RtemsIntrReqRaiseOn_Action( ctx ); RtemsIntrReqRaiseOn_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); RtemsIntrReqRaiseOn_Post_Pending_Check( ctx, ctx->Map.entry.Post_Pending ); @@ -697,19 +714,19 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqRaiseOn, &RtemsIntrReqRaiseOn_Fixture ) ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqRaiseOn_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqRaiseOn_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqRaiseOn_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqRaiseOn_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqRaiseOn_Pre_CPU_Online; - ctx->Map.pcs[ 1 ] < RtemsIntrReqRaiseOn_Pre_CPU_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqRaiseOn_Pre_CPU_Online; + ctx->Map.pci[ 1 ] < RtemsIntrReqRaiseOn_Pre_CPU_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Yes; - ctx->Map.pcs[ 2 ] < RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Yes; + ctx->Map.pci[ 2 ] < RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA; + ++ctx->Map.pci[ 2 ] ) { ctx->Map.entry = RtemsIntrReqRaiseOn_PopEntry( ctx ); @@ -717,6 +734,7 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqRaiseOn, &RtemsIntrReqRaiseOn_Fixture ) continue; } + RtemsIntrReqRaiseOn_SetPreConditionStates( ctx ); RtemsIntrReqRaiseOn_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr-raise.c b/testsuites/validation/tc-intr-raise.c index 81e8f8e856..dde5f2c0e0 100644 --- a/testsuites/validation/tc-intr-raise.c +++ b/testsuites/validation/tc-intr-raise.c @@ -63,7 +63,7 @@ /** * @defgroup RTEMSTestCaseRtemsIntrReqRaise spec:/rtems/intr/req/raise * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -133,6 +133,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 2 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -304,21 +310,21 @@ static void CheckRaise( T_rsc_success( sc ); if ( !IsPending( ctx) && ( attr->can_enable || IsEnabled( ctx ) ) ) { - T_false( IsPending( ctx ) ); + Disable( ctx ); + Raise( ctx ); - if ( attr->can_disable ) { - Disable( ctx ); - Raise( ctx ); - T_true( IsPending( ctx ) ); + /* + * Some interrupt controllers will signal a pending interrupt if it is + * disabled (for example ARM GIC), others will not signal a pending + * interrupt if it is disabled (for example Freescale/NXP MPIC). + */ + (void) IsPending( ctx ); - sc = rtems_interrupt_vector_enable( ctx->vector ); - T_rsc_success( sc ); + sc = rtems_interrupt_vector_enable( ctx->vector ); + T_rsc_success( sc ); - while ( ctx->interrupt_count < 1 ) { - /* Wait */ - } - } else { - ++ctx->interrupt_count; + while ( ctx->interrupt_count < 1 ) { + /* Wait */ } T_false( IsPending( ctx ) ); @@ -550,13 +556,23 @@ static inline RtemsIntrReqRaise_Entry RtemsIntrReqRaise_PopEntry( ]; } +static void RtemsIntrReqRaise_SetPreConditionStates( + RtemsIntrReqRaise_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + + if ( ctx->Map.entry.Pre_CanRaise_NA ) { + ctx->Map.pcs[ 1 ] = RtemsIntrReqRaise_Pre_CanRaise_NA; + } else { + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + } +} + static void RtemsIntrReqRaise_TestVariant( RtemsIntrReqRaise_Context *ctx ) { RtemsIntrReqRaise_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); - RtemsIntrReqRaise_Pre_CanRaise_Prepare( - ctx, - ctx->Map.entry.Pre_CanRaise_NA ? RtemsIntrReqRaise_Pre_CanRaise_NA : ctx->Map.pcs[ 1 ] - ); + RtemsIntrReqRaise_Pre_CanRaise_Prepare( ctx, ctx->Map.pcs[ 1 ] ); RtemsIntrReqRaise_Action( ctx ); RtemsIntrReqRaise_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); RtemsIntrReqRaise_Post_Pending_Check( ctx, ctx->Map.entry.Post_Pending ); @@ -574,16 +590,17 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqRaise, &RtemsIntrReqRaise_Fixture ) ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqRaise_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqRaise_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqRaise_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqRaise_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqRaise_Pre_CanRaise_Yes; - ctx->Map.pcs[ 1 ] < RtemsIntrReqRaise_Pre_CanRaise_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqRaise_Pre_CanRaise_Yes; + ctx->Map.pci[ 1 ] < RtemsIntrReqRaise_Pre_CanRaise_NA; + ++ctx->Map.pci[ 1 ] ) { ctx->Map.entry = RtemsIntrReqRaise_PopEntry( ctx ); + RtemsIntrReqRaise_SetPreConditionStates( ctx ); RtemsIntrReqRaise_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr-set-affinity.c b/testsuites/validation/tc-intr-set-affinity.c index a2a6a45e09..0295fbaed4 100644 --- a/testsuites/validation/tc-intr-set-affinity.c +++ b/testsuites/validation/tc-intr-set-affinity.c @@ -7,7 +7,7 @@ */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021, 2022 embedded brains GmbH (http://www.embedded-brains.de) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -63,7 +63,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqSetAffinity \ * spec:/rtems/intr/req/set-affinity * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -75,11 +75,23 @@ typedef enum { } RtemsIntrReqSetAffinity_Pre_Vector; typedef enum { - RtemsIntrReqSetAffinity_Pre_CPUSetKind_Valid, - RtemsIntrReqSetAffinity_Pre_CPUSetKind_Huge, - RtemsIntrReqSetAffinity_Pre_CPUSetKind_Askew, - RtemsIntrReqSetAffinity_Pre_CPUSetKind_NA -} RtemsIntrReqSetAffinity_Pre_CPUSetKind; + RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew, + RtemsIntrReqSetAffinity_Pre_CPUSetSize_Normal, + RtemsIntrReqSetAffinity_Pre_CPUSetSize_Huge, + RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA +} RtemsIntrReqSetAffinity_Pre_CPUSetSize; + +typedef enum { + RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid, + RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Empty, + RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA +} RtemsIntrReqSetAffinity_Pre_CPUSetOnline; + +typedef enum { + RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero, + RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Zero, + RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA +} RtemsIntrReqSetAffinity_Pre_CPUSetHuge; typedef enum { RtemsIntrReqSetAffinity_Pre_CPUSet_Valid, @@ -103,7 +115,7 @@ typedef enum { } RtemsIntrReqSetAffinity_Post_Status; typedef enum { - RtemsIntrReqSetAffinity_Post_SetAffinity_Yes, + RtemsIntrReqSetAffinity_Post_SetAffinity_Set, RtemsIntrReqSetAffinity_Post_SetAffinity_Nop, RtemsIntrReqSetAffinity_Post_SetAffinity_NA } RtemsIntrReqSetAffinity_Post_SetAffinity; @@ -111,7 +123,9 @@ typedef enum { typedef struct { uint16_t Skip : 1; uint16_t Pre_Vector_NA : 1; - uint16_t Pre_CPUSetKind_NA : 1; + uint16_t Pre_CPUSetSize_NA : 1; + uint16_t Pre_CPUSetOnline_NA : 1; + uint16_t Pre_CPUSetHuge_NA : 1; uint16_t Pre_CPUSet_NA : 1; uint16_t Pre_CanSetAffinity_NA : 1; uint16_t Post_Status : 3; @@ -161,10 +175,16 @@ typedef struct { cpu_set_t *cpuset; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 6 ]; + /** * @brief This member defines the pre-condition states for the next action. */ - size_t pcs[ 4 ]; + size_t pcs[ 6 ]; /** * @brief If this member is true, then the test action loop is executed. @@ -198,10 +218,22 @@ static const char * const RtemsIntrReqSetAffinity_PreDesc_Vector[] = { "NA" }; -static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetKind[] = { - "Valid", - "Huge", +static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetSize[] = { "Askew", + "Normal", + "Huge", + "NA" +}; + +static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetOnline[] = { + "Valid", + "Empty", + "NA" +}; + +static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetHuge[] = { + "NotZero", + "Zero", "NA" }; @@ -219,7 +251,9 @@ static const char * const RtemsIntrReqSetAffinity_PreDesc_CanSetAffinity[] = { static const char * const * const RtemsIntrReqSetAffinity_PreDesc[] = { RtemsIntrReqSetAffinity_PreDesc_Vector, - RtemsIntrReqSetAffinity_PreDesc_CPUSetKind, + RtemsIntrReqSetAffinity_PreDesc_CPUSetSize, + RtemsIntrReqSetAffinity_PreDesc_CPUSetOnline, + RtemsIntrReqSetAffinity_PreDesc_CPUSetHuge, RtemsIntrReqSetAffinity_PreDesc_CPUSet, RtemsIntrReqSetAffinity_PreDesc_CanSetAffinity, NULL @@ -295,43 +329,107 @@ static void RtemsIntrReqSetAffinity_Pre_Vector_Prepare( } } -static void RtemsIntrReqSetAffinity_Pre_CPUSetKind_Prepare( +static void RtemsIntrReqSetAffinity_Pre_CPUSetSize_Prepare( RtemsIntrReqSetAffinity_Context *ctx, - RtemsIntrReqSetAffinity_Pre_CPUSetKind state + RtemsIntrReqSetAffinity_Pre_CPUSetSize state ) { switch ( state ) { - case RtemsIntrReqSetAffinity_Pre_CPUSetKind_Valid: { + case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew: { + /* + * While the ``affinity_size`` parameter is not an integral multiple of + * the size of long. + */ + ctx->cpusetsize = SIZE_MAX; + break; + } + + case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Normal: { /* * While the ``affinity_size`` parameter is an integral multiple of the - * size of long, while the ``affinity_size`` and ``affinity`` parameter - * specify a processor set which is within the implementation limits. + * size of long, while the ``affinity_size`` parameter is less than or + * equal to the maximum processor set size storable in the system. */ ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] ); break; } - case RtemsIntrReqSetAffinity_Pre_CPUSetKind_Huge: { + case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Huge: { /* * While the ``affinity_size`` parameter is an integral multiple of the - * size of long, while the ``affinity_size`` and ``affinity`` parameter - * specify a processor set which exceeds the implementation limits. + * size of long, while the ``affinity_size`` parameter is greater than + * the maximum processor set size storable in the system. */ ctx->cpusetsize = sizeof( ctx->cpuset_obj ); + break; + } + + case RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA: + break; + } +} + +static void RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Prepare( + RtemsIntrReqSetAffinity_Context *ctx, + RtemsIntrReqSetAffinity_Pre_CPUSetOnline state +) +{ + switch ( state ) { + case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid: { + /* + * While the intersection of the processor set specified by the + * ``affinity_size`` and ``affinity`` parameters and the set of online + * processors is not empty, while the intersection of the processor set + * specified by the ``affinity_size`` and ``affinity`` parameters and the + * set of online processors is a supported processor affinity set of the + * interrupt vector. + */ + /* Already prepared */ + break; + } + + case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Empty: { + /* + * While the intersection of the processor set specified by the + * ``affinity_size`` and ``affinity`` parameters and the set of online + * processors is empty. + */ CPU_ZERO( &ctx->cpuset_obj[ 0 ] ); break; } - case RtemsIntrReqSetAffinity_Pre_CPUSetKind_Askew: { + case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA: + break; + } +} + +static void RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Prepare( + RtemsIntrReqSetAffinity_Context *ctx, + RtemsIntrReqSetAffinity_Pre_CPUSetHuge state +) +{ + switch ( state ) { + case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero: { /* - * While the ``affinity_size`` parameter is not an integral multiple of - * the size of long. + * While the processor set specified by the ``affinity_size`` and + * ``affinity`` parameters contains at least one processor which is not + * storable in a processor set supported by the system. */ - ctx->cpusetsize = SIZE_MAX; + /* Already prepared */ + break; + } + + case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Zero: { + /* + * While the processor set specified by the ``affinity_size`` and + * ``affinity`` parameters contains no processor which is not storable in + * a processor set supported by the system. + */ + CPU_ZERO( &ctx->cpuset_obj[ 1 ] ); break; } - case RtemsIntrReqSetAffinity_Pre_CPUSetKind_NA: + case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA: break; } } @@ -455,7 +553,7 @@ static void RtemsIntrReqSetAffinity_Post_SetAffinity_Check( ) { switch ( state ) { - case RtemsIntrReqSetAffinity_Post_SetAffinity_Yes: { + case RtemsIntrReqSetAffinity_Post_SetAffinity_Set: { /* * The affinity set of the interrupt specified by ``vector`` shall be set * to the processor set specified by ``affinity_size`` and ``affinity`` @@ -513,7 +611,7 @@ static void RtemsIntrReqSetAffinity_Action( if ( ctx->valid_vector && ctx->cpusetsize == sizeof( ctx->cpuset_obj[ 0 ] ) && - ctx->cpuset == &ctx->cpuset_obj[ 0 ] + ctx->cpuset == &ctx->cpuset_obj[ 0 ] && !CPU_EMPTY( &ctx->cpuset_obj[ 0 ] ) ) { for ( ctx->vector = 0; @@ -532,6 +630,7 @@ static void RtemsIntrReqSetAffinity_Action( T_rsc_success( sc ); CheckSetAffinity( ctx, &attr ); + ctx->status = RTEMS_SUCCESSFUL; } } else { cpu_set_t set; @@ -539,6 +638,8 @@ static void RtemsIntrReqSetAffinity_Action( CPU_ZERO( &set ); CPU_ZERO( &set2 ); + CPU_SET( 0, &set ); + CPU_SET( 0, &set2 ); if ( ctx->valid_vector ) { ctx->vector = ctx->some_vector; @@ -549,7 +650,9 @@ static void RtemsIntrReqSetAffinity_Action( ctx->vector = BSP_INTERRUPT_VECTOR_COUNT; } - CPU_ZERO( &ctx->cpuset_obj[ 0 ] ); + if ( !CPU_EMPTY( &ctx->cpuset_obj[ 0 ] ) ) { + CPU_COPY( &set, &ctx->cpuset_obj[ 0 ] ); + } ctx->status = rtems_interrupt_set_affinity( ctx->vector, @@ -567,23 +670,34 @@ static void RtemsIntrReqSetAffinity_Action( static const RtemsIntrReqSetAffinity_Entry RtemsIntrReqSetAffinity_Entries[] = { - { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvAddr, + { 0, 0, 0, 1, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvAddr, + RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }, + { 0, 0, 0, 1, 1, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvAddr, + RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }, + { 0, 0, 0, 1, 1, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId, RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }, - { 0, 0, 0, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId, - RtemsIntrReqSetAffinity_Post_SetAffinity_NA }, - { 0, 0, 0, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvAddr, - RtemsIntrReqSetAffinity_Post_SetAffinity_NA }, - { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum, + { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum, RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }, - { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok, - RtemsIntrReqSetAffinity_Post_SetAffinity_Yes }, - { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat, + { 0, 0, 0, 1, 0, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId, + RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }, + { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum, + RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }, + { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok, + RtemsIntrReqSetAffinity_Post_SetAffinity_Set }, + { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat, + RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }, + { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok, + RtemsIntrReqSetAffinity_Post_SetAffinity_Set }, + { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat, RtemsIntrReqSetAffinity_Post_SetAffinity_Nop } }; static const uint8_t RtemsIntrReqSetAffinity_Map[] = { - 4, 5, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2 + 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 6, 7, 0, 0, 6, 7, 0, 0, 3, 3, + 0, 0, 3, 3, 0, 0, 8, 9, 0, 0, 8, 9, 0, 0, 5, 5, 0, 0, 5, 5, 0, 0, 2, 2, 1, 1, + 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, + 1, 1, 4, 4, 1, 1, 4, 4, 1, 1, 4, 4, 1, 1, 4, 4, 1, 1 }; static size_t RtemsIntrReqSetAffinity_Scope( void *arg, char *buf, size_t n ) @@ -625,17 +739,44 @@ static inline RtemsIntrReqSetAffinity_Entry RtemsIntrReqSetAffinity_PopEntry( ]; } +static void RtemsIntrReqSetAffinity_SetPreConditionStates( + RtemsIntrReqSetAffinity_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + + if ( ctx->Map.entry.Pre_CPUSetOnline_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } + + if ( ctx->Map.entry.Pre_CPUSetHuge_NA ) { + ctx->Map.pcs[ 3 ] = RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA; + } else { + ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ]; + } + + ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ]; + + if ( ctx->Map.entry.Pre_CanSetAffinity_NA ) { + ctx->Map.pcs[ 5 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA; + } else { + ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ]; + } +} + static void RtemsIntrReqSetAffinity_TestVariant( RtemsIntrReqSetAffinity_Context *ctx ) { RtemsIntrReqSetAffinity_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); - RtemsIntrReqSetAffinity_Pre_CPUSetKind_Prepare( ctx, ctx->Map.pcs[ 1 ] ); - RtemsIntrReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] ); - RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Prepare( - ctx, - ctx->Map.entry.Pre_CanSetAffinity_NA ? RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA : ctx->Map.pcs[ 3 ] - ); + RtemsIntrReqSetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] ); + RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Prepare( ctx, ctx->Map.pcs[ 2 ] ); + RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Prepare( ctx, ctx->Map.pcs[ 3 ] ); + RtemsIntrReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 4 ] ); + RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Prepare( ctx, ctx->Map.pcs[ 5 ] ); RtemsIntrReqSetAffinity_Action( ctx ); RtemsIntrReqSetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status ); RtemsIntrReqSetAffinity_Post_SetAffinity_Check( @@ -659,28 +800,41 @@ T_TEST_CASE_FIXTURE( ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqSetAffinity_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqSetAffinity_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqSetAffinity_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqSetAffinity_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqSetAffinity_Pre_CPUSetKind_Valid; - ctx->Map.pcs[ 1 ] < RtemsIntrReqSetAffinity_Pre_CPUSetKind_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew; + ctx->Map.pci[ 1 ] < RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSet_Valid; - ctx->Map.pcs[ 2 ] < RtemsIntrReqSetAffinity_Pre_CPUSet_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid; + ctx->Map.pci[ 2 ] < RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA; + ++ctx->Map.pci[ 2 ] ) { for ( - ctx->Map.pcs[ 3 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Yes; - ctx->Map.pcs[ 3 ] < RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA; - ++ctx->Map.pcs[ 3 ] + ctx->Map.pci[ 3 ] = RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero; + ctx->Map.pci[ 3 ] < RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA; + ++ctx->Map.pci[ 3 ] ) { - ctx->Map.entry = RtemsIntrReqSetAffinity_PopEntry( ctx ); - RtemsIntrReqSetAffinity_Prepare( ctx ); - RtemsIntrReqSetAffinity_TestVariant( ctx ); + for ( + ctx->Map.pci[ 4 ] = RtemsIntrReqSetAffinity_Pre_CPUSet_Valid; + ctx->Map.pci[ 4 ] < RtemsIntrReqSetAffinity_Pre_CPUSet_NA; + ++ctx->Map.pci[ 4 ] + ) { + for ( + ctx->Map.pci[ 5 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Yes; + ctx->Map.pci[ 5 ] < RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA; + ++ctx->Map.pci[ 5 ] + ) { + ctx->Map.entry = RtemsIntrReqSetAffinity_PopEntry( ctx ); + RtemsIntrReqSetAffinity_SetPreConditionStates( ctx ); + RtemsIntrReqSetAffinity_Prepare( ctx ); + RtemsIntrReqSetAffinity_TestVariant( ctx ); + } + } } } } diff --git a/testsuites/validation/tc-intr-smp-only.c b/testsuites/validation/tc-intr-smp-only.c new file mode 100644 index 0000000000..4bf596141c --- /dev/null +++ b/testsuites/validation/tc-intr-smp-only.c @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsIntrValIntrSmpOnly + */ + +/* + * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * + * 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 "tx-support.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsIntrValIntrSmpOnly \ + * spec:/rtems/intr/val/intr-smp-only + * + * @ingroup RTEMSTestSuiteTestsuitesValidationSmpOnly0 + * + * @brief Tests some @ref RTEMSAPIClassicIntr directives. + * + * This test case performs the following actions: + * + * - Validate the interrupt lock directives. + * + * - Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expanded to a lock reference + * definition. Check that the lock is available after static + * initialization. + * + * - Check that the lock is available after initialization. + * + * - Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_interrupt_disable() and disabled afterwards. + * + * - Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_acquire_isr() call. Check that the lock is no + * longer available. + * + * - Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. Check that the lock is available afterwards. + * + * - Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_destroy() call. + * + * - Initialize the lock using rtems_interrupt_lock_initialize(). Check that + * the lock is available after initialization. + * + * - Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_acquire() and disabled afterwards. Check that the + * lock is no longer available. + * + * - Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. Check that the lock is available afterwards. + * + * - Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_destroy() call. + * + * @{ + */ + +RTEMS_INTERRUPT_LOCK_DECLARE( static, the_lock ) +RTEMS_INTERRUPT_LOCK_DEFINE( static, the_lock, "name " ) + +/** + * @brief Validate the interrupt lock directives. + */ +static void RtemsIntrValIntrSmpOnly_Action_0( void ) +{ + struct { + int a; + RTEMS_INTERRUPT_LOCK_MEMBER( member ) + int b; + } lock = { + .member = RTEMS_INTERRUPT_LOCK_INITIALIZER( "name" ) + }; + + RTEMS_INTERRUPT_LOCK_REFERENCE( ref, &the_lock ) + rtems_interrupt_lock_context lock_context; + + /* + * Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expanded to a lock reference + * definition. Check that the lock is available after static initialization. + */ + T_true( ISRLockIsAvailable( ref ) ); + + /* + * Check that the lock is available after initialization. + */ + T_true( ISRLockIsAvailable( &lock.member ) ); + + /* + * Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_interrupt_disable() and disabled afterwards. + */ + T_true( AreInterruptsEnabled() ); + T_true( ISRLockIsAvailable( &lock.member ) ); + rtems_interrupt_lock_interrupt_disable( &lock_context ); + T_false( AreInterruptsEnabled() ); + T_true( ISRLockIsAvailable( &lock.member ) ); + + /* + * Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_acquire_isr() call. Check that the lock is no longer + * available. + */ + T_false( AreInterruptsEnabled() ); + T_true( ISRLockIsAvailable( &lock.member ) ); + rtems_interrupt_lock_acquire_isr( &lock.member, &lock_context ); + T_false( AreInterruptsEnabled() ); + T_false( ISRLockIsAvailable( &lock.member ) ); + + /* + * Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. Check that the lock is available afterwards. + */ + T_false( AreInterruptsEnabled() ); + T_false( ISRLockIsAvailable( &lock.member ) ); + rtems_interrupt_lock_release( &lock.member, &lock_context ); + T_true( AreInterruptsEnabled() ); + T_true( ISRLockIsAvailable( &lock.member ) ); + + /* + * Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_destroy() call. + */ + T_true( AreInterruptsEnabled() ); + rtems_interrupt_lock_destroy( &lock.member ); + T_true( AreInterruptsEnabled() ); + + /* + * Initialize the lock using rtems_interrupt_lock_initialize(). Check that + * the lock is available after initialization. + */ + rtems_interrupt_lock_initialize( &lock.member, "name" ); + T_true( ISRLockIsAvailable( &lock.member ) ); + + /* + * Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_acquire() and disabled afterwards. Check that the + * lock is no longer available. + */ + T_true( AreInterruptsEnabled() ); + T_true( ISRLockIsAvailable( &lock.member ) ); + rtems_interrupt_lock_acquire( &lock.member, &lock_context ); + T_false( AreInterruptsEnabled() ); + T_false( ISRLockIsAvailable( &lock.member ) ); + + /* + * Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. Check that the lock is available afterwards. + */ + T_false( AreInterruptsEnabled() ); + T_false( ISRLockIsAvailable( &lock.member ) ); + rtems_interrupt_lock_release( &lock.member, &lock_context ); + T_true( AreInterruptsEnabled() ); + T_true( ISRLockIsAvailable( &lock.member ) ); + + /* + * Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_destroy() call. + */ + T_true( AreInterruptsEnabled() ); + rtems_interrupt_lock_destroy( &lock.member ); + T_true( AreInterruptsEnabled() ); +} + +/** + * @fn void T_case_body_RtemsIntrValIntrSmpOnly( void ) + */ +T_TEST_CASE( RtemsIntrValIntrSmpOnly ) +{ + RtemsIntrValIntrSmpOnly_Action_0(); +} + +/** @} */ diff --git a/testsuites/validation/tc-intr-vector-disable.c b/testsuites/validation/tc-intr-vector-disable.c index fea05a257a..3c7eb11838 100644 --- a/testsuites/validation/tc-intr-vector-disable.c +++ b/testsuites/validation/tc-intr-vector-disable.c @@ -64,7 +64,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqVectorDisable \ * spec:/rtems/intr/req/vector-disable * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -138,6 +138,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 3 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -594,19 +600,32 @@ RtemsIntrReqVectorDisable_PopEntry( RtemsIntrReqVectorDisable_Context *ctx ) ]; } +static void RtemsIntrReqVectorDisable_SetPreConditionStates( + RtemsIntrReqVectorDisable_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + + if ( ctx->Map.entry.Pre_IsEnabled_NA ) { + ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorDisable_Pre_IsEnabled_NA; + } else { + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + } + + if ( ctx->Map.entry.Pre_CanDisable_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorDisable_Pre_CanDisable_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } +} + static void RtemsIntrReqVectorDisable_TestVariant( RtemsIntrReqVectorDisable_Context *ctx ) { RtemsIntrReqVectorDisable_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); - RtemsIntrReqVectorDisable_Pre_IsEnabled_Prepare( - ctx, - ctx->Map.entry.Pre_IsEnabled_NA ? RtemsIntrReqVectorDisable_Pre_IsEnabled_NA : ctx->Map.pcs[ 1 ] - ); - RtemsIntrReqVectorDisable_Pre_CanDisable_Prepare( - ctx, - ctx->Map.entry.Pre_CanDisable_NA ? RtemsIntrReqVectorDisable_Pre_CanDisable_NA : ctx->Map.pcs[ 2 ] - ); + RtemsIntrReqVectorDisable_Pre_IsEnabled_Prepare( ctx, ctx->Map.pcs[ 1 ] ); + RtemsIntrReqVectorDisable_Pre_CanDisable_Prepare( ctx, ctx->Map.pcs[ 2 ] ); RtemsIntrReqVectorDisable_Action( ctx ); RtemsIntrReqVectorDisable_Post_Status_Check( ctx, @@ -633,21 +652,22 @@ T_TEST_CASE_FIXTURE( ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqVectorDisable_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqVectorDisable_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqVectorDisable_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqVectorDisable_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorDisable_Pre_IsEnabled_Yes; - ctx->Map.pcs[ 1 ] < RtemsIntrReqVectorDisable_Pre_IsEnabled_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqVectorDisable_Pre_IsEnabled_Yes; + ctx->Map.pci[ 1 ] < RtemsIntrReqVectorDisable_Pre_IsEnabled_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorDisable_Pre_CanDisable_Yes; - ctx->Map.pcs[ 2 ] < RtemsIntrReqVectorDisable_Pre_CanDisable_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqVectorDisable_Pre_CanDisable_Yes; + ctx->Map.pci[ 2 ] < RtemsIntrReqVectorDisable_Pre_CanDisable_NA; + ++ctx->Map.pci[ 2 ] ) { ctx->Map.entry = RtemsIntrReqVectorDisable_PopEntry( ctx ); + RtemsIntrReqVectorDisable_SetPreConditionStates( ctx ); RtemsIntrReqVectorDisable_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr-vector-enable.c b/testsuites/validation/tc-intr-vector-enable.c index c0d985a9d0..024953ab48 100644 --- a/testsuites/validation/tc-intr-vector-enable.c +++ b/testsuites/validation/tc-intr-vector-enable.c @@ -64,7 +64,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqVectorEnable \ * spec:/rtems/intr/req/vector-enable * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -138,6 +138,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 3 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -600,19 +606,32 @@ static inline RtemsIntrReqVectorEnable_Entry RtemsIntrReqVectorEnable_PopEntry( ]; } +static void RtemsIntrReqVectorEnable_SetPreConditionStates( + RtemsIntrReqVectorEnable_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + + if ( ctx->Map.entry.Pre_IsEnabled_NA ) { + ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorEnable_Pre_IsEnabled_NA; + } else { + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + } + + if ( ctx->Map.entry.Pre_CanEnable_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorEnable_Pre_CanEnable_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } +} + static void RtemsIntrReqVectorEnable_TestVariant( RtemsIntrReqVectorEnable_Context *ctx ) { RtemsIntrReqVectorEnable_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); - RtemsIntrReqVectorEnable_Pre_IsEnabled_Prepare( - ctx, - ctx->Map.entry.Pre_IsEnabled_NA ? RtemsIntrReqVectorEnable_Pre_IsEnabled_NA : ctx->Map.pcs[ 1 ] - ); - RtemsIntrReqVectorEnable_Pre_CanEnable_Prepare( - ctx, - ctx->Map.entry.Pre_CanEnable_NA ? RtemsIntrReqVectorEnable_Pre_CanEnable_NA : ctx->Map.pcs[ 2 ] - ); + RtemsIntrReqVectorEnable_Pre_IsEnabled_Prepare( ctx, ctx->Map.pcs[ 1 ] ); + RtemsIntrReqVectorEnable_Pre_CanEnable_Prepare( ctx, ctx->Map.pcs[ 2 ] ); RtemsIntrReqVectorEnable_Action( ctx ); RtemsIntrReqVectorEnable_Post_Status_Check( ctx, @@ -639,21 +658,22 @@ T_TEST_CASE_FIXTURE( ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqVectorEnable_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqVectorEnable_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqVectorEnable_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqVectorEnable_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorEnable_Pre_IsEnabled_Yes; - ctx->Map.pcs[ 1 ] < RtemsIntrReqVectorEnable_Pre_IsEnabled_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqVectorEnable_Pre_IsEnabled_Yes; + ctx->Map.pci[ 1 ] < RtemsIntrReqVectorEnable_Pre_IsEnabled_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorEnable_Pre_CanEnable_Yes; - ctx->Map.pcs[ 2 ] < RtemsIntrReqVectorEnable_Pre_CanEnable_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqVectorEnable_Pre_CanEnable_Yes; + ctx->Map.pci[ 2 ] < RtemsIntrReqVectorEnable_Pre_CanEnable_NA; + ++ctx->Map.pci[ 2 ] ) { ctx->Map.entry = RtemsIntrReqVectorEnable_PopEntry( ctx ); + RtemsIntrReqVectorEnable_SetPreConditionStates( ctx ); RtemsIntrReqVectorEnable_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr-vector-is-enabled.c b/testsuites/validation/tc-intr-vector-is-enabled.c index de1d0c2ebb..ea26b80aee 100644 --- a/testsuites/validation/tc-intr-vector-is-enabled.c +++ b/testsuites/validation/tc-intr-vector-is-enabled.c @@ -64,7 +64,7 @@ * @defgroup RTEMSTestCaseRtemsIntrReqVectorIsEnabled \ * spec:/rtems/intr/req/vector-is-enabled * - * @ingroup RTEMSTestSuiteTestsuitesValidation0 + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr * * @{ */ @@ -153,6 +153,12 @@ typedef struct { rtems_status_code status; struct { + /** + * @brief This member defines the pre-condition indices for the next + * action. + */ + size_t pci[ 3 ]; + /** * @brief This member defines the pre-condition states for the next action. */ @@ -584,16 +590,27 @@ RtemsIntrReqVectorIsEnabled_PopEntry( ]; } +static void RtemsIntrReqVectorIsEnabled_SetPreConditionStates( + RtemsIntrReqVectorIsEnabled_Context *ctx +) +{ + ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ]; + ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ]; + + if ( ctx->Map.entry.Pre_IsEnabled_NA ) { + ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA; + } else { + ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ]; + } +} + static void RtemsIntrReqVectorIsEnabled_TestVariant( RtemsIntrReqVectorIsEnabled_Context *ctx ) { RtemsIntrReqVectorIsEnabled_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] ); RtemsIntrReqVectorIsEnabled_Pre_Enabled_Prepare( ctx, ctx->Map.pcs[ 1 ] ); - RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Prepare( - ctx, - ctx->Map.entry.Pre_IsEnabled_NA ? RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA : ctx->Map.pcs[ 2 ] - ); + RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Prepare( ctx, ctx->Map.pcs[ 2 ] ); RtemsIntrReqVectorIsEnabled_Action( ctx ); RtemsIntrReqVectorIsEnabled_Post_Status_Check( ctx, @@ -620,21 +637,22 @@ T_TEST_CASE_FIXTURE( ctx->Map.index = 0; for ( - ctx->Map.pcs[ 0 ] = RtemsIntrReqVectorIsEnabled_Pre_Vector_Valid; - ctx->Map.pcs[ 0 ] < RtemsIntrReqVectorIsEnabled_Pre_Vector_NA; - ++ctx->Map.pcs[ 0 ] + ctx->Map.pci[ 0 ] = RtemsIntrReqVectorIsEnabled_Pre_Vector_Valid; + ctx->Map.pci[ 0 ] < RtemsIntrReqVectorIsEnabled_Pre_Vector_NA; + ++ctx->Map.pci[ 0 ] ) { for ( - ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorIsEnabled_Pre_Enabled_Obj; - ctx->Map.pcs[ 1 ] < RtemsIntrReqVectorIsEnabled_Pre_Enabled_NA; - ++ctx->Map.pcs[ 1 ] + ctx->Map.pci[ 1 ] = RtemsIntrReqVectorIsEnabled_Pre_Enabled_Obj; + ctx->Map.pci[ 1 ] < RtemsIntrReqVectorIsEnabled_Pre_Enabled_NA; + ++ctx->Map.pci[ 1 ] ) { for ( - ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Yes; - ctx->Map.pcs[ 2 ] < RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA; - ++ctx->Map.pcs[ 2 ] + ctx->Map.pci[ 2 ] = RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Yes; + ctx->Map.pci[ 2 ] < RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA; + ++ctx->Map.pci[ 2 ] ) { ctx->Map.entry = RtemsIntrReqVectorIsEnabled_PopEntry( ctx ); + RtemsIntrReqVectorIsEnabled_SetPreConditionStates( ctx ); RtemsIntrReqVectorIsEnabled_TestVariant( ctx ); } } diff --git a/testsuites/validation/tc-intr.c b/testsuites/validation/tc-intr.c new file mode 100644 index 0000000000..7b2e6b0d48 --- /dev/null +++ b/testsuites/validation/tc-intr.c @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestCaseRtemsIntrValIntr + */ + +/* + * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * + * 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 + +#include "tx-support.h" + +#include + +/** + * @defgroup RTEMSTestCaseRtemsIntrValIntr spec:/rtems/intr/val/intr + * + * @ingroup RTEMSTestSuiteTestsuitesValidationNoClock0 + * + * @brief Tests some @ref RTEMSAPIClassicIntr directives. + * + * This test case performs the following actions: + * + * - Validate rtems_interrupt_local_disable() and + * rtems_interrupt_local_enable(). + * + * - Check that maskable interrupts are enabled before the call to + * rtems_interrupt_local_disable() and disabled afterwards. + * + * - Check that maskable interrupts are disabled before the call to + * rtems_interrupt_local_disable() and disabled afterwards. + * + * - Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_local_enable() according to the ``_isr_cookie`` + * parameter. In this case maskable interrupts are still disabled + * afterwards. + * + * - Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_local_enable() according to the ``_isr_cookie`` + * parameter. In this case maskable interrupts are enabled afterwards. + * + * - Validate the interrupt lock directives. + * + * - Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_interrupt_disable() and disabled afterwards. + * + * - Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_acquire_isr() call. + * + * - Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. + * + * - Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_acquire() and disabled afterwards. + * + * - Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. + * + * - Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_destroy() call. + * + * - Validate the interrupt entry initialization. + * + * - Check that the entry is properly initialized by + * RTEMS_INTERRUPT_ENTRY_INITIALIZER(). + * + * - Call rtems_interrupt_entry_initialize(). Check that the entry is + * properly initialized by rtems_interrupt_entry_initialize(). + * + * @{ + */ + +static void EntryRoutine( void *arg ) +{ + (void) arg; +} + +static void EntryRoutine2( void *arg ) +{ + (void) arg; +} + +/** + * @brief Validate rtems_interrupt_local_disable() and + * rtems_interrupt_local_enable(). + */ +static void RtemsIntrValIntr_Action_0( void ) +{ + rtems_interrupt_level level; + rtems_interrupt_level level_2; + + /* + * Check that maskable interrupts are enabled before the call to + * rtems_interrupt_local_disable() and disabled afterwards. + */ + T_true( AreInterruptsEnabled() ); + rtems_interrupt_local_disable( level ); + T_false( AreInterruptsEnabled() ); + + /* + * Check that maskable interrupts are disabled before the call to + * rtems_interrupt_local_disable() and disabled afterwards. + */ + T_false( AreInterruptsEnabled() ); + rtems_interrupt_local_disable( level_2 ); + T_false( AreInterruptsEnabled() ); + + /* + * Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_local_enable() according to the ``_isr_cookie`` parameter. + * In this case maskable interrupts are still disabled afterwards. + */ + T_false( AreInterruptsEnabled() ); + rtems_interrupt_local_enable( level_2 ); + T_false( AreInterruptsEnabled() ); + + /* + * Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_local_enable() according to the ``_isr_cookie`` parameter. + * In this case maskable interrupts are enabled afterwards. + */ + T_false( AreInterruptsEnabled() ); + rtems_interrupt_local_enable( level ); + T_true( AreInterruptsEnabled() ); +} + +/** + * @brief Validate the interrupt lock directives. + */ +static void RtemsIntrValIntr_Action_1( void ) +{ + RTEMS_INTERRUPT_LOCK_DEFINE( , lock, "name" ); + rtems_interrupt_lock_context lock_context; + + /* + * Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_interrupt_disable() and disabled afterwards. + */ + T_true( AreInterruptsEnabled() ); + rtems_interrupt_lock_interrupt_disable( &lock_context ); + T_false( AreInterruptsEnabled() ); + + /* + * Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_acquire_isr() call. + */ + T_false( AreInterruptsEnabled() ); + rtems_interrupt_lock_acquire_isr( &lock, &lock_context ); + T_false( AreInterruptsEnabled() ); + + /* + * Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. + */ + T_false( AreInterruptsEnabled() ); + rtems_interrupt_lock_release( &lock, &lock_context ); + T_true( AreInterruptsEnabled() ); + + /* + * Check that maskable interrupts are disabled before the call to + * rtems_interrupt_lock_acquire() and disabled afterwards. + */ + T_true( AreInterruptsEnabled() ); + rtems_interrupt_lock_acquire( &lock, &lock_context ); + T_false( AreInterruptsEnabled() ); + + /* + * Check that the maskable interrupt status is restored by the call to + * rtems_interrupt_lock_release() according to the ``_lock_context`` + * parameter. + */ + T_false( AreInterruptsEnabled() ); + rtems_interrupt_lock_release( &lock, &lock_context ); + T_true( AreInterruptsEnabled() ); + + /* + * Check that the maskable interrupt status is not changed by the + * rtems_interrupt_lock_destroy() call. + */ + T_true( AreInterruptsEnabled() ); + rtems_interrupt_lock_destroy( &lock ); + T_true( AreInterruptsEnabled() ); +} + +/** + * @brief Validate the interrupt entry initialization. + */ +static void RtemsIntrValIntr_Action_2( void ) +{ + int entry_arg; + int entry_arg_2; + const char entry_info[] = "1"; + const char entry_info_2[] = "1"; + rtems_interrupt_entry entry = RTEMS_INTERRUPT_ENTRY_INITIALIZER( + EntryRoutine, + &entry_arg, + entry_info + ); + + /* + * Check that the entry is properly initialized by + * RTEMS_INTERRUPT_ENTRY_INITIALIZER(). + */ + T_eq_ptr( entry.handler, EntryRoutine ); + T_eq_ptr( entry.arg, &entry_arg ); + T_eq_ptr( entry.next, NULL ); + T_eq_ptr( entry.info, entry_info ); + + /* + * Call rtems_interrupt_entry_initialize(). Check that the entry is properly + * initialized by rtems_interrupt_entry_initialize(). + */ + entry.next = &entry; + rtems_interrupt_entry_initialize( + &entry, + EntryRoutine2, + &entry_arg_2, + entry_info_2 + ); + T_eq_ptr( entry.handler, EntryRoutine2 ); + T_eq_ptr( entry.arg, &entry_arg_2 ); + T_eq_ptr( entry.next, NULL ); + T_eq_ptr( entry.info, entry_info_2 ); +} + +/** + * @fn void T_case_body_RtemsIntrValIntr( void ) + */ +T_TEST_CASE( RtemsIntrValIntr ) +{ + RtemsIntrValIntr_Action_0(); + RtemsIntrValIntr_Action_1(); + RtemsIntrValIntr_Action_2(); +} + +/** @} */ diff --git a/testsuites/validation/ts-validation-intr.c b/testsuites/validation/ts-validation-intr.c new file mode 100644 index 0000000000..1a79608f78 --- /dev/null +++ b/testsuites/validation/ts-validation-intr.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSTestSuiteTestsuitesValidationIntr + */ + +/* + * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * + * 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 + +/** + * @defgroup RTEMSTestSuiteTestsuitesValidationIntr \ + * spec:/testsuites/validation-intr + * + * @ingroup RTEMSTestSuites + * + * @brief This validation test suite provides enough resources to run tests for + * the interrupt controller related directives of the @ref + * RTEMSAPIClassicIntr. + * + * In SMP configurations, up to three scheduler instances using the SMP EDF + * scheduler are provided using up to four processors. + * + * @{ + */ + +const char rtems_test_name[] = "ValidationIntr"; + +#define CONFIGURE_MAXIMUM_PROCESSORS 5 + +#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER + +#include "ts-default.h" + +/** @} */ -- cgit v1.2.3