source: rtems/bsps/shared/dev/irq/arm-gicv2.c @ 23ec04c

Last change on this file since 23ec04c was 23ec04c, checked in by Sebastian Huber <sebastian.huber@…>, on 07/06/21 at 16:39:57

bsps/irq: bsp_interrupt_get_affinity()

Return a status code for bsp_interrupt_get_affinity().

Update #3269.

  • Property mode set to 100644
File size: 7.8 KB
Line 
1/*
2 * Copyright (c) 2013, 2019 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <info@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#include <dev/irq/arm-gic.h>
16#include <dev/irq/arm-gic-arch.h>
17
18#include <bsp/irq.h>
19#include <bsp/irq-generic.h>
20#include <bsp/start.h>
21
22#define GIC_CPUIF ((volatile gic_cpuif *) BSP_ARM_GIC_CPUIF_BASE)
23
24#define PRIORITY_DEFAULT 127
25
26/*
27 * The following variants
28 *
29 *  - GICv1 with Security Extensions,
30 *  - GICv2 without Security Extensions, or
31 *  - within Secure processor mode
32 *
33 * have the ability to assign group 0 or 1 to individual interrupts.  Group
34 * 0 interrupts can be configured to raise an FIQ exception.  This enables
35 * the use of NMIs with respect to RTEMS.
36 *
37 * BSPs can enable this feature with the BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0
38 * define.  Use arm_gic_irq_set_group() to change the group of an
39 * interrupt (default group is 1, if BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0 is
40 * defined).
41 */
42#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0
43#define DIST_ICDDCR (GIC_DIST_ICDDCR_ENABLE_GRP_1 | GIC_DIST_ICDDCR_ENABLE)
44#define CPUIF_ICCICR \
45  (GIC_CPUIF_ICCICR_CBPR | GIC_CPUIF_ICCICR_FIQ_EN \
46    | GIC_CPUIF_ICCICR_ACK_CTL | GIC_CPUIF_ICCICR_ENABLE_GRP_1 \
47    | GIC_CPUIF_ICCICR_ENABLE)
48#else
49#define DIST_ICDDCR GIC_DIST_ICDDCR_ENABLE
50#define CPUIF_ICCICR GIC_CPUIF_ICCICR_ENABLE
51#endif
52
53void bsp_interrupt_dispatch(void)
54{
55  volatile gic_cpuif *cpuif = GIC_CPUIF;
56  uint32_t icciar = cpuif->icciar;
57  rtems_vector_number vector = GIC_CPUIF_ICCIAR_ACKINTID_GET(icciar);
58  rtems_vector_number spurious = 1023;
59
60  if (vector != spurious) {
61    arm_interrupt_handler_dispatch(vector);
62
63    cpuif->icceoir = icciar;
64  }
65}
66
67rtems_status_code bsp_interrupt_get_attributes(
68  rtems_vector_number         vector,
69  rtems_interrupt_attributes *attributes
70)
71{
72  return RTEMS_SUCCESSFUL;
73}
74
75rtems_status_code bsp_interrupt_is_pending(
76  rtems_vector_number vector,
77  bool               *pending
78)
79{
80  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
81  bsp_interrupt_assert(pending != NULL);
82  *pending = false;
83  return RTEMS_UNSATISFIED;
84}
85
86rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
87{
88  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
89  return RTEMS_UNSATISFIED;
90}
91
92#if defined(RTEMS_SMP)
93rtems_status_code bsp_interrupt_raise_on(
94  rtems_vector_number vector,
95  uint32_t            cpu_index
96)
97{
98  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
99  return RTEMS_UNSATISFIED;
100}
101#endif
102
103rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
104{
105  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
106  return RTEMS_UNSATISFIED;
107}
108
109rtems_status_code bsp_interrupt_vector_is_enabled(
110  rtems_vector_number vector,
111  bool               *enabled
112)
113{
114  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
115  bsp_interrupt_assert(enabled != NULL);
116  *enabled = false;
117  return RTEMS_UNSATISFIED;
118}
119
120rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
121{
122  volatile gic_dist *dist = ARM_GIC_DIST;
123
124  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
125
126  gic_id_enable(dist, vector);
127  return RTEMS_SUCCESSFUL;
128}
129
130rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
131{
132  volatile gic_dist *dist = ARM_GIC_DIST;
133
134  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
135
136  gic_id_disable(dist, vector);
137  return RTEMS_SUCCESSFUL;
138}
139
140static inline uint32_t get_id_count(volatile gic_dist *dist)
141{
142  uint32_t id_count = GIC_DIST_ICDICTR_IT_LINES_NUMBER_GET(dist->icdictr);
143
144  id_count = 32 * (id_count + 1);
145  id_count = id_count <= 1020 ? id_count : 1020;
146
147  return id_count;
148}
149
150static void enable_fiq(void)
151{
152#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0
153  rtems_interrupt_level level;
154
155  rtems_interrupt_local_disable(level);
156  level &= ~ARM_PSR_F;
157  rtems_interrupt_local_enable(level);
158#endif
159}
160
161rtems_status_code bsp_interrupt_facility_initialize(void)
162{
163  volatile gic_cpuif *cpuif = GIC_CPUIF;
164  volatile gic_dist *dist = ARM_GIC_DIST;
165  uint32_t id_count = get_id_count(dist);
166  uint32_t id;
167
168  arm_interrupt_facility_set_exception_handler();
169
170  for (id = 0; id < id_count; id += 32) {
171#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0
172    dist->icdigr[id / 32] = 0xffffffff;
173#endif
174    dist->icdicer[id / 32] = 0xffffffff;
175  }
176
177  for (id = 0; id < id_count; ++id) {
178    gic_id_set_priority(dist, id, PRIORITY_DEFAULT);
179  }
180
181  for (id = 32; id < id_count; ++id) {
182    gic_id_set_targets(dist, id, 0x01);
183  }
184
185  cpuif->iccpmr = GIC_CPUIF_ICCPMR_PRIORITY(0xff);
186  cpuif->iccbpr = GIC_CPUIF_ICCBPR_BINARY_POINT(0x0);
187  cpuif->iccicr = CPUIF_ICCICR;
188
189  dist->icddcr = GIC_DIST_ICDDCR_ENABLE_GRP_1 | GIC_DIST_ICDDCR_ENABLE;
190
191  enable_fiq();
192  return RTEMS_SUCCESSFUL;
193}
194
195#ifdef RTEMS_SMP
196BSP_START_TEXT_SECTION void arm_gic_irq_initialize_secondary_cpu(void)
197{
198  volatile gic_cpuif *cpuif = GIC_CPUIF;
199  volatile gic_dist *dist = ARM_GIC_DIST;
200  uint32_t id;
201
202  while ((dist->icddcr & GIC_DIST_ICDDCR_ENABLE) == 0) {
203    /* Wait */
204  }
205
206#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0
207  dist->icdigr[0] = 0xffffffff;
208#endif
209
210  /* Initialize Peripheral Private Interrupts (PPIs) */
211  for (id = 0; id < 32; ++id) {
212    gic_id_set_priority(dist, id, PRIORITY_DEFAULT);
213  }
214
215  cpuif->iccpmr = GIC_CPUIF_ICCPMR_PRIORITY(0xff);
216  cpuif->iccbpr = GIC_CPUIF_ICCBPR_BINARY_POINT(0x0);
217  cpuif->iccicr = CPUIF_ICCICR;
218
219  enable_fiq();
220}
221#endif
222
223rtems_status_code arm_gic_irq_set_priority(
224  rtems_vector_number vector,
225  uint8_t priority
226)
227{
228  rtems_status_code sc = RTEMS_SUCCESSFUL;
229
230  if (bsp_interrupt_is_valid_vector(vector)) {
231    volatile gic_dist *dist = ARM_GIC_DIST;
232
233    gic_id_set_priority(dist, vector, priority);
234  } else {
235    sc = RTEMS_INVALID_ID;
236  }
237
238  return sc;
239}
240
241rtems_status_code arm_gic_irq_get_priority(
242  rtems_vector_number vector,
243  uint8_t *priority
244)
245{
246  rtems_status_code sc = RTEMS_SUCCESSFUL;
247
248  if (bsp_interrupt_is_valid_vector(vector)) {
249    volatile gic_dist *dist = ARM_GIC_DIST;
250
251    *priority = gic_id_get_priority(dist, vector);
252  } else {
253    sc = RTEMS_INVALID_ID;
254  }
255
256  return sc;
257}
258
259rtems_status_code arm_gic_irq_set_group(
260  rtems_vector_number vector,
261  gic_group group
262)
263{
264  rtems_status_code sc = RTEMS_SUCCESSFUL;
265
266  if (bsp_interrupt_is_valid_vector(vector)) {
267    volatile gic_dist *dist = ARM_GIC_DIST;
268
269    gic_id_set_group(dist, vector, group);
270  } else {
271    sc = RTEMS_INVALID_ID;
272  }
273
274  return sc;
275}
276
277rtems_status_code arm_gic_irq_get_group(
278  rtems_vector_number vector,
279  gic_group *group
280)
281{
282  rtems_status_code sc = RTEMS_SUCCESSFUL;
283
284  if (bsp_interrupt_is_valid_vector(vector)) {
285    volatile gic_dist *dist = ARM_GIC_DIST;
286
287    *group = gic_id_get_group(dist, vector);
288  } else {
289    sc = RTEMS_INVALID_ID;
290  }
291
292  return sc;
293}
294
295void bsp_interrupt_set_affinity(
296  rtems_vector_number vector,
297  const Processor_mask *affinity
298)
299{
300  volatile gic_dist *dist = ARM_GIC_DIST;
301  uint8_t targets = (uint8_t) _Processor_mask_To_uint32_t(affinity, 0);
302
303  gic_id_set_targets(dist, vector, targets);
304}
305
306rtems_status_code bsp_interrupt_get_affinity(
307  rtems_vector_number vector,
308  Processor_mask *affinity
309)
310{
311  volatile gic_dist *dist = ARM_GIC_DIST;
312  uint8_t targets = gic_id_get_targets(dist, vector);
313
314  _Processor_mask_From_uint32_t(affinity, targets, 0);
315  return RTEMS_SUCCESSFUL;
316}
317
318void arm_gic_trigger_sgi(rtems_vector_number vector, uint32_t targets)
319{
320  volatile gic_dist *dist = ARM_GIC_DIST;
321
322  dist->icdsgir = GIC_DIST_ICDSGIR_TARGET_LIST_FILTER(0)
323    | GIC_DIST_ICDSGIR_CPU_TARGET_LIST(targets)
324#ifdef BSP_ARM_GIC_ENABLE_FIQ_FOR_GROUP_0
325    | GIC_DIST_ICDSGIR_NSATT
326#endif
327    | GIC_DIST_ICDSGIR_SGIINTID(vector);
328}
329
330uint32_t arm_gic_irq_processor_count(void)
331{
332  volatile gic_dist *dist = ARM_GIC_DIST;
333
334  return GIC_DIST_ICDICTR_CPU_NUMBER_GET(dist->icdictr) + 1;
335}
Note: See TracBrowser for help on using the repository browser.