source: rtems/bsps/riscv/griscv/irq/irq.c @ d3d4e77

5
Last change on this file since d3d4e77 was d3d4e77, checked in by Jiri Gaisler <jiri@…>, on 01/18/19 at 11:37:55

riscv: add griscv bsp

Update #3678.

  • Property mode set to 100644
File size: 4.1 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup riscv_interrupt
5 *
6 * @brief Interrupt support.
7 */
8
9/*
10 * Copyright (c) 2018 embedded brains GmbH
11 *
12 * Copyright (c) 2015 University of York.
13 * Hesham Almatary <hesham@alumni.york.ac.uk>
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#include <bsp/irq.h>
38#include <bsp/fatal.h>
39#include <bsp/irq-generic.h>
40#include <amba.h>
41
42#include <rtems/score/percpu.h>
43#include <rtems/score/riscv-utility.h>
44#include <rtems/score/smpimpl.h>
45
46rtems_interrupt_lock GRLIB_IrqCtrl_Lock;
47
48#if defined(RTEMS_SMP)
49/* Interrupt to CPU map. Default to CPU0 since in BSS. */
50const unsigned char GRLIB_irq_to_cpu[32] __attribute__((weak));
51
52/* On SMP use map table above relative to SMP Boot CPU (normally CPU0) */
53static inline int bsp_irq_cpu(int irq)
54{
55  /* protect from bad user configuration, default to boot cpu */
56  if (rtems_configuration_get_maximum_processors() <= GRLIB_irq_to_cpu[irq])
57    return GRLIB_Cpu_Index;
58  else
59    return GRLIB_Cpu_Index + GRLIB_irq_to_cpu[irq];
60}
61#else
62/* when not SMP the local CPU is returned */
63static inline int bsp_irq_cpu(int irq)
64{
65  return read_csr(mhartid);
66}
67#endif
68
69void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
70{
71  if (mcause & 0x80000000) {
72
73    bsp_interrupt_handler_dispatch(mcause & 0xf);
74
75  } else {
76    bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
77  }
78}
79
80rtems_status_code bsp_interrupt_facility_initialize(void)
81{
82
83  /*
84   * External M-mode interrupts on secondary processors are enabled in
85   * bsp_start_on_secondary_processor().
86   */
87  set_csr(mie, MIP_MEIP);
88
89  return RTEMS_SUCCESSFUL;
90}
91
92void bsp_interrupt_vector_enable(rtems_vector_number vector)
93{
94  int irq = (int)vector;
95  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
96  GRLIB_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq));
97}
98
99void bsp_interrupt_vector_disable(rtems_vector_number vector)
100{
101  int irq = (int)vector;
102  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
103  GRLIB_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq));
104}
105
106void bsp_interrupt_get_affinity(
107  rtems_vector_number vector,
108  Processor_mask *affinity
109)
110{
111  uint32_t cpu_count = rtems_get_processor_count();
112  uint32_t cpu_index;
113
114  _Processor_mask_Zero(affinity);
115
116  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
117    if (!BSP_Cpu_Is_interrupt_masked(vector, cpu_index)) {
118      _Processor_mask_Set(affinity, cpu_index);
119    }
120  }
121}
122
123void bsp_interrupt_set_affinity(
124  rtems_vector_number vector,
125  const Processor_mask *affinity
126)
127{
128  uint32_t unmasked = 0;
129  uint32_t cpu_count = rtems_get_processor_count();
130  uint32_t cpu_index;
131
132  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
133    if (_Processor_mask_Is_set(affinity, cpu_index)) {
134      GRLIB_Cpu_Unmask_interrupt(vector, cpu_index);
135      ++unmasked;
136    }
137  }
138
139  if (unmasked > 1) {
140    GRLIB_Enable_interrupt_broadcast(vector);
141  } else {
142    GRLIB_Disable_interrupt_broadcast(vector);
143  }
144}
Note: See TracBrowser for help on using the repository browser.