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

5
Last change on this file since 8f8ccee was 8f8ccee, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 23, 2018 at 7:50:39 AM

bsps: Move interrupt controller support to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 8.7 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.org/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 */
38static void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
39{
40  /*
41   * nothing to do
42   */
43}
44
45static void BSP_irq_nop_hdl(void *hdl)
46{
47  /*
48   * nothing to do
49   */
50}
51
52static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
53{
54  /*
55   * nothing to do
56   */
57  return 0;
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(const 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  msr_value |= PPC_MSR_EE;
76  _CPU_MSR_SET(msr_value);
77}
78
79void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
80{
81  uint32_t msr_value;
82  /*
83   * get current MSR value
84   */
85  _CPU_MSR_GET(msr_value);
86
87  msr_value &= ~PPC_MSR_EE;
88  _CPU_MSR_SET(msr_value);
89}
90
91SPR_RW(BOOKE_TSR)
92
93static int C_dispatch_dec_handler (BSP_Exception_frame *frame, unsigned int excNum)
94{
95  /* Acknowledge the interrupt */
96  _write_BOOKE_TSR( BOOKE_TSR_DIS );
97
98  /* Handle the interrupt */
99  BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
100
101  return 0;
102}
103
104
105/***********************************************************
106 * High level IRQ handler called from shared_raw_irq_code_entry
107 */
108static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
109{
110  /*
111   * Handle interrupt
112   */
113  switch(excNum) {
114  case ASM_EXT_VECTOR:
115    BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
116    break;
117#if 0 /* Dealt with by C_dispatch_dec_handler(), above */
118  case ASM_BOOKE_DEC_VECTOR:
119    _write_BOOKE_TSR( BOOKE_TSR_DIS );
120    BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
121    break;
122#endif
123#if 0 /* Critical interrupts not yet supported */
124  case ASM_BOOKE_CRIT_VECTOR:
125    BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
126    break;
127#endif
128  }
129
130  return 0;
131}
132
133/***********************************************************
134 * functions to set/get/remove interrupt handlers
135 ***********************************************************/
136int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
137{
138  rtems_interrupt_level level;
139
140  /*
141   * check for valid irq name
142   * if invalid, print error and return 0
143   */
144  if (!BSP_IS_VALID_IRQ(irq->name)) {
145    printk("Invalid interrupt vector %d\n",irq->name);
146    return 0;
147  }
148
149  /*
150   * disable interrupts
151   */
152  rtems_interrupt_disable(level);
153
154  /*
155   * check, that default handler is installed now
156   */
157  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
158    rtems_interrupt_enable(level);
159    printk("IRQ vector %d already connected\n",irq->name);
160    return 0;
161  }
162
163  /*
164   * store new handler data
165   */
166  rtemsIrqTbl[irq->name] = *irq;
167
168  /*
169   * call "on" function to enable interrupt at device
170   */
171  irq->on(irq);
172
173  /*
174   * reenable interrupts
175   */
176  rtems_interrupt_enable(level);
177
178  return 1;
179}
180
181int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
182{
183  rtems_interrupt_level level;
184
185  /*
186   * check for valid IRQ name
187   */
188  if (!BSP_IS_VALID_IRQ(irq->name)) {
189    return 0;
190  }
191  rtems_interrupt_disable(level);
192
193  /*
194   * return current IRQ entry
195   */
196  *irq = rtemsIrqTbl[irq->name];
197  rtems_interrupt_enable(level);
198  return 1;
199}
200
201int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
202{
203  rtems_interrupt_level level;
204
205  /*
206   * check for valid IRQ name
207   */
208  if (!BSP_IS_VALID_IRQ(irq->name)) {
209    return 0;
210  }
211  rtems_interrupt_disable(level);
212
213  /*
214   * check, that specified handler is really connected now
215   */
216  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
217    rtems_interrupt_enable(level);
218    return 0;
219  }
220
221  /*
222   * disable interrupt at source
223   */
224  irq->off(irq);
225
226  /*
227   * restore default interrupt handler
228   */
229  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
230
231  /*
232   * reenable interrupts
233   */
234  rtems_interrupt_enable(level);
235
236  return 1;
237}
238
239/***********************************************************
240 * functions to set/get the basic interrupt management setup
241 ***********************************************************/
242/*
243 * (Re) get info on current RTEMS interrupt management.
244 */
245int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
246{
247  *ret_ptr = BSP_rtems_irq_config;
248  return 0;
249}
250
251
252/*
253 * set management stuff
254 */
255int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
256{
257  int                    i;
258  rtems_interrupt_level  level;
259
260  rtems_interrupt_disable(level);
261
262  /*
263   * store given configuration
264   */
265  BSP_rtems_irq_config = config;
266  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
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_isOn_func      /* isOn function            */
301};
302
303static rtems_irq_global_settings initialConfig = {
304  BSP_IRQ_NUMBER,           /* IRQ number               */
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_isOn_func      /* isOn function            */
311  }, /* emptyIrq */
312  rtemsIrqTbl, /* irqHdlTbl  */
313  0,           /* irqBase    */
314  NULL         /* irqPrioTbl */
315};
316
317void BSP_rtems_irq_mngt_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_dec_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  /*
338   * initialize interrupt management
339   */
340  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
341    rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
342  }
343}
Note: See TracBrowser for help on using the repository browser.