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 #ifndef LIBBSP_ARM_SHARED_ARM_GIC_H
0038 #define LIBBSP_ARM_SHARED_ARM_GIC_H
0039
0040 #include <dev/irq/arm-gic-regs.h>
0041
0042 #include <stdbool.h>
0043
0044 #ifdef __cplusplus
0045 extern "C" {
0046 #endif
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059 #define GIC_ID_TO_ONE_BIT_REG_INDEX(id) ((id) >> 5)
0060 #define GIC_ID_TO_ONE_BIT_REG_BIT(id) (1U << ((id) & 0x1fU))
0061
0062 #define GIC_ID_TO_TWO_BITS_REG_INDEX(id) ((id) >> 4)
0063 #define GIC_ID_TO_TWO_BITS_REG_OFFSET(id) (((id) & 0xfU) << 1)
0064
0065 static inline bool gic_id_is_enabled(volatile gic_dist *dist, uint32_t id)
0066 {
0067 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0068 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0069
0070 return (dist->icdiser[i] & bit) != 0;
0071 }
0072
0073 static inline void gic_id_enable(volatile gic_dist *dist, uint32_t id)
0074 {
0075 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0076 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0077
0078 dist->icdiser[i] = bit;
0079 }
0080
0081 static inline void gic_id_disable(volatile gic_dist *dist, uint32_t id)
0082 {
0083 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0084 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0085
0086 dist->icdicer[i] = bit;
0087 }
0088
0089 static inline bool gic_id_is_pending(volatile gic_dist *dist, uint32_t id)
0090 {
0091 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0092 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0093
0094 return (dist->icdispr[i] & bit) != 0;
0095 }
0096
0097 static inline void gic_id_set_pending(volatile gic_dist *dist, uint32_t id)
0098 {
0099 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0100 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0101
0102 dist->icdispr[i] = bit;
0103 }
0104
0105 static inline void gic_id_clear_pending(volatile gic_dist *dist, uint32_t id)
0106 {
0107 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0108 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0109
0110 dist->icdicpr[i] = bit;
0111 }
0112
0113 static inline bool gic_id_is_active(volatile gic_dist *dist, uint32_t id)
0114 {
0115 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0116 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0117
0118 return (dist->icdabr[i] & bit) != 0;
0119 }
0120
0121 typedef enum {
0122 GIC_GROUP_0,
0123 GIC_GROUP_1
0124 } gic_group;
0125
0126 static inline gic_group gic_id_get_group(
0127 volatile gic_dist *dist,
0128 uint32_t id
0129 )
0130 {
0131 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0132 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0133
0134 return (dist->icdigr[i] & bit) != 0 ? GIC_GROUP_1 : GIC_GROUP_0;
0135 }
0136
0137 static inline void gic_id_set_group(
0138 volatile gic_dist *dist,
0139 uint32_t id,
0140 gic_group group
0141 )
0142 {
0143 uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
0144 uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
0145 uint32_t icdigr = dist->icdigr[i];
0146
0147 icdigr &= ~bit;
0148
0149 if (group == GIC_GROUP_1) {
0150 icdigr |= bit;
0151 }
0152
0153 dist->icdigr[i] = icdigr;
0154 }
0155
0156 static inline void gic_id_set_priority(
0157 volatile gic_dist *dist,
0158 uint32_t id,
0159 uint8_t priority
0160 )
0161 {
0162 dist->icdipr[id] = priority;
0163 }
0164
0165 static inline uint8_t gic_id_get_priority(volatile gic_dist *dist, uint32_t id)
0166 {
0167 return dist->icdipr[id];
0168 }
0169
0170 static inline void gic_id_set_targets(
0171 volatile gic_dist *dist,
0172 uint32_t id,
0173 uint8_t targets
0174 )
0175 {
0176 dist->icdiptr[id] = targets;
0177 }
0178
0179 static inline uint8_t gic_id_get_targets(volatile gic_dist *dist, uint32_t id)
0180 {
0181 return dist->icdiptr[id];
0182 }
0183
0184 typedef enum {
0185 GIC_LEVEL_SENSITIVE,
0186 GIC_EDGE_TRIGGERED
0187 } gic_trigger_mode;
0188
0189 static inline gic_trigger_mode gic_id_get_trigger_mode(
0190 volatile gic_dist *dist,
0191 uint32_t id
0192 )
0193 {
0194 uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
0195 uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id) + 1;
0196 uint32_t bit = 1U << o;
0197
0198 return (dist->icdicfr[i] & bit) != 0 ?
0199 GIC_EDGE_TRIGGERED : GIC_LEVEL_SENSITIVE;
0200 }
0201
0202 static inline void gic_id_set_trigger_mode(
0203 volatile gic_dist *dist,
0204 uint32_t id,
0205 gic_trigger_mode mode
0206 )
0207 {
0208 uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
0209 uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id) + 1;
0210 uint32_t bit = mode << o;
0211 uint32_t mask = 1U << o;
0212 uint32_t icdicfr = dist->icdicfr[i];
0213
0214 icdicfr &= ~mask;
0215 icdicfr |= bit;
0216
0217 dist->icdicfr[i] = icdicfr;
0218 }
0219
0220 typedef enum {
0221 GIC_N_TO_N,
0222 GIC_1_TO_N
0223 } gic_handling_model;
0224
0225 static inline gic_handling_model gic_id_get_handling_model(
0226 volatile gic_dist *dist,
0227 uint32_t id
0228 )
0229 {
0230 uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
0231 uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id);
0232 uint32_t bit = 1U << o;
0233
0234 return (dist->icdicfr[i] & bit) != 0 ? GIC_1_TO_N : GIC_N_TO_N;
0235 }
0236
0237 static inline void gic_id_set_handling_model(
0238 volatile gic_dist *dist,
0239 uint32_t id,
0240 gic_handling_model model
0241 )
0242 {
0243 uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
0244 uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id);
0245 uint32_t bit = model << o;
0246 uint32_t mask = 1U << o;
0247 uint32_t icdicfr = dist->icdicfr[i];
0248
0249 icdicfr &= ~mask;
0250 icdicfr |= bit;
0251
0252 dist->icdicfr[i] = icdicfr;
0253 }
0254
0255
0256
0257 #ifdef __cplusplus
0258 }
0259 #endif
0260
0261 #endif