RTEMS 5.2
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
31extern "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
48static 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
56static 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
64static 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
72static 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
80static 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
88static 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
96static 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
104typedef enum {
105 GIC_GROUP_0,
106 GIC_GROUP_1
107} gic_group;
108
109static 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
120static 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
139static 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
148static inline uint8_t gic_id_get_priority(volatile gic_dist *dist, uint32_t id)
149{
150 return dist->icdipr[id];
151}
152
153static 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
162static inline uint8_t gic_id_get_targets(volatile gic_dist *dist, uint32_t id)
163{
164 return dist->icdiptr[id];
165}
166
167typedef enum {
168 GIC_LEVEL_SENSITIVE,
169 GIC_EDGE_TRIGGERED
170} gic_trigger_mode;
171
172static 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
185static 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
203typedef enum {
204 GIC_N_TO_N,
205 GIC_1_TO_N
206} gic_handling_model;
207
208static 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
220static 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 */
ARM GIC Register definitions.
Definition: arm-gic-regs.h:88