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 #ifdef HAVE_CONFIG_H
0038 #include "config.h"
0039 #endif
0040
0041 #include "tx-support.h"
0042
0043 #include <rtems/irq-extension.h>
0044 #include <rtems/test.h>
0045
0046 #include <bsp/irq-generic.h>
0047
0048 static bool HasRequiredAttributes(
0049 const rtems_interrupt_attributes *required,
0050 const rtems_interrupt_attributes *actual
0051 )
0052 {
0053 if ( required == NULL ) {
0054 return true;
0055 }
0056
0057 if ( required->can_get_affinity && !actual->can_get_affinity ) {
0058 return false;
0059 }
0060
0061 if ( required->can_raise && !actual->can_raise ) {
0062 return false;
0063 }
0064
0065 if ( required->can_raise_on && !actual->can_raise_on ) {
0066 return false;
0067 }
0068
0069 return true;
0070 }
0071
0072 rtems_vector_number GetValidInterruptVectorNumber(
0073 const rtems_interrupt_attributes *required
0074 )
0075 {
0076 rtems_vector_number vector;
0077
0078 for ( vector = 0; vector < BSP_INTERRUPT_VECTOR_COUNT; ++vector ) {
0079 rtems_status_code sc;
0080 rtems_interrupt_attributes attr;
0081
0082 sc = rtems_interrupt_get_attributes( vector, &attr );
0083
0084 if ( sc == RTEMS_SUCCESSFUL && HasRequiredAttributes( required, &attr ) ) {
0085 break;
0086 }
0087 }
0088
0089 return vector;
0090 }
0091
0092 rtems_vector_number GetTestableInterruptVector(
0093 const rtems_interrupt_attributes *required
0094 )
0095 {
0096 rtems_vector_number vector;
0097
0098 for ( vector = 0; vector < BSP_INTERRUPT_VECTOR_COUNT; ++vector ) {
0099 rtems_status_code sc;
0100 rtems_interrupt_attributes attr;
0101
0102 sc = rtems_interrupt_get_attributes( vector, &attr );
0103
0104 if ( sc != RTEMS_SUCCESSFUL ) {
0105 continue;
0106 }
0107
0108 if ( !attr.is_maskable ) {
0109 continue;
0110 }
0111
0112 if ( !HasRequiredAttributes( required, &attr ) ) {
0113 continue;
0114 }
0115
0116 if ( HasInterruptVectorEntriesInstalled( vector ) ) {
0117 continue;
0118 }
0119
0120 if ( attr.can_enable && attr.can_disable ) {
0121 break;
0122 }
0123
0124 if (
0125 attr.maybe_enable && attr.maybe_disable &&
0126 !attr.can_be_triggered_by_message &&
0127 attr.trigger_signal == RTEMS_INTERRUPT_NO_SIGNAL
0128 ) {
0129 rtems_status_code sc;
0130 bool enabled;
0131
0132 (void) rtems_interrupt_vector_enable( vector );
0133 sc = rtems_interrupt_vector_is_enabled( vector, &enabled );
0134
0135 if ( sc == RTEMS_SUCCESSFUL && enabled ) {
0136 (void) rtems_interrupt_vector_disable( vector );
0137 break;
0138 }
0139 }
0140 }
0141
0142 if ( vector == BSP_INTERRUPT_VECTOR_COUNT ) {
0143 vector = GetSoftwareInterruptVector();
0144 }
0145
0146 return vector;
0147 }
0148
0149 static void HasInstalled(
0150 void *arg,
0151 const char *info,
0152 rtems_option options,
0153 rtems_interrupt_handler handler_routine,
0154 void *handler_arg
0155 )
0156 {
0157 bool *has_installed_entries;
0158
0159 (void) info;
0160 (void) options;
0161 (void) handler_routine;
0162 (void) handler_arg;
0163
0164 has_installed_entries = arg;
0165 *has_installed_entries = true;
0166 }
0167
0168 bool HasInterruptVectorEntriesInstalled( rtems_vector_number vector )
0169 {
0170 bool has_installed_entries;
0171 rtems_status_code sc;
0172
0173 has_installed_entries = false;
0174 sc = rtems_interrupt_handler_iterate(
0175 vector,
0176 HasInstalled,
0177 &has_installed_entries
0178 );
0179 T_quiet_rsc_success( sc );
0180
0181 return has_installed_entries;
0182 }