summaryrefslogtreecommitdiffstats
path: root/bsps/sparc/leon3/start/eirq.c
blob: b4cd6d29480f536ec46ef53cbdb6bd820bc45651 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 *  GRLIB/LEON3 extended interrupt controller
 *
 *  COPYRIGHT (c) 2011
 *  Aeroflex Gaisler
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.org/license/LICENSE.
 *
 */

#include <leon.h>
#include <bsp/irq.h>

/* GRLIB extended IRQ controller IRQ number */
int LEON3_IrqCtrl_EIrq = -1;

/* Initialize Extended Interrupt controller */
void leon3_ext_irq_init(void)
{
  if ( (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf ) {
    /* Extended IRQ controller available */
    LEON3_IrqCtrl_EIrq = (LEON3_IrqCtrl_Regs->mpstat >> 16) & 0xf;
  }
}

void bsp_interrupt_set_affinity(
  rtems_vector_number vector,
  const Processor_mask *affinity
)
{
  uint32_t unmasked = 0;
  uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
  uint32_t cpu_index;

  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
    if (_Processor_mask_Is_set(affinity, cpu_index)) {
      BSP_Cpu_Unmask_interrupt(vector, cpu_index);
      ++unmasked;
    }
  }

  if (unmasked > 1) {
    LEON_Enable_interrupt_broadcast(vector);
  } else {
    LEON_Disable_interrupt_broadcast(vector);
  }
}

void bsp_interrupt_get_affinity(
  rtems_vector_number vector,
  Processor_mask *affinity
)
{
  uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
  uint32_t cpu_index;

  _Processor_mask_Zero(affinity);

  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
    if (!BSP_Cpu_Is_interrupt_masked(vector, cpu_index)) {
      _Processor_mask_Set(affinity, cpu_index);
    }
  }
}