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

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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