source: rtems/c/src/lib/libbsp/powerpc/gen83xx/irq/irq_init.c @ 52e4f356

4.104.114.84.95
Last change on this file since 52e4f356 was 52e4f356, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 17, 2007 at 2:15:14 PM

2007-09-17 Joel Sherrill <joel.sherrill@…>

  • console/console.c, irq/irq_init.c: Eliminate warnings.
  • Property mode set to 100644
File size: 10.6 KB
Line 
1/*===============================================================*\
2| Project: RTEMS generic MPC83xx BSP                              |
3+-----------------------------------------------------------------+
4|                    Copyright (c) 2007                           |
5|                    Embedded Brains GmbH                         |
6|                    Obere Lagerstr. 30                           |
7|                    D-82178 Puchheim                             |
8|                    Germany                                      |
9|                    rtems@embedded-brains.de                     |
10+-----------------------------------------------------------------+
11| The license and distribution terms for this file may be         |
12| found in the file LICENSE in this distribution or at            |
13|                                                                 |
14| http://www.rtems.com/license/LICENSE.                           |
15|                                                                 |
16+-----------------------------------------------------------------+
17| this file contains the irq controller init code                 |
18+-----------------------------------------------------------------+
19| derived from the virtex BSP                                     |
20\*===============================================================*/
21#include <libcpu/spr.h>
22#include <bsp/irq.h>
23#include <bsp.h>
24#include <libcpu/raw_exception.h>
25#include <rtems/bspIo.h>
26#include <rtems/powerpc/powerpc.h>
27#include <rtems/score/apiext.h>
28#include <bsp/vectors.h>
29
30
31static rtems_irq_connect_data rtemsIrqTbl[BSP_IRQ_NUMBER];
32rtems_irq_connect_data *BSP_rtems_irq_tbl;
33rtems_irq_global_settings* BSP_rtems_irq_config;
34
35/***********************************************************
36 * dummy functions for on/off/isOn calls
37 * these functions just do nothing fulfill the semantic
38 * requirements to enable/disable a certain interrupt or exception
39 */
40void BSP_irq_nop_func(const rtems_irq_connect_data *unused)
41{
42  /*
43   * nothing to do
44   */
45}
46
47void BSP_irq_nop_hdl(void *hdl)
48{
49  /*
50   * nothing to do
51   */
52}
53
54int BSP_irq_true_func(const rtems_irq_connect_data *unused)
55{
56  /*
57   * nothing to do
58   */
59  return TRUE;
60}
61
62/***********************************************************
63 * interrupt handler and its enable/disable functions
64 ***********************************************************/
65
66/***********************************************************
67 * functions to enable/disable/query external/critical interrupts
68 */
69void BSP_irqexc_on_fnc(rtems_irq_connect_data *conn_data)
70{
71  uint32_t msr_value;
72  /*
73   * get current MSR value
74   */
75  _CPU_MSR_GET(msr_value);
76
77
78   msr_value |= PPC_MSR_EE;
79   _CPU_MSR_SET(msr_value);
80}
81
82void BSP_irqexc_off_fnc(rtems_irq_connect_data *unused)
83{
84  /*
85   * nothing to do
86   */
87}
88
89/***********************************************************
90 * High level IRQ handler called from shared_raw_irq_code_entry
91 */
92void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum)
93{
94  uint32_t msr_value,new_msr;
95
96  /*
97   * Handle interrupt
98   */
99  switch(excNum) {
100  case ASM_DEC_VECTOR:
101    _CPU_MSR_GET(msr_value);
102    new_msr = msr_value | MSR_EE;
103    _CPU_MSR_SET(new_msr);
104   
105    BSP_rtems_irq_tbl[BSP_DECREMENTER].hdl
106      (BSP_rtems_irq_tbl[BSP_DECREMENTER].handle);
107   
108    _CPU_MSR_SET(msr_value);
109   
110    break;
111#if 0 /* Critical interrupts not yet supported */
112  case ASM_CRIT_VECTOR:
113#endif
114  case ASM_SYSMGMT_VECTOR:
115  case ASM_EXT_VECTOR:
116    BSP_irq_handle_at_ipic(excNum);
117    break;
118  }
119}
120 
121void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
122{
123  /*
124   * Process pending signals that have not already been
125   * processed by _Thread_Displatch. This happens quite
126   * unfrequently : the ISR must have posted an action
127   * to the current running thread.
128   */
129  if ( _Thread_Do_post_task_switch_extension ||
130       _Thread_Executing->do_post_task_switch_extension ) {
131    _Thread_Executing->do_post_task_switch_extension = FALSE;
132    _API_extensions_Run_postswitch();
133  }
134}
135
136/***********************************************************
137 * functions to set/get/remove interrupt handlers
138 ***********************************************************/
139int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
140{
141  rtems_interrupt_level level;
142
143  /*
144   * check for valid irq name
145   * if invalid, print error and return 0
146   */
147  if (!BSP_IS_VALID_IRQ(irq->name)) {
148    printk("Invalid interrupt vector %d\n",irq->name);
149    return 0;
150  }
151
152  /*
153   * disable interrupts
154   */
155  rtems_interrupt_disable(level);
156  /*
157   * check, that default handler is installed now
158   */
159  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
160    rtems_interrupt_enable(level);
161    printk("IRQ vector %d already connected\n",irq->name);
162    return 0;
163  }
164  /*
165   * store new handler data
166   */
167  rtemsIrqTbl[irq->name] = *irq;
168
169  /*
170   * enable irq at interrupt controller
171   */
172  if (BSP_IS_IPIC_IRQ(irq->name)) {
173    BSP_irq_enable_at_ipic(irq->name);
174  }
175  /*
176   * call "on" function to enable interrupt at device
177   */
178  irq->on(irq);
179  /*
180   * reenable interrupts
181   */
182  rtems_interrupt_enable(level);
183
184  return 1;
185}
186
187int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
188{
189  rtems_interrupt_level level;
190 
191  /*
192   * check for valid IRQ name
193   */
194  if (!BSP_IS_VALID_IRQ(irq->name)) {
195    return 0;
196  }
197  rtems_interrupt_disable(level);
198  /*
199   * return current IRQ entry
200   */
201  *irq = rtemsIrqTbl[irq->name];
202  rtems_interrupt_enable(level);
203  return 1;
204}
205
206int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
207{
208  rtems_interrupt_level level;
209 
210  /*
211   * check for valid IRQ name
212   */
213  if (!BSP_IS_VALID_IRQ(irq->name)) {
214    return 0;
215  }
216  rtems_interrupt_disable(level);
217  /*
218   * check, that specified handler is really connected now
219   */
220  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
221    rtems_interrupt_enable(level);
222    return 0;
223  }
224  /*
225   * disable interrupt at interrupt controller
226   */
227  if (BSP_IS_IPIC_IRQ(irq->name)) {
228    BSP_irq_disable_at_ipic(irq->name);
229  }
230  /*
231   * disable interrupt at source
232   */
233  irq->off(irq);
234  /*
235   * restore default interrupt handler
236   */
237  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
238
239  /*
240   * reenable interrupts
241   */
242  rtems_interrupt_enable(level);
243
244  return 1;
245}
246
247/***********************************************************
248 * functions to set/get the basic interrupt management setup
249 ***********************************************************/
250/*
251 * (Re) get info on current RTEMS interrupt management.
252 */
253int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
254{
255  *ret_ptr = BSP_rtems_irq_config;
256  return 0;
257}
258
259
260/*
261 * set management stuff
262 */
263int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
264{
265  int                    i;
266  rtems_interrupt_level  level;
267
268  rtems_interrupt_disable(level);
269  /*
270   * store given configuration
271   */
272  BSP_rtems_irq_config = config;
273  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
274  /*
275   * enable any non-empty IRQ entries at OPBINTC
276   */
277  for (i =  BSP_IPIC_IRQ_LOWEST_OFFSET;
278       i <= BSP_IPIC_IRQ_MAX_OFFSET;
279       i++) {
280    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
281      BSP_irq_enable_at_ipic(i);
282      BSP_rtems_irq_tbl[i].on((&BSP_rtems_irq_tbl[i]));
283    }
284    else {
285      BSP_rtems_irq_tbl[i].off(&(BSP_rtems_irq_tbl[i]));
286      BSP_irq_disable_at_ipic(i);
287    }
288  }
289  /*
290   * store any irq-like processor exceptions
291   */
292  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET; 
293       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
294       i++) {
295    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
296      if (BSP_rtems_irq_tbl[i].on != NULL) {
297        BSP_rtems_irq_tbl[i].on
298          (&(BSP_rtems_irq_tbl[i]));
299      }
300    }
301    else {
302      if (BSP_rtems_irq_tbl[i].off != NULL) {
303        BSP_rtems_irq_tbl[i].off
304          (&(BSP_rtems_irq_tbl[i]));
305      }
306    }
307  }
308  rtems_interrupt_enable(level);
309  return 1;
310}
311/**********************************************
312 * list of exception vectors to tap for interrupt handlers
313 */
314static rtems_raw_except_connect_data BSP_vec_desc[] = {
315#if defined(ASM_DEC_VECTOR)
316  {ASM_DEC_VECTOR,
317   {ASM_DEC_VECTOR,
318    decrementer_exception_vector_prolog_code,
319    (size_t)decrementer_exception_vector_prolog_code_size
320   },
321   exception_nop_enable,
322   exception_nop_enable,
323   exception_always_enabled
324  },
325#endif
326#if defined(ASM_SYSMGMT_VECTOR)
327  {ASM_SYSMGMT_VECTOR,
328   {ASM_SYSMGMT_VECTOR,
329    sysmgmt_exception_vector_prolog_code,
330    (size_t)sysmgmt_exception_vector_prolog_code_size
331   },
332   exception_nop_enable,
333   exception_nop_enable,
334   exception_always_enabled
335  },
336#endif
337  {ASM_EXT_VECTOR,
338   {ASM_EXT_VECTOR,
339    external_exception_vector_prolog_code,
340    (size_t)&external_exception_vector_prolog_code_size
341   },
342   exception_nop_enable,
343   exception_nop_enable,
344   exception_always_enabled
345  }
346#if 0 /* Critical interrupts not yet supported */
347  ,{ASM_CRIT_VECTOR,
348   {ASM_CRIT_VECTOR,
349    critical_exception_vector_prolog_code,
350    critical_exception_vector_prolog_code_size
351   }
352   BSP_irq_nop_func,
353   BSP_irq_nop_func,
354   BSP_irq_true_func
355  }
356#endif
357};
358
359/*
360 * dummy for an empty IRQ handler entry
361 */ 
362static rtems_irq_connect_data emptyIrq = {
363  0,                     /* Irq Name                 */
364  BSP_irq_nop_hdl,       /* handler function         */
365  NULL,                  /* handle passed to handler */
366  BSP_irq_nop_func,      /* on function              */
367  BSP_irq_nop_func,      /* off function             */
368  BSP_irq_true_func      /* isOn function            */
369};
370
371static rtems_irq_global_settings initialConfig = {
372  BSP_IRQ_NUMBER,    /* irqNb */
373  {  0,                          /* Irq Name                 */
374     BSP_irq_nop_hdl,       /* handler function         */
375     NULL,                  /* handle passed to handler */
376     BSP_irq_nop_func,      /* on function              */
377     BSP_irq_nop_func,      /* off function             */
378     BSP_irq_true_func      /* isOn function            */
379  }, /* emptyIrq */
380  rtemsIrqTbl, /* irqHdlTbl  */
381  0,           /* irqBase    */
382  NULL         /* irqPrioTbl */
383};
384
385void BSP_rtems_irq_mng_init(unsigned cpuId)
386{
387  int i;
388  /*
389   * connect all exception vectors needed
390   */
391  for (i = 0;
392       i < (sizeof(BSP_vec_desc) / 
393            sizeof(BSP_vec_desc[0]));
394       i++) {
395    if (!ppc_set_exception (&BSP_vec_desc[i])) {
396      BSP_panic("Unable to initialize RTEMS raw exception\n");
397    }
398  }
399  /*
400   * setup interrupt handlers table
401   */
402  for (i = 0;
403       i < BSP_IRQ_NUMBER;
404       i++) {
405    rtemsIrqTbl[i]      = emptyIrq;
406    rtemsIrqTbl[i].name = i;
407  }
408
409  /*
410   * initialize interrupt management
411   */
412  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
413    BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
414  } 
415}
416
Note: See TracBrowser for help on using the repository browser.