RTEMS  5.1
arm-gic.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2013, 2019 embedded brains GmbH. All rights reserved.
11  *
12  * embedded brains GmbH
13  * Dornierstr. 4
14  * 82178 Puchheim
15  * Germany
16  * <info@embedded-brains.de>
17  *
18  * The license and distribution terms for this file may be
19  * found in the file LICENSE in this distribution or at
20  * http://www.rtems.org/license/LICENSE.
21  */
22 
23 #ifndef LIBBSP_ARM_SHARED_ARM_GIC_H
24 #define LIBBSP_ARM_SHARED_ARM_GIC_H
25 
26 #include <bsp/arm-gic-regs.h>
27 
28 #include <stdbool.h>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif /* __cplusplus */
33 
42 #define GIC_ID_TO_ONE_BIT_REG_INDEX(id) ((id) >> 5)
43 #define GIC_ID_TO_ONE_BIT_REG_BIT(id) (1U << ((id) & 0x1fU))
44 
45 #define GIC_ID_TO_TWO_BITS_REG_INDEX(id) ((id) >> 4)
46 #define GIC_ID_TO_TWO_BITS_REG_OFFSET(id) (((id) & 0xfU) << 1)
47 
48 static inline bool gic_id_is_enabled(volatile gic_dist *dist, uint32_t id)
49 {
50  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
51  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
52 
53  return (dist->icdiser[i] & bit) != 0;
54 }
55 
56 static inline void gic_id_enable(volatile gic_dist *dist, uint32_t id)
57 {
58  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
59  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
60 
61  dist->icdiser[i] = bit;
62 }
63 
64 static inline void gic_id_disable(volatile gic_dist *dist, uint32_t id)
65 {
66  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
67  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
68 
69  dist->icdicer[i] = bit;
70 }
71 
72 static inline bool gic_id_is_pending(volatile gic_dist *dist, uint32_t id)
73 {
74  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
75  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
76 
77  return (dist->icdispr[i] & bit) != 0;
78 }
79 
80 static inline void gic_id_set_pending(volatile gic_dist *dist, uint32_t id)
81 {
82  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
83  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
84 
85  dist->icdispr[i] = bit;
86 }
87 
88 static inline void gic_id_clear_pending(volatile gic_dist *dist, uint32_t id)
89 {
90  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
91  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
92 
93  dist->icdicpr[i] = bit;
94 }
95 
96 static inline bool gic_id_is_active(volatile gic_dist *dist, uint32_t id)
97 {
98  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
99  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
100 
101  return (dist->icdabr[i] & bit) != 0;
102 }
103 
104 typedef enum {
105  GIC_GROUP_0,
106  GIC_GROUP_1
107 } gic_group;
108 
109 static inline gic_group gic_id_get_group(
110  volatile gic_dist *dist,
111  uint32_t id
112 )
113 {
114  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
115  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
116 
117  return (dist->icdigr[i] & bit) != 0 ? GIC_GROUP_1 : GIC_GROUP_0;
118 }
119 
120 static inline void gic_id_set_group(
121  volatile gic_dist *dist,
122  uint32_t id,
123  gic_group group
124 )
125 {
126  uint32_t i = GIC_ID_TO_ONE_BIT_REG_INDEX(id);
127  uint32_t bit = GIC_ID_TO_ONE_BIT_REG_BIT(id);
128  uint32_t icdigr = dist->icdigr[i];
129 
130  icdigr &= ~bit;
131 
132  if (group == GIC_GROUP_1) {
133  icdigr |= bit;
134  }
135 
136  dist->icdigr[i] = icdigr;
137 }
138 
139 static inline void gic_id_set_priority(
140  volatile gic_dist *dist,
141  uint32_t id,
142  uint8_t priority
143 )
144 {
145  dist->icdipr[id] = priority;
146 }
147 
148 static inline uint8_t gic_id_get_priority(volatile gic_dist *dist, uint32_t id)
149 {
150  return dist->icdipr[id];
151 }
152 
153 static inline void gic_id_set_targets(
154  volatile gic_dist *dist,
155  uint32_t id,
156  uint8_t targets
157 )
158 {
159  dist->icdiptr[id] = targets;
160 }
161 
162 static inline uint8_t gic_id_get_targets(volatile gic_dist *dist, uint32_t id)
163 {
164  return dist->icdiptr[id];
165 }
166 
167 typedef enum {
168  GIC_LEVEL_SENSITIVE,
169  GIC_EDGE_TRIGGERED
170 } gic_trigger_mode;
171 
172 static inline gic_trigger_mode gic_id_get_trigger_mode(
173  volatile gic_dist *dist,
174  uint32_t id
175 )
176 {
177  uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
178  uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id) + 1;
179  uint32_t bit = 1U << o;
180 
181  return (dist->icdicfr[i] & bit) != 0 ?
182  GIC_EDGE_TRIGGERED : GIC_LEVEL_SENSITIVE;
183 }
184 
185 static inline void gic_id_set_trigger_mode(
186  volatile gic_dist *dist,
187  uint32_t id,
188  gic_trigger_mode mode
189 )
190 {
191  uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
192  uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id) + 1;
193  uint32_t bit = mode << o;
194  uint32_t mask = 1U << o;
195  uint32_t icdicfr = dist->icdicfr[i];
196 
197  icdicfr &= ~mask;
198  icdicfr |= bit;
199 
200  dist->icdicfr[i] = icdicfr;
201 }
202 
203 typedef enum {
204  GIC_N_TO_N,
205  GIC_1_TO_N
206 } gic_handling_model;
207 
208 static inline gic_handling_model gic_id_get_handling_model(
209  volatile gic_dist *dist,
210  uint32_t id
211 )
212 {
213  uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
214  uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id);
215  uint32_t bit = 1U << o;
216 
217  return (dist->icdicfr[i] & bit) != 0 ? GIC_1_TO_N : GIC_N_TO_N;
218 }
219 
220 static inline void gic_id_set_handling_model(
221  volatile gic_dist *dist,
222  uint32_t id,
223  gic_handling_model model
224 )
225 {
226  uint32_t i = GIC_ID_TO_TWO_BITS_REG_INDEX(id);
227  uint32_t o = GIC_ID_TO_TWO_BITS_REG_OFFSET(id);
228  uint32_t bit = model << o;
229  uint32_t mask = 1U << o;
230  uint32_t icdicfr = dist->icdicfr[i];
231 
232  icdicfr &= ~mask;
233  icdicfr |= bit;
234 
235  dist->icdicfr[i] = icdicfr;
236 }
237 
238 #ifdef __cplusplus
239 }
240 #endif /* __cplusplus */
241 
242 #endif /* LIBBSP_ARM_SHARED_ARM_GIC_H */
Definition: arm-gic-regs.h:88
ARM GIC Register definitions.