summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-06-29 15:37:06 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-07-26 19:57:31 +0200
commitf89cf8e8c4996bb00430953ef9947fba33ccaf63 (patch)
treeaa022f916c722b9fff4a2b4b81c0c2d9d86add74
parentbsp/raspberrypi: Add interrupt get/set affinity (diff)
downloadrtems-f89cf8e8c4996bb00430953ef9947fba33ccaf63.tar.bz2
validation: Add CallWithinISR()
Update #3269.
Diffstat (limited to '')
-rw-r--r--spec/build/testsuites/validation/libvalidation.yml1
-rw-r--r--testsuites/validation/tx-call-within-isr.c134
-rw-r--r--testsuites/validation/tx-support.h14
3 files changed, 149 insertions, 0 deletions
diff --git a/spec/build/testsuites/validation/libvalidation.yml b/spec/build/testsuites/validation/libvalidation.yml
index d55d4b9e41..54c7ae0ac0 100644
--- a/spec/build/testsuites/validation/libvalidation.yml
+++ b/spec/build/testsuites/validation/libvalidation.yml
@@ -11,6 +11,7 @@ install: []
install-path: null
links: []
source:
+- testsuites/validation/tx-call-within-isr.c
- testsuites/validation/tx-support.c
target: validation
type: build
diff --git a/testsuites/validation/tx-call-within-isr.c b/testsuites/validation/tx-call-within-isr.c
new file mode 100644
index 0000000000..226647c0bc
--- /dev/null
+++ b/testsuites/validation/tx-call-within-isr.c
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuites
+ *
+ * @brief This source file contains the implementation of CallWithinISR(),
+ * CallWithinISRSubmit(), and CallWithinISRWait().
+ */
+
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+
+#include <rtems/sysinit.h>
+#include <rtems/score/chainimpl.h>
+
+#include <bsp.h>
+
+/* Some target architectures need this variable for <tm27.h> */
+uint32_t Interrupt_nest;
+
+#define _RTEMS_TMTEST27
+
+#include <tm27.h>
+
+typedef struct {
+ Chain_Control pending;
+ RTEMS_INTERRUPT_LOCK_MEMBER( lock )
+} CallWithinISRContext;
+
+static CallWithinISRContext CallWithinISRInstance = {
+#if defined( RTEMS_SMP )
+ .lock = RTEMS_INTERRUPT_LOCK_INITIALIZER( "CallWithinISR" ),
+#endif
+ .pending = CHAIN_INITIALIZER_EMPTY( CallWithinISRInstance.pending )
+};
+
+static void CallWithinISRHandler( rtems_vector_number vector )
+{
+ CallWithinISRContext *ctx;
+
+ (void) vector;
+ ctx = &CallWithinISRInstance;
+
+ while ( true ) {
+ rtems_interrupt_lock_context lock_context;
+ CallWithinISRRequest *request;
+
+ rtems_interrupt_lock_acquire( &ctx->lock, &lock_context );
+ request = (CallWithinISRRequest *)
+ _Chain_Get_unprotected( &ctx->pending );
+ rtems_interrupt_lock_release( &ctx->lock, &lock_context );
+
+ if ( request == NULL ) {
+ break;
+ }
+
+ ( *request->handler )( request->arg );
+ _Atomic_Store_uint( &request->done, 1, ATOMIC_ORDER_RELEASE );
+ }
+}
+
+void CallWithinISR( void ( *handler )( void * ), void *arg )
+{
+ CallWithinISRRequest request;
+
+ request.handler = handler;
+ request.arg = arg;
+ CallWithinISRSubmit( &request );
+ CallWithinISRWait( &request );
+}
+
+void CallWithinISRSubmit( CallWithinISRRequest *request )
+{
+ CallWithinISRContext *ctx;
+ rtems_interrupt_lock_context lock_context;
+
+ ctx = &CallWithinISRInstance;
+
+ rtems_interrupt_lock_acquire( &ctx->lock, &lock_context );
+ _Atomic_Store_uint( &request->done, 0, ATOMIC_ORDER_RELAXED );
+ _Chain_Initialize_node( &request->node );
+ _Chain_Append_unprotected( &ctx->pending, &request->node );
+ rtems_interrupt_lock_release( &ctx->lock, &lock_context );
+
+ Cause_tm27_intr();
+}
+
+void CallWithinISRWait( const CallWithinISRRequest *request )
+{
+ while ( _Atomic_Load_uint( &request->done, ATOMIC_ORDER_ACQUIRE ) == 0 ) {
+ /* Wait */
+ }
+}
+
+static void CallWithinISRInitialize( void )
+{
+ Install_tm27_vector( CallWithinISRHandler );
+}
+
+RTEMS_SYSINIT_ITEM(
+ CallWithinISRInitialize,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
diff --git a/testsuites/validation/tx-support.h b/testsuites/validation/tx-support.h
index 932584b168..9d5a51e461 100644
--- a/testsuites/validation/tx-support.h
+++ b/testsuites/validation/tx-support.h
@@ -38,6 +38,7 @@
#define _TX_SUPPORT_H
#include <rtems.h>
+#include <rtems/score/atomic.h>
#ifdef __cplusplus
extern "C" {
@@ -99,6 +100,19 @@ void RestoreRunnerMode( void );
void RestoreRunnerPriority( void );
+typedef struct {
+ Chain_Node node;
+ void ( *handler )( void * );
+ void *arg;
+ Atomic_Uint done;
+} CallWithinISRRequest;
+
+void CallWithinISR( void ( *handler )( void * ), void *arg );
+
+void CallWithinISRSubmit( CallWithinISRRequest *request );
+
+void CallWithinISRWait( const CallWithinISRRequest *request );
+
/** @} */
#ifdef __cplusplus