From 55318d17b40e491839c874ecbb342925c9b1e5ea Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 11 Nov 2022 16:30:09 +0100 Subject: validation: Improve spurious interrupt test case Use the tm27 support to test a spurious interrupt. This helps to run the validation test case on targets which have no software interrupt available for tests (for example riscv/PLIC/CLINT in the SMP configuration). --- testsuites/validation/tc-bsp-interrupt-spurious.c | 40 ++++++--------- testsuites/validation/tx-call-within-isr.c | 59 +++++++++++++++++++++-- testsuites/validation/tx-support.h | 6 +++ 3 files changed, 76 insertions(+), 29 deletions(-) diff --git a/testsuites/validation/tc-bsp-interrupt-spurious.c b/testsuites/validation/tc-bsp-interrupt-spurious.c index f5e992a51d..eb3c98e30a 100644 --- a/testsuites/validation/tc-bsp-interrupt-spurious.c +++ b/testsuites/validation/tc-bsp-interrupt-spurious.c @@ -109,6 +109,12 @@ typedef struct { * @brief Test context for spec:/bsp/req/interrupt-spurious test case. */ typedef struct { + /** + * @brief This member references the interrupt entry to restore during test + * case teardown. + */ + rtems_interrupt_entry *entry_to_restore; + /** * @brief This member provides a jump buffer to return from the fatal error. */ @@ -119,11 +125,6 @@ typedef struct { */ 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. */ @@ -234,14 +235,7 @@ static void Disable( const Context *ctx ) 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 ); - } - + CallWithinISRClear(); Disable( ctx ); } @@ -424,20 +418,15 @@ static void BspReqInterruptSpurious_Setup( BspReqInterruptSpurious_Context *ctx ) { - rtems_interrupt_attributes attr = { - .can_raise = true - }; rtems_status_code sc; - ctx->test_vector = GetTestableInterruptVector( &attr ); + ctx->first = NULL; + ctx->test_vector = CallWithinISRGetVector(); 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; + ctx->entry_to_restore = *ctx->first; rtems_interrupt_entry_initialize( &ctx->entry, EntryRoutine, ctx, "Info" ); test_case_active = true; @@ -459,6 +448,10 @@ static void BspReqInterruptSpurious_Teardown( { SetFatalHandler( NULL, NULL ); test_case_active = false; + + if ( ctx->first != NULL ) { + *ctx->first = ctx->entry_to_restore; + } } static void BspReqInterruptSpurious_Teardown_Wrap( void *arg ) @@ -487,12 +480,9 @@ static void BspReqInterruptSpurious_Action( } else #endif { - rtems_status_code sc; - (void) rtems_interrupt_vector_enable( ctx->test_vector ); - sc = rtems_interrupt_raise( ctx->test_vector ); - T_rsc_success( sc ); + CallWithinISRRaise(); while ( !ctx->interrupt_occurred ) { /* Wait */ diff --git a/testsuites/validation/tx-call-within-isr.c b/testsuites/validation/tx-call-within-isr.c index 3b5d1e139d..0767f96edf 100644 --- a/testsuites/validation/tx-call-within-isr.c +++ b/testsuites/validation/tx-call-within-isr.c @@ -5,12 +5,13 @@ * * @ingroup RTEMSTestSuites * - * @brief This source file contains the implementation of CallWithinISR(), + * @brief This source file contains the implementation of CallWithinISRClear(), + * CallWithinISRGetVector(), CallWithinISR(), CallWithinISRRaise(), * CallWithinISRSubmit(), and CallWithinISRWait(). */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021, 2022 embedded brains GmbH * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -44,6 +45,7 @@ #include #include +#include /* Some target architectures need this variable for */ uint32_t Interrupt_nest; @@ -64,6 +66,16 @@ static CallWithinISRContext CallWithinISRInstance = { .pending = CHAIN_INITIALIZER_EMPTY( CallWithinISRInstance.pending ) }; +void CallWithinISRRaise( void ) +{ + Cause_tm27_intr(); +} + +void CallWithinISRClear( void ) +{ + Clear_tm27_intr(); +} + static void CallWithinISRHandler( rtems_vector_number vector ) { CallWithinISRContext *ctx; @@ -71,7 +83,7 @@ static void CallWithinISRHandler( rtems_vector_number vector ) (void) vector; ctx = &CallWithinISRInstance; - Clear_tm27_intr(); + CallWithinISRClear(); while ( true ) { rtems_interrupt_lock_context lock_context; @@ -114,7 +126,7 @@ void CallWithinISRSubmit( CallWithinISRRequest *request ) _Chain_Append_unprotected( &ctx->pending, &request->node ); rtems_interrupt_lock_release( &ctx->lock, &lock_context ); - Cause_tm27_intr(); + CallWithinISRRaise(); } void CallWithinISRWait( const CallWithinISRRequest *request ) @@ -124,6 +136,45 @@ void CallWithinISRWait( const CallWithinISRRequest *request ) } } +static void CallWithinISRIsHandlerInstalled( + void *arg, + const char *info, + rtems_option option, + rtems_interrupt_handler handler, + void *handler_arg +) +{ + (void) info; + (void) option; + (void) handler_arg; + + if ( handler == (rtems_interrupt_handler) CallWithinISRHandler ) { + *(bool *) arg = true; + } +} + +rtems_vector_number CallWithinISRGetVector( void ) +{ + rtems_vector_number vector; + + for ( vector = 0; vector < BSP_INTERRUPT_VECTOR_COUNT; ++vector ) { + bool installed; + + installed = false; + (void) rtems_interrupt_handler_iterate( + vector, + CallWithinISRIsHandlerInstalled, + &installed + ); + + if ( installed ) { + return vector; + } + } + + return UINT32_MAX; +} + static void CallWithinISRInitialize( void ) { Install_tm27_vector( CallWithinISRHandler ); diff --git a/testsuites/validation/tx-support.h b/testsuites/validation/tx-support.h index 20f74faa2d..89152d66c0 100644 --- a/testsuites/validation/tx-support.h +++ b/testsuites/validation/tx-support.h @@ -390,6 +390,12 @@ void CallWithinISRSubmit( CallWithinISRRequest *request ); void CallWithinISRWait( const CallWithinISRRequest *request ); +void CallWithinISRRaise( void ); + +void CallWithinISRClear( void ); + +rtems_vector_number CallWithinISRGetVector( void ); + typedef struct { Thread_queue_Operations tq_ops; const Thread_queue_Operations *wrapped_ops; -- cgit v1.2.3