summaryrefslogtreecommitdiffstats
path: root/testsuites/validation/tc-intr-entry-install.c
diff options
context:
space:
mode:
Diffstat (limited to 'testsuites/validation/tc-intr-entry-install.c')
-rw-r--r--testsuites/validation/tc-intr-entry-install.c267
1 files changed, 199 insertions, 68 deletions
diff --git a/testsuites/validation/tc-intr-entry-install.c b/testsuites/validation/tc-intr-entry-install.c
index 37583249aa..58c7989dbe 100644
--- a/testsuites/validation/tc-intr-entry-install.c
+++ b/testsuites/validation/tc-intr-entry-install.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqEntryInstall
+ * @ingroup RtemsIntrReqEntryInstall
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,10 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqEntryInstall \
- * spec:/rtems/intr/req/entry-install
+ * @defgroup RtemsIntrReqEntryInstall spec:/rtems/intr/req/entry-install
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -174,9 +173,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
@@ -185,6 +189,12 @@ typedef struct {
rtems_vector_number test_vector;
/**
+ * @brief If this member is true, then the testable interrupt vector was
+ * enabled at the test case begin.
+ */
+ bool test_vector_was_enabled;
+
+ /**
* @brief This member provides the attributes of the testable interrupt
* vector.
*/
@@ -262,7 +272,7 @@ typedef struct {
/**
* @brief This member specifies if the ``entry`` parameter value.
*/
- rtems_interrupt_entry *entry;;
+ rtems_interrupt_entry *entry;
/**
* @brief This member contains the return value of the
@@ -272,6 +282,12 @@ typedef struct {
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.
*/
size_t pcs[ 8 ];
@@ -409,29 +425,63 @@ 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.cleared_by_acknowledge ) {
+ sc = ClearSoftwareInterrupt( 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 )
@@ -469,7 +519,7 @@ static void Action( void *arg )
T_rsc_success( sc );
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized
);
@@ -480,7 +530,7 @@ static void Action( void *arg )
);
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized_during_setup
);
@@ -489,6 +539,11 @@ static void Action( void *arg )
&ctx->enabled_after
);
T_rsc_success( sc );
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ sc = RaiseSoftwareInterrupt( ctx->test_vector );
+ T_rsc_success( sc );
+ }
}
static void VisitInstalled(
@@ -940,7 +995,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 +1005,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 +1013,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 +1029,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 +1057,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 +1115,18 @@ 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();
+ ctx->test_vector = GetTestableInterruptVector( &required );
+ ctx->test_vector_was_enabled = false;
+ (void) rtems_interrupt_vector_is_enabled(
+ ctx->test_vector,
+ &ctx->test_vector_was_enabled
+ );
sc = rtems_interrupt_get_attributes( ctx->test_vector, &ctx->attributes );
T_rsc_success( sc );
}
@@ -1055,11 +1140,35 @@ static void RtemsIntrReqEntryInstall_Setup_Wrap( void *arg )
RtemsIntrReqEntryInstall_Setup( ctx );
}
+static void RtemsIntrReqEntryInstall_Teardown(
+ RtemsIntrReqEntryInstall_Context *ctx
+)
+{
+ if ( ctx->test_vector_was_enabled ) {
+ (void) rtems_interrupt_vector_enable( ctx->test_vector );
+ }
+}
+
+static void RtemsIntrReqEntryInstall_Teardown_Wrap( void *arg )
+{
+ RtemsIntrReqEntryInstall_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsIntrReqEntryInstall_Teardown( ctx );
+}
+
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;
}
@@ -1236,7 +1345,7 @@ static size_t RtemsIntrReqEntryInstall_Scope( void *arg, char *buf, size_t n )
static T_fixture RtemsIntrReqEntryInstall_Fixture = {
.setup = RtemsIntrReqEntryInstall_Setup_Wrap,
.stop = NULL,
- .teardown = NULL,
+ .teardown = RtemsIntrReqEntryInstall_Teardown_Wrap,
.scope = RtemsIntrReqEntryInstall_Scope,
.initial_context = &RtemsIntrReqEntryInstall_Instance
};
@@ -1254,6 +1363,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 +1400,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 +1435,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 );