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

5
Last change on this file since 8f8ccee was 8f8ccee, checked in by Sebastian Huber <sebastian.huber@…>, on 04/23/18 at 07:50:39

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.3 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
91/***********************************************************
92 * High level IRQ handler called from shared_raw_irq_code_entry
93 */
94static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
95{
96  /*
97   * Handle interrupt
98   */
99  switch(excNum) {
100  case ASM_EXT_VECTOR:
101    BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
102    break;
103  case ASM_BOOKE_DEC_VECTOR:
104    BSP_rtems_irq_tbl[BSP_PIT].hdl(BSP_rtems_irq_tbl[BSP_PIT].handle);
105    break;
106#if 0 /* Critical interrupts not yet supported */
107  case ASM_BOOKE_CRIT_VECTOR:
108    BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
109    break;
110#endif
111  }
112
113  return 0;
114}
115
116/***********************************************************
117 * functions to set/get/remove interrupt handlers
118 ***********************************************************/
119int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
120{
121  rtems_interrupt_level level;
122
123  /*
124   * check for valid irq name
125   * if invalid, print error and return 0
126   */
127  if (!BSP_IS_VALID_IRQ(irq->name)) {
128    printk("Invalid interrupt vector %d\n",irq->name);
129    return 0;
130  }
131
132  /*
133   * disable interrupts
134   */
135  rtems_interrupt_disable(level);
136
137  /*
138   * check, that default handler is installed now
139   */
140  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
141    rtems_interrupt_enable(level);
142    printk("IRQ vector %d already connected\n",irq->name);
143    return 0;
144  }
145
146  /*
147   * store new handler data
148   */
149  rtemsIrqTbl[irq->name] = *irq;
150
151  /*
152   * call "on" function to enable interrupt at device
153   */
154  irq->on(irq);
155
156  /*
157   * reenable interrupts
158   */
159  rtems_interrupt_enable(level);
160
161  return 1;
162}
163
164int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
165{
166  rtems_interrupt_level level;
167
168  /*
169   * check for valid IRQ name
170   */
171  if (!BSP_IS_VALID_IRQ(irq->name)) {
172    return 0;
173  }
174  rtems_interrupt_disable(level);
175
176  /*
177   * return current IRQ entry
178   */
179  *irq = rtemsIrqTbl[irq->name];
180  rtems_interrupt_enable(level);
181  return 1;
182}
183
184int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
185{
186  rtems_interrupt_level level;
187
188  /*
189   * check for valid IRQ name
190   */
191  if (!BSP_IS_VALID_IRQ(irq->name)) {
192    return 0;
193  }
194  rtems_interrupt_disable(level);
195
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  /*
205   * disable interrupt at source
206   */
207  irq->off(irq);
208
209  /*
210   * restore default interrupt handler
211   */
212  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
213
214  /*
215   * reenable interrupts
216   */
217  rtems_interrupt_enable(level);
218
219  return 1;
220}
221
222/***********************************************************
223 * functions to set/get the basic interrupt management setup
224 ***********************************************************/
225/*
226 * (Re) get info on current RTEMS interrupt management.
227 */
228int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
229{
230  *ret_ptr = BSP_rtems_irq_config;
231  return 0;
232}
233
234
235/*
236 * set management stuff
237 */
238int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
239{
240  int                    i;
241  rtems_interrupt_level  level;
242
243  rtems_interrupt_disable(level);
244
245  /*
246   * store given configuration
247   */
248  BSP_rtems_irq_config = config;
249  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
250
251  /*
252   * store any irq-like processor exceptions
253   */
254  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
255       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
256       i++) {
257    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
258      if (BSP_rtems_irq_tbl[i].on != NULL) {
259        BSP_rtems_irq_tbl[i].on
260          (&(BSP_rtems_irq_tbl[i]));
261      }
262    }
263    else {
264      if (BSP_rtems_irq_tbl[i].off != NULL) {
265        BSP_rtems_irq_tbl[i].off
266          (&(BSP_rtems_irq_tbl[i]));
267      }
268    }
269  }
270  rtems_interrupt_enable(level);
271  return 1;
272}
273
274/*
275 * dummy for an empty IRQ handler entry
276 */
277static rtems_irq_connect_data emptyIrq = {
278  0,                     /* IRQ Name                 */
279  BSP_irq_nop_hdl,       /* handler function         */
280  NULL,                  /* handle passed to handler */
281  BSP_irq_nop_func,      /* on function              */
282  BSP_irq_nop_func,      /* off function             */
283  BSP_irq_isOn_func      /* isOn function            */
284};
285
286static rtems_irq_global_settings initialConfig = {
287  BSP_IRQ_NUMBER,           /* IRQ Number               */
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  }, /* emptyIrq */
295  rtemsIrqTbl, /* irqHdlTbl  */
296  0,           /* irqBase    */
297  NULL         /* irqPrioTbl */
298};
299
300void BSP_rtems_irq_mngt_init(unsigned cpuId)
301{
302  int i;
303
304  /*
305   * connect all exception vectors needed
306   */
307  ppc_exc_set_handler(ASM_EXT_VECTOR,       C_dispatch_irq_handler);
308  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_irq_handler);
309
310  /*
311   * setup interrupt handlers table
312   */
313  for (i = 0;
314       i < BSP_IRQ_NUMBER;
315       i++) {
316    rtemsIrqTbl[i]      = emptyIrq;
317    rtemsIrqTbl[i].name = i;
318  }
319
320  /*
321   * initialize interrupt management
322   */
323  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
324    rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
325  }
326}
Note: See TracBrowser for help on using the repository browser.