File indexing completed on 2025-05-11 08:23:42
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 #ifndef _RTEMS_DEV_IRQ_ARM_GICV3_H
0039 #define _RTEMS_DEV_IRQ_ARM_GICV3_H
0040
0041 #include <dev/irq/arm-gic.h>
0042 #include <dev/irq/arm-gic-arch.h>
0043
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif
0047
0048
0049
0050
0051
0052
0053
0054 #define PRIORITY_DEFAULT 127
0055
0056 #define MPIDR_AFFINITY2(val) BSP_FLD64(val, 16, 23)
0057 #define MPIDR_AFFINITY2_GET(reg) BSP_FLD64GET(reg, 16, 23)
0058 #define MPIDR_AFFINITY2_SET(reg, val) BSP_FLD64SET(reg, val, 16, 23)
0059 #define MPIDR_AFFINITY1(val) BSP_FLD64(val, 8, 15)
0060 #define MPIDR_AFFINITY1_GET(reg) BSP_FLD64GET(reg, 8, 15)
0061 #define MPIDR_AFFINITY1_SET(reg, val) BSP_FLD64SET(reg, val, 8, 15)
0062 #define MPIDR_AFFINITY0(val) BSP_FLD64(val, 0, 7)
0063 #define MPIDR_AFFINITY0_GET(reg) BSP_FLD64GET(reg, 0, 7)
0064 #define MPIDR_AFFINITY0_SET(reg, val) BSP_FLD64SET(reg, val, 0, 7)
0065
0066 #define ICC_SGIR_AFFINITY3(val) BSP_FLD64(val, 48, 55)
0067 #define ICC_SGIR_AFFINITY3_GET(reg) BSP_FLD64GET(reg, 48, 55)
0068 #define ICC_SGIR_AFFINITY3_SET(reg, val) BSP_FLD64SET(reg, val, 48, 55)
0069 #define ICC_SGIR_IRM BSP_BIT32(40)
0070 #define ICC_SGIR_AFFINITY2(val) BSP_FLD64(val, 32, 39)
0071 #define ICC_SGIR_AFFINITY2_GET(reg) BSP_FLD64GET(reg, 32, 39)
0072 #define ICC_SGIR_AFFINITY2_SET(reg, val) BSP_FLD64SET(reg, val, 32, 39)
0073 #define ICC_SGIR_INTID(val) BSP_FLD64(val, 24, 27)
0074 #define ICC_SGIR_INTID_GET(reg) BSP_FLD64GET(reg, 24, 27)
0075 #define ICC_SGIR_INTID_SET(reg, val) BSP_FLD64SET(reg, val, 24, 27)
0076 #define ICC_SGIR_AFFINITY1(val) BSP_FLD64(val, 16, 23)
0077 #define ICC_SGIR_AFFINITY1_GET(reg) BSP_FLD64GET(reg, 16, 23)
0078 #define ICC_SGIR_AFFINITY1_SET(reg, val) BSP_FLD64SET(reg, val, 16, 23)
0079 #define ICC_SGIR_CPU_TARGET_LIST(val) BSP_FLD64(val, 0, 15)
0080 #define ICC_SGIR_CPU_TARGET_LIST_GET(reg) BSP_FLD64GET(reg, 0, 15)
0081 #define ICC_SGIR_CPU_TARGET_LIST_SET(reg, val) BSP_FLD64SET(reg, val, 0, 15)
0082
0083 #ifdef ARM_MULTILIB_ARCH_V4
0084
0085 #define ICC_CTLR "p15, 0, %0, c12, c12, 4"
0086
0087
0088 #define ICC_PMR "p15, 0, %0, c4, c6, 0"
0089
0090
0091 #define ICC_BPR0 "p15, 0, %0, c12, c8, 3"
0092 #define ICC_BPR1 "p15, 0, %0, c12, c12, 3"
0093
0094
0095 #define ICC_IAR0 "p15, 0, %0, c12, c8, 0"
0096 #define ICC_IAR1 "p15, 0, %0, c12, c12, 0"
0097
0098
0099 #define ICC_EOIR0 "p15, 0, %0, c12, c8, 1"
0100 #define ICC_EOIR1 "p15, 0, %0, c12, c12, 1"
0101
0102 #define ICC_SRE "p15, 0, %0, c12, c12, 5"
0103
0104 #define ICC_IGRPEN0 "p15, 0, %0, c12, c12, 6"
0105 #define ICC_IGRPEN1 "p15, 0, %0, c12, c12, 7"
0106
0107 #define MPIDR "p15, 0, %0, c0, c0, 5"
0108
0109 #define READ_SR(SR_NAME) \
0110 ({ \
0111 uint32_t value; \
0112 __asm__ volatile("mrc " SR_NAME : "=r" (value) ); \
0113 value; \
0114 })
0115
0116 #define WRITE_SR(SR_NAME, VALUE) \
0117 __asm__ volatile("mcr " SR_NAME " \n" : : "r" (VALUE) );
0118
0119 #define ICC_SGI1 "p15, 0, %Q0, %R0, c12"
0120 #define WRITE64_SR(SR_NAME, VALUE) \
0121 __asm__ volatile("mcrr " SR_NAME " \n" : : "r" (VALUE) );
0122
0123 #else
0124
0125
0126 #define ICC_IGRPEN0_EL1 "S3_0_C12_C12_6, %0"
0127 #define ICC_IGRPEN1_EL1 "S3_0_C12_C12_7, %0"
0128 #define ICC_IGRPEN1_EL3 "S3_6_C12_C12_7, %0"
0129 #define ICC_IGRPEN0 ICC_IGRPEN0_EL1
0130 #define ICC_IGRPEN1 ICC_IGRPEN1_EL1
0131 #define ICC_PMR "S3_0_C4_C6_0, %0"
0132 #define ICC_EOIR1 "S3_0_C12_C12_1, %0"
0133 #define ICC_SRE "S3_0_C12_C12_5, %0"
0134 #define ICC_BPR0 "S3_0_C12_C8_3, %0"
0135 #define ICC_BPR1 "S3_0_C12_C12_3, %0"
0136 #define ICC_CTLR "S3_0_C12_C12_4, %0"
0137 #define ICC_IAR1 "%0, S3_0_C12_C12_0"
0138 #define MPIDR "%0, mpidr_el1"
0139 #define MPIDR_AFFINITY3(val) BSP_FLD64(val, 32, 39)
0140 #define MPIDR_AFFINITY3_GET(reg) BSP_FLD64GET(reg, 32, 39)
0141 #define MPIDR_AFFINITY3_SET(reg, val) BSP_FLD64SET(reg, val, 32, 39)
0142
0143 #define ICC_SGI1 "S3_0_C12_C11_5, %0"
0144 #define WRITE64_SR(SR_NAME, VALUE) \
0145 __asm__ volatile("msr " SR_NAME " \n" : : "r" (VALUE) );
0146 #define WRITE_SR(SR_NAME, VALUE) WRITE64_SR(SR_NAME, VALUE)
0147
0148 #define READ_SR(SR_NAME) \
0149 ({ \
0150 uint64_t value; \
0151 __asm__ volatile("mrs " SR_NAME : "=&r" (value) ); \
0152 value; \
0153 })
0154
0155 #endif
0156
0157 static inline volatile gic_redist *gicv3_get_redist(uint32_t cpu_index)
0158 {
0159 return (volatile gic_redist *)
0160 ((uintptr_t)BSP_ARM_GIC_REDIST_BASE + cpu_index * 0x20000);
0161 }
0162
0163 static inline volatile gic_sgi_ppi *gicv3_get_sgi_ppi(uint32_t cpu_index)
0164 {
0165 return (volatile gic_sgi_ppi *)
0166 ((uintptr_t)BSP_ARM_GIC_REDIST_BASE + cpu_index * 0x20000 + 0x10000);
0167 }
0168
0169 static inline void gicv3_sgi_ppi_enable(
0170 rtems_vector_number vector,
0171 uint32_t cpu_index
0172 )
0173 {
0174 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0175
0176
0177 sgi_ppi->icspigrpr[0] |= 1U << vector;
0178 sgi_ppi->icspigrpmodr[0] &= ~(1U << vector);
0179
0180
0181 sgi_ppi->icspiser[0] = 1U << vector;
0182 }
0183
0184 static inline void gicv3_sgi_ppi_disable(
0185 rtems_vector_number vector,
0186 uint32_t cpu_index
0187 )
0188 {
0189 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0190
0191 sgi_ppi->icspicer[0] = 1U << vector;
0192 }
0193
0194 static inline bool gicv3_sgi_ppi_is_enabled(
0195 rtems_vector_number vector,
0196 uint32_t cpu_index
0197 )
0198 {
0199 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0200
0201 return (sgi_ppi->icspiser[0] & (1U << vector)) != 0;
0202 }
0203
0204 static inline void gicv3_sgi_ppi_set_priority(
0205 rtems_vector_number vector,
0206 uint8_t priority,
0207 uint32_t cpu_index
0208 )
0209 {
0210 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0211
0212 sgi_ppi->icspiprior[vector] = priority;
0213 }
0214
0215 static inline uint8_t gicv3_sgi_ppi_get_priority(
0216 rtems_vector_number vector,
0217 uint32_t cpu_index
0218 )
0219 {
0220 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0221
0222 return sgi_ppi->icspiprior[vector];
0223 }
0224
0225 static inline bool gicv3_sgi_ppi_is_pending(
0226 rtems_vector_number vector,
0227 uint32_t cpu_index
0228 )
0229 {
0230 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0231
0232 return (sgi_ppi->icspispendr[0] & (1U << vector)) != 0;
0233 }
0234
0235 static inline void gicv3_ppi_set_pending(
0236 rtems_vector_number vector,
0237 uint32_t cpu_index
0238 )
0239 {
0240 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0241
0242 sgi_ppi->icspispendr[0] = 1U << vector;
0243 }
0244
0245 static inline void gicv3_ppi_clear_pending(
0246 rtems_vector_number vector,
0247 uint32_t cpu_index
0248 )
0249 {
0250 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0251
0252 sgi_ppi->icspicpendr[0] = 1U << vector;
0253 }
0254
0255 static inline void gicv3_trigger_sgi(
0256 rtems_vector_number vector,
0257 uint32_t targets
0258 )
0259 {
0260 #ifndef ARM_MULTILIB_ARCH_V4
0261 uint64_t mpidr;
0262 #else
0263 uint32_t mpidr;
0264 #endif
0265 mpidr = READ_SR(MPIDR);
0266 uint64_t value = ICC_SGIR_AFFINITY2(MPIDR_AFFINITY2_GET(mpidr))
0267 | ICC_SGIR_INTID(vector)
0268 | ICC_SGIR_AFFINITY1(MPIDR_AFFINITY1_GET(mpidr))
0269 | ICC_SGIR_CPU_TARGET_LIST(targets);
0270 #ifndef ARM_MULTILIB_ARCH_V4
0271 value |= ICC_SGIR_AFFINITY3(MPIDR_AFFINITY3_GET(mpidr));
0272 #endif
0273 WRITE64_SR(ICC_SGI1, value);
0274 }
0275
0276 static inline uint32_t gicv3_get_id_count(volatile gic_dist *dist)
0277 {
0278 uint32_t id_count = GIC_DIST_ICDICTR_IT_LINES_NUMBER_GET(dist->icdictr);
0279
0280 id_count = 32 * (id_count + 1);
0281 id_count = id_count <= 1020 ? id_count : 1020;
0282
0283 return id_count;
0284 }
0285
0286 static void gicv3_init_dist(volatile gic_dist *dist)
0287 {
0288 uint32_t id_count = gicv3_get_id_count(dist);
0289 uint32_t id;
0290
0291 dist->icddcr = GIC_DIST_ICDDCR_ARE_NS | GIC_DIST_ICDDCR_ARE_S
0292 | GIC_DIST_ICDDCR_ENABLE_GRP1S | GIC_DIST_ICDDCR_ENABLE_GRP1NS
0293 | GIC_DIST_ICDDCR_ENABLE_GRP0;
0294
0295 for (id = 0; id < id_count; id += 32) {
0296
0297 dist->icdicer[id / 32] = 0xffffffff;
0298
0299
0300 dist->icdigr[id / 32] = 0xffffffff;
0301 dist->icdigmr[id / 32] = 0;
0302 }
0303
0304 for (id = 0; id < id_count; ++id) {
0305 gic_id_set_priority(dist, id, PRIORITY_DEFAULT);
0306 }
0307
0308 for (id = 32; id < id_count; ++id) {
0309 gic_id_set_targets(dist, id, 0x01);
0310 }
0311 }
0312
0313 static void gicv3_init_cpu_interface(uint32_t cpu_index)
0314 {
0315
0316 #ifdef BSP_ARM_GIC_ICC_SRE
0317 WRITE_SR(ICC_SRE, BSP_ARM_GIC_ICC_SRE);
0318 #endif
0319
0320
0321 #ifdef BSP_ARM_GIC_ICC_PMR
0322 WRITE_SR(ICC_PMR, BSP_ARM_GIC_ICC_PMR);
0323 #endif
0324
0325
0326 #ifdef BSP_ARM_GIC_ICC_BPR0
0327 WRITE_SR(ICC_BPR0, BSP_ARM_GIC_ICC_BPR0);
0328 #endif
0329
0330
0331 #ifdef BSP_ARM_GIC_ICC_BPR1
0332 WRITE_SR(ICC_BPR1, BSP_ARM_GIC_ICC_BPR1);
0333 #endif
0334
0335 volatile gic_redist *redist = gicv3_get_redist(cpu_index);
0336 uint32_t waker = redist->icrwaker;
0337 uint32_t waker_mask = GIC_REDIST_ICRWAKER_PROCESSOR_SLEEP;
0338 waker &= ~waker_mask;
0339 redist->icrwaker = waker;
0340
0341 volatile gic_sgi_ppi *sgi_ppi = gicv3_get_sgi_ppi(cpu_index);
0342
0343 sgi_ppi->icspigrpr[0] = 0xffffffff;
0344 sgi_ppi->icspigrpmodr[0] = 0;
0345 for (int id = 0; id < 32; id++) {
0346 sgi_ppi->icspiprior[id] = PRIORITY_DEFAULT;
0347 }
0348
0349
0350 #ifdef BSP_ARM_GIC_ICC_IGRPEN0
0351 WRITE_SR(ICC_IGRPEN0, BSP_ARM_GIC_ICC_IGRPEN0);
0352 #endif
0353
0354
0355 #ifdef BSP_ARM_GIC_ICC_IGRPEN1
0356 WRITE_SR(ICC_IGRPEN1, BSP_ARM_GIC_ICC_IGRPEN1);
0357 #endif
0358
0359
0360 #ifdef BSP_ARM_GIC_ICC_CTRL
0361 WRITE_SR(ICC_CTLR, BSP_ARM_GIC_ICC_CTRL);
0362 #endif
0363 }
0364
0365 static inline void gicv3_get_attributes(
0366 rtems_vector_number vector,
0367 rtems_interrupt_attributes *attributes
0368 )
0369 {
0370 attributes->is_maskable = true;
0371 attributes->maybe_enable = true;
0372 attributes->maybe_disable = true;
0373 attributes->can_raise = true;
0374 attributes->can_get_priority = true;
0375 attributes->can_set_priority = true;
0376 attributes->maximum_priority = 255;
0377
0378 if ( vector <= ARM_GIC_IRQ_SGI_LAST ) {
0379
0380
0381
0382
0383
0384 attributes->can_raise_on = true;
0385 attributes->cleared_by_acknowledge = true;
0386 attributes->trigger_signal = RTEMS_INTERRUPT_NO_SIGNAL;
0387 } else {
0388 attributes->can_disable = true;
0389 attributes->can_clear = true;
0390 attributes->trigger_signal = RTEMS_INTERRUPT_UNSPECIFIED_SIGNAL;
0391
0392 if ( vector > ARM_GIC_IRQ_PPI_LAST ) {
0393
0394 attributes->can_get_affinity = true;
0395 attributes->can_set_affinity = true;
0396 }
0397 }
0398 }
0399
0400
0401
0402 #ifdef __cplusplus
0403 }
0404 #endif
0405
0406 #endif