source: rtems/c/src/lib/libbsp/m68k/genmcf548x/irq/irq.c @ c6810c8

5
Last change on this file since c6810c8 was c6810c8, checked in by Sebastian Huber <sebastian.huber@…>, on 06/19/17 at 12:09:28

bsps: Improve interrupt vector enable/disable API

Change bsp_interrupt_vector_enable() and bsp_interrupt_vector_disable()
to not return a status code. Add bsp_interrupt_assert() and use it to
validate the vector number in the vector enable/disable implementations.

  • Property mode set to 100644
File size: 5.0 KB
Line 
1/*
2 * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@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 <bsp/irq-generic.h>
16
17#include <mcf548x/mcf548x.h>
18
19void asm_default_interrupt(void);
20
21typedef void (*void_func)(void);
22
23typedef struct {
24  rtems_interrupt_handler handler;
25  void *arg;
26  const char *info;
27} interrupt_control;
28
29static interrupt_control interrupt_controls[BSP_INTERRUPT_VECTOR_MAX + 1];
30
31static uint32_t vector_to_reg(rtems_vector_number vector)
32{
33  return ((vector + 32U) >> 5) & 0x1;
34}
35
36static uint32_t vector_to_bit(rtems_vector_number vector)
37{
38  return 1U << (vector & 0x1fU);
39}
40
41static volatile uint32_t *vector_to_imr(rtems_vector_number vector)
42{
43  volatile uint32_t *imr = &MCF548X_INTC_IMRH;
44
45  return &imr[vector_to_reg(vector)];
46}
47
48static rtems_vector_number exception_vector_to_vector(
49  rtems_vector_number exception_vector
50)
51{
52  return exception_vector - 64U;
53}
54
55static rtems_vector_number vector_to_exception_vector(
56  rtems_vector_number vector
57)
58{
59  return vector + 64U;
60}
61
62void bsp_interrupt_vector_enable(rtems_vector_number vector)
63{
64  volatile uint32_t *imr = vector_to_imr(vector);
65  uint32_t bit = vector_to_bit(vector);
66  rtems_interrupt_level level;
67
68  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
69
70  rtems_interrupt_disable(level);
71  *imr &= ~bit;
72  rtems_interrupt_enable(level);
73}
74
75void bsp_interrupt_vector_disable(rtems_vector_number vector)
76{
77  volatile uint32_t *imr = vector_to_imr(vector);
78  uint32_t bit = vector_to_bit(vector);
79  rtems_interrupt_level level;
80
81  bsp_interrupt_assert(bsp_interrupt_is_valid_vector(vector));
82
83  rtems_interrupt_disable(level);
84  *imr |= bit;
85  rtems_interrupt_enable(level);
86}
87
88static void_func get_exception_handler(rtems_vector_number vector)
89{
90  void **vbr;
91  void_func *exception_table;
92
93  m68k_get_vbr(vbr);
94
95  exception_table = (void_func *)vbr;
96
97  return exception_table[vector_to_exception_vector(vector)];
98}
99
100static void set_exception_handler(rtems_vector_number vector, void_func handler)
101{
102  void **vbr;
103  void_func *exception_table;
104
105  m68k_get_vbr(vbr);
106
107  exception_table = (void_func *)vbr;
108
109  exception_table[vector_to_exception_vector(vector)] = handler;
110}
111
112static void dispatch_handler(rtems_vector_number exception_vector)
113{
114  const interrupt_control *ic =
115    &interrupt_controls[exception_vector_to_vector(exception_vector)];
116
117  (*ic->handler)(ic->arg);
118}
119
120static uint8_t get_intc_icr(rtems_vector_number vector)
121{
122  volatile uint8_t *icr = &MCF548X_INTC_ICR0;
123
124  return icr[vector];
125}
126
127rtems_status_code rtems_interrupt_handler_install(
128  rtems_vector_number vector,
129  const char *info,
130  rtems_option options,
131  rtems_interrupt_handler handler,
132  void *arg
133)
134{
135  rtems_status_code sc = RTEMS_SUCCESSFUL;
136
137  if (bsp_interrupt_is_valid_vector(vector)) {
138    rtems_interrupt_level level;
139
140    rtems_interrupt_disable(level);
141
142    if (
143      get_exception_handler(vector) == asm_default_interrupt
144        && get_intc_icr(vector) != 0
145    ) {
146      interrupt_control *ic = &interrupt_controls[vector];
147
148      ic->handler = handler;
149      ic->arg = arg;
150      ic->info = info;
151
152      _ISR_Vector_table[vector_to_exception_vector(vector)]
153        = dispatch_handler;
154      set_exception_handler(vector, _ISR_Handler);
155      bsp_interrupt_vector_enable(vector);
156    } else {
157      sc = RTEMS_RESOURCE_IN_USE;
158    }
159
160    rtems_interrupt_enable(level);
161  } else {
162    sc = RTEMS_INVALID_ID;
163  }
164
165  return sc;
166}
167
168static bool is_occupied_by_us(rtems_vector_number vector)
169{
170  return get_exception_handler(vector) == _ISR_Handler
171    && _ISR_Vector_table[vector_to_exception_vector(vector)]
172      == dispatch_handler;
173}
174
175rtems_status_code rtems_interrupt_handler_remove(
176  rtems_vector_number vector,
177  rtems_interrupt_handler handler,
178  void *arg
179)
180{
181  rtems_status_code sc = RTEMS_SUCCESSFUL;
182
183  if (bsp_interrupt_is_valid_vector(vector)) {
184    rtems_interrupt_level level;
185    interrupt_control *ic = &interrupt_controls[vector];
186
187    rtems_interrupt_disable(level);
188
189    if (
190      is_occupied_by_us(vector)
191        && ic->handler == handler
192        && ic->arg == arg
193    ) {
194      bsp_interrupt_vector_disable(vector);
195      set_exception_handler(vector, asm_default_interrupt);
196
197      memset(ic, 0, sizeof(*ic));
198    } else {
199      sc = RTEMS_UNSATISFIED;
200    }
201
202    rtems_interrupt_enable(level);
203  } else {
204    sc = RTEMS_INVALID_ID;
205  }
206
207  return sc;
208}
209
210rtems_status_code rtems_interrupt_handler_iterate(
211  rtems_vector_number vector,
212  rtems_interrupt_per_handler_routine routine,
213  void *arg
214)
215{
216  rtems_status_code sc = RTEMS_SUCCESSFUL;
217
218  if (bsp_interrupt_is_valid_vector(vector)) {
219    if (is_occupied_by_us(vector)) {
220      const interrupt_control *ic = &interrupt_controls[vector];
221
222      (*routine)(arg, ic->info, RTEMS_INTERRUPT_UNIQUE, ic->handler, ic->arg);
223    }
224  } else {
225    sc = RTEMS_INVALID_ID;
226  }
227
228  return sc;
229}
Note: See TracBrowser for help on using the repository browser.