source: rtems/c/src/lib/libbsp/powerpc/virtex/irq/irq_init.c @ ac7af4a

4.104.115
Last change on this file since ac7af4a was ac7af4a, checked in by Ralf Corsepius <ralf.corsepius@…>, on 11/30/09 at 04:37:44

Whitespace removal.

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