File indexing completed on 2025-05-11 08:24:54
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #ifdef HAVE_CONFIG_H
0039 #include "config.h"
0040 #endif
0041
0042 #include "tx-support.h"
0043
0044 #include <rtems/sysinit.h>
0045 #include <rtems/score/chainimpl.h>
0046
0047 #include <bsp.h>
0048 #include <bsp/irq-generic.h>
0049
0050
0051 uint32_t Interrupt_nest;
0052
0053 #define _RTEMS_TMTEST27
0054
0055 #include <tm27.h>
0056
0057 typedef struct {
0058 Chain_Control pending;
0059 RTEMS_INTERRUPT_LOCK_MEMBER( lock )
0060 } CallWithinISRContext;
0061
0062 static CallWithinISRContext CallWithinISRInstance = {
0063 #if defined( RTEMS_SMP )
0064 .lock = RTEMS_INTERRUPT_LOCK_INITIALIZER( "CallWithinISR" ),
0065 #endif
0066 .pending = CHAIN_INITIALIZER_EMPTY( CallWithinISRInstance.pending )
0067 };
0068
0069 void CallWithinISRRaise( void )
0070 {
0071 Cause_tm27_intr();
0072 }
0073
0074 void CallWithinISRClear( void )
0075 {
0076 Clear_tm27_intr();
0077 }
0078
0079 #ifdef TM27_USE_VECTOR_HANDLER
0080 static rtems_isr CallWithinISRHandler( rtems_vector_number arg )
0081 #else
0082 static void CallWithinISRHandler( void *arg )
0083 #endif
0084 {
0085 CallWithinISRContext *ctx;
0086
0087 (void) arg;
0088 ctx = &CallWithinISRInstance;
0089
0090 CallWithinISRClear();
0091
0092 while ( true ) {
0093 rtems_interrupt_lock_context lock_context;
0094 CallWithinISRRequest *request;
0095
0096 rtems_interrupt_lock_acquire( &ctx->lock, &lock_context );
0097 request = (CallWithinISRRequest *)
0098 _Chain_Get_unprotected( &ctx->pending );
0099 rtems_interrupt_lock_release( &ctx->lock, &lock_context );
0100
0101 if ( request == NULL ) {
0102 break;
0103 }
0104
0105 ( *request->handler )( request->arg );
0106 _Atomic_Store_uint( &request->done, 1, ATOMIC_ORDER_RELEASE );
0107 }
0108 }
0109
0110 void CallWithinISR( void ( *handler )( void * ), void *arg )
0111 {
0112 CallWithinISRRequest request;
0113
0114 request.handler = handler;
0115 request.arg = arg;
0116 CallWithinISRSubmit( &request );
0117 CallWithinISRWait( &request );
0118 }
0119
0120 void CallWithinISRSubmit( CallWithinISRRequest *request )
0121 {
0122 CallWithinISRContext *ctx;
0123 rtems_interrupt_lock_context lock_context;
0124
0125 ctx = &CallWithinISRInstance;
0126
0127 rtems_interrupt_lock_acquire( &ctx->lock, &lock_context );
0128 _Atomic_Store_uint( &request->done, 0, ATOMIC_ORDER_RELAXED );
0129 _Chain_Initialize_node( &request->node );
0130 _Chain_Append_unprotected( &ctx->pending, &request->node );
0131 rtems_interrupt_lock_release( &ctx->lock, &lock_context );
0132
0133 CallWithinISRRaise();
0134 }
0135
0136 void CallWithinISRWait( const CallWithinISRRequest *request )
0137 {
0138 while ( _Atomic_Load_uint( &request->done, ATOMIC_ORDER_ACQUIRE ) == 0 ) {
0139
0140 }
0141 }
0142
0143 #if !defined( TM27_INTERRUPT_VECTOR_DEFAULT )
0144 static void CallWithinISRIsHandlerInstalled(
0145 void *arg,
0146 const char *info,
0147 rtems_option option,
0148 rtems_interrupt_handler handler,
0149 void *handler_arg
0150 )
0151 {
0152 (void) info;
0153 (void) option;
0154 (void) handler_arg;
0155
0156 if ( handler == CallWithinISRHandler && handler_arg == NULL ) {
0157 *(bool *) arg = true;
0158 }
0159 }
0160 #endif
0161
0162 rtems_vector_number CallWithinISRGetVector( void )
0163 {
0164 #if defined( TM27_INTERRUPT_VECTOR_DEFAULT )
0165 return TM27_INTERRUPT_VECTOR_DEFAULT;
0166 #else
0167 rtems_vector_number vector;
0168
0169 for ( vector = 0; vector < BSP_INTERRUPT_VECTOR_COUNT; ++vector ) {
0170 bool installed;
0171
0172 installed = false;
0173 (void) rtems_interrupt_handler_iterate(
0174 vector,
0175 CallWithinISRIsHandlerInstalled,
0176 &installed
0177 );
0178
0179 if ( installed ) {
0180 return vector;
0181 }
0182 }
0183
0184 return UINT32_MAX;
0185 #endif
0186 }
0187
0188 rtems_vector_number GetSoftwareInterruptVector( void )
0189 {
0190 #if defined( TM27_INTERRUPT_VECTOR_ALTERNATIVE )
0191 return TM27_INTERRUPT_VECTOR_ALTERNATIVE;
0192 #else
0193 return UINT32_MAX;
0194 #endif
0195 }
0196
0197 rtems_status_code RaiseSoftwareInterrupt( rtems_vector_number vector )
0198 {
0199 #if defined( TM27_INTERRUPT_VECTOR_ALTERNATIVE )
0200 if ( vector == TM27_INTERRUPT_VECTOR_ALTERNATIVE ) {
0201 return _TM27_Raise_alternative();
0202 }
0203 #endif
0204
0205 return rtems_interrupt_raise( vector );
0206 }
0207
0208 rtems_status_code ClearSoftwareInterrupt( rtems_vector_number vector )
0209 {
0210 #if defined( TM27_INTERRUPT_VECTOR_ALTERNATIVE )
0211 if ( vector == TM27_INTERRUPT_VECTOR_ALTERNATIVE ) {
0212 return _TM27_Clear_alternative();
0213 }
0214 #endif
0215
0216 return rtems_interrupt_clear( vector );
0217 }
0218
0219 static void CallWithinISRInitialize( void )
0220 {
0221 Install_tm27_vector( CallWithinISRHandler );
0222 }
0223
0224 RTEMS_SYSINIT_ITEM(
0225 CallWithinISRInitialize,
0226 RTEMS_SYSINIT_DEVICE_DRIVERS,
0227 RTEMS_SYSINIT_ORDER_MIDDLE
0228 );