source: rtems/bsps/sparc/leon3/start/eirq.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: 5.6 KB
Line 
1/*
2 *  GRLIB/LEON3 extended interrupt controller
3 *
4 *  Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
5 *
6 *  COPYRIGHT (c) 2011
7 *  Aeroflex Gaisler
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.rtems.org/license/LICENSE.
12 *
13 */
14
15#include <leon.h>
16#include <bsp/irq.h>
17#include <bsp/irq-generic.h>
18
19/* GRLIB extended IRQ controller IRQ number */
20int LEON3_IrqCtrl_EIrq = -1;
21
22/* Initialize Extended Interrupt controller */
23void leon3_ext_irq_init(void)
24{
25  if ( (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf ) {
26    /* Extended IRQ controller available */
27    LEON3_IrqCtrl_EIrq = (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf;
28  }
29}
30
31bool bsp_interrupt_is_valid_vector(rtems_vector_number vector)
32{
33  if (vector == 0) {
34    return false;
35  }
36
37  if (LEON3_IrqCtrl_EIrq > 0) {
38    return vector <= BSP_INTERRUPT_VECTOR_MAX_EXT;
39  }
40
41  return vector <= BSP_INTERRUPT_VECTOR_MAX_STD;
42}
43
44#if defined(RTEMS_SMP)
45Processor_mask leon3_interrupt_affinities[BSP_INTERRUPT_VECTOR_MAX_STD + 1];
46#endif
47
48rtems_status_code bsp_interrupt_facility_initialize(void)
49{
50#if defined(RTEMS_SMP)
51  Processor_mask affinity;
52  size_t i;
53
54  _Processor_mask_From_index(&affinity, rtems_scheduler_get_processor());
55
56  for (i = 0; i < RTEMS_ARRAY_SIZE(leon3_interrupt_affinities); ++i) {
57    leon3_interrupt_affinities[i] = affinity;
58  }
59#endif
60
61  return RTEMS_SUCCESSFUL;
62}
63
64rtems_status_code bsp_interrupt_get_attributes(
65  rtems_vector_number         vector,
66  rtems_interrupt_attributes *attributes
67)
68{
69  return RTEMS_SUCCESSFUL;
70}
71
72rtems_status_code bsp_interrupt_is_pending(
73  rtems_vector_number vector,
74  bool               *pending
75)
76{
77  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
78  bsp_interrupt_assert(pending != NULL);
79  *pending = false;
80  return RTEMS_UNSATISFIED;
81}
82
83rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
84{
85  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
86  return RTEMS_UNSATISFIED;
87}
88
89#if defined(RTEMS_SMP)
90rtems_status_code bsp_interrupt_raise_on(
91  rtems_vector_number vector,
92  uint32_t            cpu_index
93)
94{
95  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
96  return RTEMS_UNSATISFIED;
97}
98#endif
99
100rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
101{
102  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
103  return RTEMS_UNSATISFIED;
104}
105
106rtems_status_code bsp_interrupt_vector_is_enabled(
107  rtems_vector_number vector,
108  bool               *enabled
109)
110{
111  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
112  bsp_interrupt_assert(enabled != NULL);
113  *enabled = false;
114  return RTEMS_UNSATISFIED;
115}
116
117#if defined(RTEMS_SMP)
118static void leon3_interrupt_vector_enable(rtems_vector_number vector)
119{
120  uint32_t cpu_index;
121  uint32_t cpu_count;
122  Processor_mask affinity;
123  uint32_t bit;
124  uint32_t unmasked;
125
126  cpu_count = rtems_scheduler_get_processor_maximum();
127  affinity = leon3_interrupt_affinities[vector];
128  bit = 1U << vector;
129  unmasked = 0;
130
131  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
132    uint32_t mask;
133
134    mask = LEON3_IrqCtrl_Regs->mask[cpu_index];
135
136    if (_Processor_mask_Is_set(&affinity, cpu_index)) {
137      ++unmasked;
138      mask |= bit;
139    } else {
140      mask &= ~bit;
141    }
142
143    LEON3_IrqCtrl_Regs->mask[cpu_index] = mask;
144  }
145
146  if (unmasked > 1) {
147    LEON3_IrqCtrl_Regs->bcast |= bit;
148  } else {
149    LEON3_IrqCtrl_Regs->bcast &= ~bit;
150  }
151}
152#endif
153
154rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
155{
156#if defined(RTEMS_SMP)
157  rtems_interrupt_lock_context lock_context;
158
159  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
160  LEON3_IRQCTRL_ACQUIRE(&lock_context);
161  leon3_interrupt_vector_enable(vector);
162  LEON3_IRQCTRL_RELEASE(&lock_context);
163#else
164  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
165  BSP_Cpu_Unmask_interrupt(vector, _LEON3_Get_current_processor());
166#endif
167  return RTEMS_SUCCESSFUL;
168}
169
170rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
171{
172#if defined(RTEMS_SMP)
173  rtems_interrupt_lock_context lock_context;
174  uint32_t bit;
175  uint32_t cpu_index;
176  uint32_t cpu_count;
177
178  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
179  bit = 1U << vector;
180  cpu_count = rtems_scheduler_get_processor_maximum();
181
182  LEON3_IRQCTRL_ACQUIRE(&lock_context);
183
184  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
185    LEON3_IrqCtrl_Regs->mask[cpu_index] &= ~bit;
186  }
187
188  LEON3_IrqCtrl_Regs->bcast &= ~bit;
189
190  LEON3_IRQCTRL_RELEASE(&lock_context);
191#else
192  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
193  BSP_Cpu_Mask_interrupt(vector, _LEON3_Get_current_processor());
194#endif
195  return RTEMS_SUCCESSFUL;
196}
197
198#if defined(RTEMS_SMP)
199void bsp_interrupt_set_affinity(
200  rtems_vector_number vector,
201  const Processor_mask *affinity
202)
203{
204  rtems_interrupt_lock_context lock_context;
205  uint32_t cpu_count;
206  uint32_t cpu_index;
207  uint32_t bit;
208
209  cpu_count = rtems_scheduler_get_processor_maximum();
210  bit = 1U << vector;
211
212  LEON3_IRQCTRL_ACQUIRE(&lock_context);
213  leon3_interrupt_affinities[vector] = *affinity;
214
215  /*
216   * If the interrupt is enabled on at least one processor, then re-enable it
217   * using the new affinity.
218   */
219  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
220    if ((LEON3_IrqCtrl_Regs->mask[cpu_index] & bit) != 0) {
221      leon3_interrupt_vector_enable(vector);
222      break;
223    }
224  }
225
226  LEON3_IRQCTRL_RELEASE(&lock_context);
227}
228
229rtems_status_code bsp_interrupt_get_affinity(
230  rtems_vector_number vector,
231  Processor_mask *affinity
232)
233{
234  *affinity = leon3_interrupt_affinities[vector];
235  return RTEMS_SUCCESSFUL;
236}
237#endif
Note: See TracBrowser for help on using the repository browser.