source: rtems/bsps/powerpc/virtex5/irq/irq_init.c @ f0f6e888

Last change on this file since f0f6e888 was f0f6e888, checked in by Christian Mauderer <christian.mauderer@…>, on 03/03/22 at 09:17:19

bsps/powerpc: Manual file header clean up

Updates #4625.

  • Property mode set to 100644
File size: 7.6 KB
Line 
1/*
2 * RTEMS virtex BSP
3 *
4 * This file contains the irq controller handler.
5 */
6
7/*
8 * Copyright (c) 2007 embedded brains GmbH. All rights reserved.
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 <libcpu/spr.h>
16#include <bsp/irq.h>
17#include <bsp.h>
18#include <rtems/bspIo.h>
19#include <rtems/powerpc/powerpc.h>
20#include <bsp/vectors.h>
21
22static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
23rtems_irq_connect_data *BSP_rtems_irq_tbl;
24rtems_irq_global_settings* BSP_rtems_irq_config;
25
26/***********************************************************
27 * dummy functions for on/off/isOn calls
28 * these functions just do nothing fulfill the semantic
29 * requirements to enable/disable a certain interrupt or exception
30 */
31static void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
32{
33  /*
34   * nothing to do
35   */
36}
37
38static void BSP_irq_nop_hdl(void *hdl)
39{
40  /*
41   * nothing to do
42   */
43}
44
45static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
46{
47  /*
48   * nothing to do
49   */
50  return 0;
51}
52
53/***********************************************************
54 * interrupt handler and its enable/disable functions
55 ***********************************************************/
56
57/***********************************************************
58 * functions to enable/disable/query external/critical interrupts
59 */
60void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data)
61{
62  uint32_t msr_value;
63  /*
64   * get current MSR value
65   */
66  _CPU_MSR_GET(msr_value);
67
68  msr_value |= PPC_MSR_EE;
69  _CPU_MSR_SET(msr_value);
70}
71
72void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
73{
74  uint32_t msr_value;
75  /*
76   * get current MSR value
77   */
78  _CPU_MSR_GET(msr_value);
79
80  msr_value &= ~PPC_MSR_EE;
81  _CPU_MSR_SET(msr_value);
82}
83
84SPR_RW(BOOKE_TSR)
85
86static int C_dispatch_dec_handler (BSP_Exception_frame *frame, unsigned int excNum)
87{
88  /* Acknowledge the interrupt */
89  _write_BOOKE_TSR( BOOKE_TSR_DIS );
90
91  /* Handle the interrupt */
92  BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
93
94  return 0;
95}
96
97
98/***********************************************************
99 * High level IRQ handler called from shared_raw_irq_code_entry
100 */
101static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
102{
103  /*
104   * Handle interrupt
105   */
106  switch(excNum) {
107  case ASM_EXT_VECTOR:
108    BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
109    break;
110#if 0 /* Dealt with by C_dispatch_dec_handler(), above */
111  case ASM_BOOKE_DEC_VECTOR:
112    _write_BOOKE_TSR( BOOKE_TSR_DIS );
113    BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
114    break;
115#endif
116#if 0 /* Critical interrupts not yet supported */
117  case ASM_BOOKE_CRIT_VECTOR:
118    BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
119    break;
120#endif
121  }
122
123  return 0;
124}
125
126/***********************************************************
127 * functions to set/get/remove interrupt handlers
128 ***********************************************************/
129int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
130{
131  rtems_interrupt_level level;
132
133  /*
134   * check for valid irq name
135   * if invalid, print error and return 0
136   */
137  if (!BSP_IS_VALID_IRQ(irq->name)) {
138    printk("Invalid interrupt vector %d\n",irq->name);
139    return 0;
140  }
141
142  /*
143   * disable interrupts
144   */
145  rtems_interrupt_disable(level);
146
147  /*
148   * check, that default handler is installed now
149   */
150  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
151    rtems_interrupt_enable(level);
152    printk("IRQ vector %d already connected\n",irq->name);
153    return 0;
154  }
155
156  /*
157   * store new handler data
158   */
159  rtemsIrqTbl[irq->name] = *irq;
160
161  /*
162   * call "on" function to enable interrupt at device
163   */
164  irq->on(irq);
165
166  /*
167   * reenable interrupts
168   */
169  rtems_interrupt_enable(level);
170
171  return 1;
172}
173
174int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
175{
176  rtems_interrupt_level level;
177
178  /*
179   * check for valid IRQ name
180   */
181  if (!BSP_IS_VALID_IRQ(irq->name)) {
182    return 0;
183  }
184  rtems_interrupt_disable(level);
185
186  /*
187   * return current IRQ entry
188   */
189  *irq = rtemsIrqTbl[irq->name];
190  rtems_interrupt_enable(level);
191  return 1;
192}
193
194int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
195{
196  rtems_interrupt_level level;
197
198  /*
199   * check for valid IRQ name
200   */
201  if (!BSP_IS_VALID_IRQ(irq->name)) {
202    return 0;
203  }
204  rtems_interrupt_disable(level);
205
206  /*
207   * check, that specified handler is really connected now
208   */
209  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
210    rtems_interrupt_enable(level);
211    return 0;
212  }
213
214  /*
215   * disable interrupt at source
216   */
217  irq->off(irq);
218
219  /*
220   * restore default interrupt handler
221   */
222  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
223
224  /*
225   * reenable interrupts
226   */
227  rtems_interrupt_enable(level);
228
229  return 1;
230}
231
232/***********************************************************
233 * functions to set/get the basic interrupt management setup
234 ***********************************************************/
235/*
236 * (Re) get info on current RTEMS interrupt management.
237 */
238int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
239{
240  *ret_ptr = BSP_rtems_irq_config;
241  return 0;
242}
243
244
245/*
246 * set management stuff
247 */
248int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
249{
250  int                    i;
251  rtems_interrupt_level  level;
252
253  rtems_interrupt_disable(level);
254
255  /*
256   * store given configuration
257   */
258  BSP_rtems_irq_config = config;
259  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
260
261  /*
262   * store any irq-like processor exceptions
263   */
264  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
265       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
266       i++) {
267    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
268      if (BSP_rtems_irq_tbl[i].on != NULL) {
269        BSP_rtems_irq_tbl[i].on
270          (&(BSP_rtems_irq_tbl[i]));
271      }
272    }
273    else {
274      if (BSP_rtems_irq_tbl[i].off != NULL) {
275        BSP_rtems_irq_tbl[i].off
276          (&(BSP_rtems_irq_tbl[i]));
277      }
278    }
279  }
280  rtems_interrupt_enable(level);
281  return 1;
282}
283
284/*
285 * dummy for an empty IRQ handler entry
286 */
287static rtems_irq_connect_data emptyIrq = {
288  0,                     /* IRQ Name                 */
289  BSP_irq_nop_hdl,       /* handler function         */
290  NULL,                  /* handle passed to handler */
291  BSP_irq_nop_func,      /* on function              */
292  BSP_irq_nop_func,      /* off function             */
293  BSP_irq_isOn_func      /* isOn function            */
294};
295
296static rtems_irq_global_settings initialConfig = {
297  BSP_IRQ_NUMBER,           /* IRQ number               */
298  {  0,                     /* IRQ Name                 */
299     BSP_irq_nop_hdl,       /* handler function         */
300     NULL,                  /* handle passed to handler */
301     BSP_irq_nop_func,      /* on function              */
302     BSP_irq_nop_func,      /* off function             */
303     BSP_irq_isOn_func      /* isOn function            */
304  }, /* emptyIrq */
305  rtemsIrqTbl, /* irqHdlTbl  */
306  0,           /* irqBase    */
307  NULL         /* irqPrioTbl */
308};
309
310void BSP_rtems_irq_mngt_init(unsigned cpuId)
311{
312  int i;
313
314  /*
315   * connect all exception vectors needed
316   */
317  ppc_exc_set_handler(ASM_EXT_VECTOR,       C_dispatch_irq_handler);
318  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler);
319
320  /*
321   * setup interrupt handlers table
322   */
323  for (i = 0;
324       i < BSP_IRQ_NUMBER;
325       i++) {
326    rtemsIrqTbl[i]      = emptyIrq;
327    rtemsIrqTbl[i].name = i;
328  }
329
330  /*
331   * initialize interrupt management
332   */
333  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
334    rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
335  }
336}
Note: See TracBrowser for help on using the repository browser.