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

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 8.8 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * RTEMS virtex BSP
5 *
6 * This file contains the irq controller handler.
7 */
8
9/*
10 * Copyright (c) 2007 embedded brains GmbH & Co. KG
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <libcpu/spr.h>
35#include <bsp/irq.h>
36#include <bsp.h>
37#include <rtems/bspIo.h>
38#include <rtems/powerpc/powerpc.h>
39#include <bsp/vectors.h>
40
41static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
42rtems_irq_connect_data *BSP_rtems_irq_tbl;
43rtems_irq_global_settings* BSP_rtems_irq_config;
44
45/***********************************************************
46 * dummy functions for on/off/isOn calls
47 * these functions just do nothing fulfill the semantic
48 * requirements to enable/disable a certain interrupt or exception
49 */
50static void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
51{
52  /*
53   * nothing to do
54   */
55}
56
57static void BSP_irq_nop_hdl(void *hdl)
58{
59  /*
60   * nothing to do
61   */
62}
63
64static int BSP_irq_isOn_func(const rtems_irq_connect_data *unused)
65{
66  /*
67   * nothing to do
68   */
69  return 0;
70}
71
72/***********************************************************
73 * interrupt handler and its enable/disable functions
74 ***********************************************************/
75
76/***********************************************************
77 * functions to enable/disable/query external/critical interrupts
78 */
79void BSP_irqexc_on_fnc(const rtems_irq_connect_data *conn_data)
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
91void BSP_irqexc_off_fnc(const rtems_irq_connect_data *unused)
92{
93  uint32_t msr_value;
94  /*
95   * get current MSR value
96   */
97  _CPU_MSR_GET(msr_value);
98
99  msr_value &= ~PPC_MSR_EE;
100  _CPU_MSR_SET(msr_value);
101}
102
103SPR_RW(BOOKE_TSR)
104
105static int C_dispatch_dec_handler (BSP_Exception_frame *frame, unsigned int excNum)
106{
107  /* Acknowledge the interrupt */
108  _write_BOOKE_TSR( BOOKE_TSR_DIS );
109
110  /* Handle the interrupt */
111  BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
112
113  return 0;
114}
115
116
117/***********************************************************
118 * High level IRQ handler called from shared_raw_irq_code_entry
119 */
120static int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
121{
122  /*
123   * Handle interrupt
124   */
125  switch(excNum) {
126  case ASM_EXT_VECTOR:
127    BSP_rtems_irq_tbl[BSP_EXT].hdl(BSP_rtems_irq_tbl[BSP_EXT].handle);
128    break;
129#if 0 /* Dealt with by C_dispatch_dec_handler(), above */
130  case ASM_BOOKE_DEC_VECTOR:
131    _write_BOOKE_TSR( BOOKE_TSR_DIS );
132    BSP_rtems_irq_tbl[BSP_DEC].hdl(BSP_rtems_irq_tbl[BSP_DEC].handle);
133    break;
134#endif
135#if 0 /* Critical interrupts not yet supported */
136  case ASM_BOOKE_CRIT_VECTOR:
137    BSP_rtems_irq_tbl[BSP_CRIT].hdl(BSP_rtems_irq_tbl[BSP_CRIT].handle);
138    break;
139#endif
140  }
141
142  return 0;
143}
144
145/***********************************************************
146 * functions to set/get/remove interrupt handlers
147 ***********************************************************/
148int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
149{
150  rtems_interrupt_level level;
151
152  /*
153   * check for valid irq name
154   * if invalid, print error and return 0
155   */
156  if (!BSP_IS_VALID_IRQ(irq->name)) {
157    printk("Invalid interrupt vector %d\n",irq->name);
158    return 0;
159  }
160
161  /*
162   * disable interrupts
163   */
164  rtems_interrupt_disable(level);
165
166  /*
167   * check, that default handler is installed now
168   */
169  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
170    rtems_interrupt_enable(level);
171    printk("IRQ vector %d already connected\n",irq->name);
172    return 0;
173  }
174
175  /*
176   * store new handler data
177   */
178  rtemsIrqTbl[irq->name] = *irq;
179
180  /*
181   * call "on" function to enable interrupt at device
182   */
183  irq->on(irq);
184
185  /*
186   * reenable interrupts
187   */
188  rtems_interrupt_enable(level);
189
190  return 1;
191}
192
193int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
194{
195  rtems_interrupt_level level;
196
197  /*
198   * check for valid IRQ name
199   */
200  if (!BSP_IS_VALID_IRQ(irq->name)) {
201    return 0;
202  }
203  rtems_interrupt_disable(level);
204
205  /*
206   * return current IRQ entry
207   */
208  *irq = rtemsIrqTbl[irq->name];
209  rtems_interrupt_enable(level);
210  return 1;
211}
212
213int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
214{
215  rtems_interrupt_level level;
216
217  /*
218   * check for valid IRQ name
219   */
220  if (!BSP_IS_VALID_IRQ(irq->name)) {
221    return 0;
222  }
223  rtems_interrupt_disable(level);
224
225  /*
226   * check, that specified handler is really connected now
227   */
228  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
229    rtems_interrupt_enable(level);
230    return 0;
231  }
232
233  /*
234   * disable interrupt at source
235   */
236  irq->off(irq);
237
238  /*
239   * restore default interrupt handler
240   */
241  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
242
243  /*
244   * reenable interrupts
245   */
246  rtems_interrupt_enable(level);
247
248  return 1;
249}
250
251/***********************************************************
252 * functions to set/get the basic interrupt management setup
253 ***********************************************************/
254/*
255 * (Re) get info on current RTEMS interrupt management.
256 */
257int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
258{
259  *ret_ptr = BSP_rtems_irq_config;
260  return 0;
261}
262
263
264/*
265 * set management stuff
266 */
267int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
268{
269  int                    i;
270  rtems_interrupt_level  level;
271
272  rtems_interrupt_disable(level);
273
274  /*
275   * store given configuration
276   */
277  BSP_rtems_irq_config = config;
278  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
279
280  /*
281   * store any irq-like processor exceptions
282   */
283  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
284       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
285       i++) {
286    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
287      if (BSP_rtems_irq_tbl[i].on != NULL) {
288        BSP_rtems_irq_tbl[i].on
289          (&(BSP_rtems_irq_tbl[i]));
290      }
291    }
292    else {
293      if (BSP_rtems_irq_tbl[i].off != NULL) {
294        BSP_rtems_irq_tbl[i].off
295          (&(BSP_rtems_irq_tbl[i]));
296      }
297    }
298  }
299  rtems_interrupt_enable(level);
300  return 1;
301}
302
303/*
304 * dummy for an empty IRQ handler entry
305 */
306static rtems_irq_connect_data emptyIrq = {
307  0,                     /* IRQ Name                 */
308  BSP_irq_nop_hdl,       /* handler function         */
309  NULL,                  /* handle passed to handler */
310  BSP_irq_nop_func,      /* on function              */
311  BSP_irq_nop_func,      /* off function             */
312  BSP_irq_isOn_func      /* isOn function            */
313};
314
315static rtems_irq_global_settings initialConfig = {
316  BSP_IRQ_NUMBER,           /* IRQ number               */
317  {  0,                     /* IRQ Name                 */
318     BSP_irq_nop_hdl,       /* handler function         */
319     NULL,                  /* handle passed to handler */
320     BSP_irq_nop_func,      /* on function              */
321     BSP_irq_nop_func,      /* off function             */
322     BSP_irq_isOn_func      /* isOn function            */
323  }, /* emptyIrq */
324  rtemsIrqTbl, /* irqHdlTbl  */
325  0,           /* irqBase    */
326  NULL         /* irqPrioTbl */
327};
328
329void BSP_rtems_irq_mngt_init(unsigned cpuId)
330{
331  int i;
332
333  /*
334   * connect all exception vectors needed
335   */
336  ppc_exc_set_handler(ASM_EXT_VECTOR,       C_dispatch_irq_handler);
337  ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler);
338
339  /*
340   * setup interrupt handlers table
341   */
342  for (i = 0;
343       i < BSP_IRQ_NUMBER;
344       i++) {
345    rtemsIrqTbl[i]      = emptyIrq;
346    rtemsIrqTbl[i].name = i;
347  }
348
349  /*
350   * initialize interrupt management
351   */
352  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
353    rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
354  }
355}
Note: See TracBrowser for help on using the repository browser.