source: rtems/testsuites/validation/tx-call-within-isr.c @ 55318d17

Last change on this file since 55318d17 was 55318d17, checked in by Sebastian Huber <sebastian.huber@…>, on 11/11/22 at 15:30:09

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).

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSTestSuites
7 *
8 * @brief This source file contains the implementation of CallWithinISRClear(),
9 *   CallWithinISRGetVector(), CallWithinISR(), CallWithinISRRaise(),
10 *   CallWithinISRSubmit(), and CallWithinISRWait().
11 */
12
13/*
14 * Copyright (C) 2021, 2022 embedded brains GmbH
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 *    notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 *    notice, this list of conditions and the following disclaimer in the
23 *    documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#endif
41
42#include "tx-support.h"
43
44#include <rtems/sysinit.h>
45#include <rtems/score/chainimpl.h>
46
47#include <bsp.h>
48#include <bsp/irq-generic.h>
49
50/* Some target architectures need this variable for <tm27.h> */
51uint32_t Interrupt_nest;
52
53#define _RTEMS_TMTEST27
54
55#include <tm27.h>
56
57typedef struct {
58  Chain_Control pending;
59  RTEMS_INTERRUPT_LOCK_MEMBER( lock )
60} CallWithinISRContext;
61
62static CallWithinISRContext CallWithinISRInstance = {
63#if defined( RTEMS_SMP )
64  .lock = RTEMS_INTERRUPT_LOCK_INITIALIZER( "CallWithinISR" ),
65#endif
66  .pending = CHAIN_INITIALIZER_EMPTY( CallWithinISRInstance.pending )
67};
68
69void CallWithinISRRaise( void )
70{
71  Cause_tm27_intr();
72}
73
74void CallWithinISRClear( void )
75{
76  Clear_tm27_intr();
77}
78
79static void CallWithinISRHandler( rtems_vector_number vector )
80{
81  CallWithinISRContext *ctx;
82
83  (void) vector;
84  ctx = &CallWithinISRInstance;
85
86  CallWithinISRClear();
87
88  while ( true ) {
89    rtems_interrupt_lock_context lock_context;
90    CallWithinISRRequest        *request;
91
92    rtems_interrupt_lock_acquire( &ctx->lock, &lock_context );
93    request = (CallWithinISRRequest *)
94      _Chain_Get_unprotected( &ctx->pending );
95    rtems_interrupt_lock_release( &ctx->lock, &lock_context );
96
97    if ( request == NULL ) {
98      break;
99    }
100
101    ( *request->handler )( request->arg );
102    _Atomic_Store_uint( &request->done, 1, ATOMIC_ORDER_RELEASE );
103  }
104}
105
106void CallWithinISR( void ( *handler )( void * ), void *arg )
107{
108  CallWithinISRRequest request;
109
110  request.handler = handler;
111  request.arg = arg;
112  CallWithinISRSubmit( &request );
113  CallWithinISRWait( &request );
114}
115
116void CallWithinISRSubmit( CallWithinISRRequest *request )
117{
118  CallWithinISRContext        *ctx;
119  rtems_interrupt_lock_context lock_context;
120
121  ctx = &CallWithinISRInstance;
122
123  rtems_interrupt_lock_acquire( &ctx->lock, &lock_context );
124  _Atomic_Store_uint( &request->done, 0, ATOMIC_ORDER_RELAXED );
125  _Chain_Initialize_node( &request->node );
126  _Chain_Append_unprotected( &ctx->pending, &request->node );
127  rtems_interrupt_lock_release( &ctx->lock, &lock_context );
128
129  CallWithinISRRaise();
130}
131
132void CallWithinISRWait( const CallWithinISRRequest *request )
133{
134  while ( _Atomic_Load_uint( &request->done, ATOMIC_ORDER_ACQUIRE ) == 0 ) {
135    /* Wait */
136  }
137}
138
139static void CallWithinISRIsHandlerInstalled(
140  void                   *arg,
141  const char             *info,
142  rtems_option            option,
143  rtems_interrupt_handler handler,
144  void                   *handler_arg
145)
146{
147  (void) info;
148  (void) option;
149  (void) handler_arg;
150
151  if ( handler == (rtems_interrupt_handler) CallWithinISRHandler ) {
152    *(bool *) arg = true;
153  }
154}
155
156rtems_vector_number CallWithinISRGetVector( void )
157{
158  rtems_vector_number vector;
159
160  for ( vector = 0; vector < BSP_INTERRUPT_VECTOR_COUNT; ++vector ) {
161    bool installed;
162
163    installed = false;
164    (void) rtems_interrupt_handler_iterate(
165      vector,
166      CallWithinISRIsHandlerInstalled,
167      &installed
168    );
169
170    if ( installed ) {
171      return vector;
172    }
173  }
174
175  return UINT32_MAX;
176}
177
178static void CallWithinISRInitialize( void )
179{
180  Install_tm27_vector( CallWithinISRHandler );
181}
182
183RTEMS_SYSINIT_ITEM(
184  CallWithinISRInitialize,
185  RTEMS_SYSINIT_DEVICE_DRIVERS,
186  RTEMS_SYSINIT_ORDER_MIDDLE
187);
Note: See TracBrowser for help on using the repository browser.