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

5
Last change on this file since 485222e was 485222e, checked in by Joel Sherrill <joel@…>, on 04/24/17 at 17:00:15

genmcf548x/irq/irq.c: Fix incompatible pointer warning

  • Property mode set to 100644
File size: 5.2 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
62rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
63{
64  rtems_status_code sc = RTEMS_SUCCESSFUL;
65
66  if (bsp_interrupt_is_valid_vector(vector)) {
67    volatile uint32_t *imr = vector_to_imr(vector);
68    uint32_t bit = vector_to_bit(vector);
69    rtems_interrupt_level level;
70
71    rtems_interrupt_disable(level);
72    *imr &= ~bit;
73    rtems_interrupt_enable(level);
74  } else {
75    sc = RTEMS_INVALID_ID;
76  }
77
78  return sc;
79}
80
81rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
82{
83  rtems_status_code sc = RTEMS_SUCCESSFUL;
84
85  if (bsp_interrupt_is_valid_vector(vector)) {
86    volatile uint32_t *imr = vector_to_imr(vector);
87    uint32_t bit = vector_to_bit(vector);
88    rtems_interrupt_level level;
89
90    rtems_interrupt_disable(level);
91    *imr |= bit;
92    rtems_interrupt_enable(level);
93  } else {
94    sc = RTEMS_INVALID_ID;
95  }
96
97  return sc;
98}
99
100static void_func get_exception_handler(rtems_vector_number vector)
101{
102  void **vbr;
103  void_func *exception_table;
104
105  m68k_get_vbr(vbr);
106
107  exception_table = (void_func *)vbr;
108
109  return exception_table[vector_to_exception_vector(vector)];
110}
111
112static void set_exception_handler(rtems_vector_number vector, void_func handler)
113{
114  void **vbr;
115  void_func *exception_table;
116
117  m68k_get_vbr(vbr);
118
119  exception_table = (void_func *)vbr;
120
121  exception_table[vector_to_exception_vector(vector)] = handler;
122}
123
124static void dispatch_handler(rtems_vector_number exception_vector)
125{
126  const interrupt_control *ic =
127    &interrupt_controls[exception_vector_to_vector(exception_vector)];
128
129  (*ic->handler)(ic->arg);
130}
131
132static uint8_t get_intc_icr(rtems_vector_number vector)
133{
134  volatile uint8_t *icr = &MCF548X_INTC_ICR0;
135
136  return icr[vector];
137}
138
139rtems_status_code rtems_interrupt_handler_install(
140  rtems_vector_number vector,
141  const char *info,
142  rtems_option options,
143  rtems_interrupt_handler handler,
144  void *arg
145)
146{
147  rtems_status_code sc = RTEMS_SUCCESSFUL;
148
149  if (bsp_interrupt_is_valid_vector(vector)) {
150    rtems_interrupt_level level;
151
152    rtems_interrupt_disable(level);
153
154    if (
155      get_exception_handler(vector) == asm_default_interrupt
156        && get_intc_icr(vector) != 0
157    ) {
158      interrupt_control *ic = &interrupt_controls[vector];
159
160      ic->handler = handler;
161      ic->arg = arg;
162      ic->info = info;
163
164      _ISR_Vector_table[vector_to_exception_vector(vector)]
165        = dispatch_handler;
166      set_exception_handler(vector, _ISR_Handler);
167      bsp_interrupt_vector_enable(vector);
168    } else {
169      sc = RTEMS_RESOURCE_IN_USE;
170    }
171
172    rtems_interrupt_enable(level);
173  } else {
174    sc = RTEMS_INVALID_ID;
175  }
176
177  return sc;
178}
179
180static bool is_occupied_by_us(rtems_vector_number vector)
181{
182  return get_exception_handler(vector) == _ISR_Handler
183    && _ISR_Vector_table[vector_to_exception_vector(vector)]
184      == dispatch_handler;
185}
186
187rtems_status_code rtems_interrupt_handler_remove(
188  rtems_vector_number vector,
189  rtems_interrupt_handler handler,
190  void *arg
191)
192{
193  rtems_status_code sc = RTEMS_SUCCESSFUL;
194
195  if (bsp_interrupt_is_valid_vector(vector)) {
196    rtems_interrupt_level level;
197    interrupt_control *ic = &interrupt_controls[vector];
198
199    rtems_interrupt_disable(level);
200
201    if (
202      is_occupied_by_us(vector)
203        && ic->handler == handler
204        && ic->arg == arg
205    ) {
206      bsp_interrupt_vector_disable(vector);
207      set_exception_handler(vector, asm_default_interrupt);
208
209      memset(ic, 0, sizeof(*ic));
210    } else {
211      sc = RTEMS_UNSATISFIED;
212    }
213
214    rtems_interrupt_enable(level);
215  } else {
216    sc = RTEMS_INVALID_ID;
217  }
218
219  return sc;
220}
221
222rtems_status_code rtems_interrupt_handler_iterate(
223  rtems_vector_number vector,
224  rtems_interrupt_per_handler_routine routine,
225  void *arg
226)
227{
228  rtems_status_code sc = RTEMS_SUCCESSFUL;
229
230  if (bsp_interrupt_is_valid_vector(vector)) {
231    if (is_occupied_by_us(vector)) {
232      const interrupt_control *ic = &interrupt_controls[vector];
233
234      (*routine)(arg, ic->info, RTEMS_INTERRUPT_UNIQUE, ic->handler, ic->arg);
235    }
236  } else {
237    sc = RTEMS_INVALID_ID;
238  }
239
240  return sc;
241}
Note: See TracBrowser for help on using the repository browser.