File indexing completed on 2025-05-11 08:24:04
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 #include <dev/irq/arm-gicv3.h>
0038
0039 #include <bsp/irq-generic.h>
0040 #include <bsp/start.h>
0041 #include <rtems/score/processormaskimpl.h>
0042
0043
0044
0045
0046
0047
0048 #if BSP_INTERRUPT_VECTOR_COUNT > 1020
0049 #error "BSP_INTERRUPT_VECTOR_COUNT is too large"
0050 #endif
0051
0052 void bsp_interrupt_dispatch(void)
0053 {
0054 while (true) {
0055 uint32_t icciar = READ_SR(ICC_IAR1);
0056 rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
0057 uint32_t status;
0058
0059 if (!bsp_interrupt_is_valid_vector(vector)) {
0060 break;
0061 }
0062
0063 status = arm_interrupt_enable_interrupts();
0064 bsp_interrupt_handler_dispatch_unchecked(vector);
0065 arm_interrupt_restore_interrupts(status);
0066
0067 WRITE_SR(ICC_EOIR1, icciar);
0068 }
0069 }
0070
0071 rtems_status_code bsp_interrupt_get_attributes(
0072 rtems_vector_number vector,
0073 rtems_interrupt_attributes *attributes
0074 )
0075 {
0076 gicv3_get_attributes(vector, attributes);
0077 return RTEMS_SUCCESSFUL;
0078 }
0079
0080 rtems_status_code bsp_interrupt_is_pending(
0081 rtems_vector_number vector,
0082 bool *pending
0083 )
0084 {
0085 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0086 bsp_interrupt_assert(pending != NULL);
0087
0088 if (vector <= ARM_GIC_IRQ_PPI_LAST) {
0089 *pending = gicv3_sgi_ppi_is_pending(vector, _SMP_Get_current_processor());
0090 } else {
0091 volatile gic_dist *dist = ARM_GIC_DIST;
0092
0093 *pending = gic_id_is_pending(dist, vector);
0094 }
0095
0096 return RTEMS_SUCCESSFUL;
0097 }
0098
0099 rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
0100 {
0101 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0102
0103 if (vector <= ARM_GIC_IRQ_SGI_LAST) {
0104 arm_gic_trigger_sgi(vector, 1U << _SMP_Get_current_processor());
0105 } else if (vector <= ARM_GIC_IRQ_PPI_LAST) {
0106 gicv3_ppi_set_pending(vector, _SMP_Get_current_processor());
0107 } else {
0108 volatile gic_dist *dist = ARM_GIC_DIST;
0109
0110 gic_id_set_pending(dist, vector);
0111 }
0112
0113 return RTEMS_SUCCESSFUL;
0114 }
0115
0116 #if defined(RTEMS_SMP)
0117 rtems_status_code bsp_interrupt_raise_on(
0118 rtems_vector_number vector,
0119 uint32_t cpu_index
0120 )
0121 {
0122 if (vector >= 16) {
0123 return RTEMS_UNSATISFIED;
0124 }
0125
0126 arm_gic_trigger_sgi(vector, 1U << cpu_index);
0127 return RTEMS_SUCCESSFUL;
0128 }
0129 #endif
0130
0131 rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
0132 {
0133 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0134
0135 if (vector <= ARM_GIC_IRQ_SGI_LAST) {
0136 return RTEMS_UNSATISFIED;
0137 }
0138
0139 if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
0140 gicv3_ppi_clear_pending(vector, _SMP_Get_current_processor());
0141 } else {
0142 volatile gic_dist *dist = ARM_GIC_DIST;
0143
0144 gic_id_clear_pending(dist, vector);
0145 }
0146
0147 return RTEMS_SUCCESSFUL;
0148 }
0149
0150 rtems_status_code bsp_interrupt_vector_is_enabled(
0151 rtems_vector_number vector,
0152 bool *enabled
0153 )
0154 {
0155 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0156 bsp_interrupt_assert(enabled != NULL);
0157
0158 if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
0159 *enabled = gicv3_sgi_ppi_is_enabled(vector, _SMP_Get_current_processor());
0160 } else {
0161 volatile gic_dist *dist = ARM_GIC_DIST;
0162
0163 *enabled = gic_id_is_enabled(dist, vector);
0164 }
0165
0166 return RTEMS_SUCCESSFUL;
0167 }
0168
0169 rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
0170 {
0171
0172 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0173
0174 if (vector > ARM_GIC_IRQ_PPI_LAST) {
0175 volatile gic_dist *dist = ARM_GIC_DIST;
0176
0177 gic_id_enable(dist, vector);
0178 } else {
0179 gicv3_sgi_ppi_enable(vector, _SMP_Get_current_processor());
0180 }
0181
0182 return RTEMS_SUCCESSFUL;
0183 }
0184
0185 rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
0186 {
0187 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0188
0189 if (vector > ARM_GIC_IRQ_PPI_LAST) {
0190 volatile gic_dist *dist = ARM_GIC_DIST;
0191
0192 gic_id_disable(dist, vector);
0193 } else {
0194 gicv3_sgi_ppi_disable(vector, _SMP_Get_current_processor());
0195 }
0196
0197 return RTEMS_SUCCESSFUL;
0198 }
0199
0200 void bsp_interrupt_facility_initialize(void)
0201 {
0202 arm_interrupt_facility_set_exception_handler();
0203 gicv3_init_dist(ARM_GIC_DIST);
0204 gicv3_init_cpu_interface(_SMP_Get_current_processor());
0205 }
0206
0207 #ifdef RTEMS_SMP
0208 BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void)
0209 {
0210 gicv3_init_cpu_interface(_SMP_Get_current_processor());
0211 }
0212 #endif
0213
0214 rtems_status_code bsp_interrupt_set_priority(
0215 rtems_vector_number vector,
0216 uint32_t priority
0217 )
0218 {
0219 uint8_t gic_priority = (uint8_t) priority;
0220
0221 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0222
0223 if (gic_priority != priority) {
0224 return RTEMS_INVALID_PRIORITY;
0225 }
0226
0227 if (vector >= 32) {
0228 volatile gic_dist *dist = ARM_GIC_DIST;
0229 gic_id_set_priority(dist, vector, priority);
0230 } else {
0231 gicv3_sgi_ppi_set_priority(
0232 vector,
0233 priority,
0234 _SMP_Get_current_processor()
0235 );
0236 }
0237
0238 return RTEMS_SUCCESSFUL;
0239 }
0240
0241 rtems_status_code bsp_interrupt_get_priority(
0242 rtems_vector_number vector,
0243 uint32_t *priority
0244 )
0245 {
0246 bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
0247 bsp_interrupt_assert(priority != NULL);
0248
0249 if (vector >= 32) {
0250 volatile gic_dist *dist = ARM_GIC_DIST;
0251 *priority = gic_id_get_priority(dist, vector);
0252 } else {
0253 *priority = gicv3_sgi_ppi_get_priority(
0254 vector,
0255 _SMP_Get_current_processor()
0256 );
0257 }
0258
0259 return RTEMS_SUCCESSFUL;
0260 }
0261
0262 #if defined(BSP_IRQ_HAVE_GET_SET_AFFINITY)
0263 rtems_status_code bsp_interrupt_set_affinity(
0264 rtems_vector_number vector,
0265 const Processor_mask *affinity
0266 )
0267 {
0268 volatile gic_dist *dist = ARM_GIC_DIST;
0269 uint8_t targets = (uint8_t) _Processor_mask_To_uint32_t(affinity, 0);
0270
0271 if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
0272 return RTEMS_UNSATISFIED;
0273 }
0274
0275 gic_id_set_targets(dist, vector, targets);
0276 return RTEMS_SUCCESSFUL;
0277 }
0278
0279 rtems_status_code bsp_interrupt_get_affinity(
0280 rtems_vector_number vector,
0281 Processor_mask *affinity
0282 )
0283 {
0284 volatile gic_dist *dist = ARM_GIC_DIST;
0285 uint8_t targets;
0286
0287 if ( vector <= ARM_GIC_IRQ_PPI_LAST ) {
0288 return RTEMS_UNSATISFIED;
0289 }
0290
0291 targets = gic_id_get_targets(dist, vector);
0292 _Processor_mask_From_uint32_t(affinity, targets, 0);
0293 return RTEMS_SUCCESSFUL;
0294 }
0295 #endif
0296
0297 void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
0298 {
0299 gicv3_trigger_sgi(vector, targets);
0300 }
0301
0302 #ifdef RTEMS_SMP
0303 uint32_t arm_gic_irq_processor_count(void)
0304 {
0305 volatile gic_dist *dist = ARM_GIC_DIST;
0306 uint32_t cpu_count;
0307
0308 if ((dist->icddcr & GIC_DIST_ICDDCR_ARE_S) == 0) {
0309 cpu_count = GIC_DIST_ICDICTR_CPU_NUMBER_GET(dist->icdictr) + 1;
0310 } else {
0311 int i;
0312
0313
0314 cpu_count = 0;
0315
0316 for (i = 0; i < CPU_MAXIMUM_PROCESSORS; ++i) {
0317 volatile gic_redist *redist = gicv3_get_redist(i);
0318
0319 ++cpu_count;
0320 if ((redist->icrtyper & GIC_REDIST_ICRTYPER_LAST) != 0) {
0321 break;
0322 }
0323 }
0324 }
0325
0326 return cpu_count;
0327 }
0328 #endif