source: rtems/bsps/riscv/griscv/irq/irq.c @ 85a3785

Last change on this file since 85a3785 was 85a3785, checked in by Sebastian Huber <sebastian.huber@…>, on 07/06/21 at 17:00:20

bsps/irq: bsp_interrupt_set_affinity()

Return a status code for bsp_interrupt_set_affinity().

Update #3269.

  • Property mode set to 100644
File size: 5.4 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
46#if defined(RTEMS_SMP)
47/* Interrupt to CPU map. Default to CPU0 since in BSS. */
48const unsigned char GRLIB_irq_to_cpu[32] __attribute__((weak));
49
50/* On SMP use map table above relative to SMP Boot CPU (normally CPU0) */
51static inline int bsp_irq_cpu(int irq)
52{
53  /* protect from bad user configuration, default to boot cpu */
54  if (rtems_configuration_get_maximum_processors() <= GRLIB_irq_to_cpu[irq])
55    return GRLIB_Cpu_Index;
56  else
57    return GRLIB_Cpu_Index + GRLIB_irq_to_cpu[irq];
58}
59#else
60/* when not SMP the local CPU is returned */
61static inline int bsp_irq_cpu(int irq)
62{
63  return read_csr(mhartid);
64}
65#endif
66
67void _RISCV_Interrupt_dispatch(uintptr_t mcause, Per_CPU_Control *cpu_self)
68{
69  if (mcause & 0x80000000) {
70
71    bsp_interrupt_handler_dispatch(mcause & 0xf);
72
73  } else {
74    bsp_fatal(RISCV_FATAL_UNEXPECTED_INTERRUPT_EXCEPTION);
75  }
76}
77
78rtems_status_code bsp_interrupt_facility_initialize(void)
79{
80
81  /*
82   * External M-mode interrupts on secondary processors are enabled in
83   * bsp_start_on_secondary_processor().
84   */
85  set_csr(mie, MIP_MEIP);
86
87  return RTEMS_SUCCESSFUL;
88}
89
90rtems_status_code bsp_interrupt_get_attributes(
91  rtems_vector_number         vector,
92  rtems_interrupt_attributes *attributes
93)
94{
95  return RTEMS_SUCCESSFUL;
96}
97
98rtems_status_code bsp_interrupt_is_pending(
99  rtems_vector_number vector,
100  bool               *pending
101)
102{
103  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
104  bsp_interrupt_assert(pending != NULL);
105  *pending = false;
106  return RTEMS_UNSATISFIED;
107}
108
109rtems_status_code bsp_interrupt_raise(rtems_vector_number vector)
110{
111  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
112  return RTEMS_UNSATISFIED;
113}
114
115#if defined(RTEMS_SMP)
116rtems_status_code bsp_interrupt_raise_on(
117  rtems_vector_number vector,
118  uint32_t            cpu_index
119)
120{
121  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
122  return RTEMS_UNSATISFIED;
123}
124#endif
125
126rtems_status_code bsp_interrupt_clear(rtems_vector_number vector)
127{
128  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
129  return RTEMS_UNSATISFIED;
130}
131
132rtems_status_code bsp_interrupt_vector_is_enabled(
133  rtems_vector_number vector,
134  bool               *enabled
135)
136{
137  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
138  bsp_interrupt_assert(enabled != NULL);
139  *enabled = false;
140  return RTEMS_UNSATISFIED;
141}
142
143rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
144{
145  int irq = (int)vector;
146  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
147  GRLIB_Cpu_Unmask_interrupt(irq, bsp_irq_cpu(irq));
148  return RTEMS_SUCCESSFUL;
149}
150
151rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
152{
153  int irq = (int)vector;
154  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
155  GRLIB_Cpu_Mask_interrupt(irq, bsp_irq_cpu(irq));
156  return RTEMS_SUCCESSFUL;
157}
158
159rtems_status_code bsp_interrupt_get_affinity(
160  rtems_vector_number vector,
161  Processor_mask *affinity
162)
163{
164  uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
165  uint32_t cpu_index;
166
167  _Processor_mask_Zero(affinity);
168
169  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
170    if (!BSP_Cpu_Is_interrupt_masked(vector, cpu_index)) {
171      _Processor_mask_Set(affinity, cpu_index);
172    }
173  }
174
175  return RTEMS_SUCCESSFUL;
176}
177
178rtems_status_code bsp_interrupt_set_affinity(
179  rtems_vector_number vector,
180  const Processor_mask *affinity
181)
182{
183  uint32_t unmasked = 0;
184  uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
185  uint32_t cpu_index;
186
187  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
188    if (_Processor_mask_Is_set(affinity, cpu_index)) {
189      GRLIB_Cpu_Unmask_interrupt(vector, cpu_index);
190      ++unmasked;
191    }
192  }
193
194  if (unmasked > 1) {
195    GRLIB_Enable_interrupt_broadcast(vector);
196  } else {
197    GRLIB_Disable_interrupt_broadcast(vector);
198  }
199
200  return RTEMS_SUCCESSFUL;
201}
Note: See TracBrowser for help on using the repository browser.