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

4.104.114.95
Last change on this file since a9e62c2 was a9e62c2, checked in by Till Straumann <strauman@…>, on 12/08/07 at 17:26:19

2007-12-08 Till Straumann <strauman@…>

  • ep1a/irq/irq.c, gen5200/irq/irq.c, gen83xx/irq/irq_init.c, mbx8xx/irq/irq.c, mpc8260ads/irq/irq.c, mvme5500/irq/irq.c, psim/irq/no_pic.c, score603e/irq/irq.c, shared/irq/irq_supp.h, shared/irq/openpic_i8259_irq.c, virtex/irq/irq_init.c: let C_dispatch_irq_handler() return zero to indicate to low-level exception handling code that the exception was handled (not used yet).
  • Property mode set to 100644
File size: 10.7 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 */
92int 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_BOOKE_CRIT_VECTOR:
113#endif
114  case ASM_60X_SYSMGMT_VECTOR:
115  case ASM_EXT_VECTOR:
116    BSP_irq_handle_at_ipic(excNum);
117    break;
118  }
119  return 0;
120}
121 
122void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx)
123{
124  /*
125   * Process pending signals that have not already been
126   * processed by _Thread_Displatch. This happens quite
127   * unfrequently : the ISR must have posted an action
128   * to the current running thread.
129   */
130  if ( _Thread_Do_post_task_switch_extension ||
131       _Thread_Executing->do_post_task_switch_extension ) {
132    _Thread_Executing->do_post_task_switch_extension = FALSE;
133    _API_extensions_Run_postswitch();
134  }
135}
136
137/***********************************************************
138 * functions to set/get/remove interrupt handlers
139 ***********************************************************/
140int BSP_install_rtems_irq_handler  (const rtems_irq_connect_data* irq)
141{
142  rtems_interrupt_level level;
143
144  /*
145   * check for valid irq name
146   * if invalid, print error and return 0
147   */
148  if (!BSP_IS_VALID_IRQ(irq->name)) {
149    printk("Invalid interrupt vector %d\n",irq->name);
150    return 0;
151  }
152
153  /*
154   * disable interrupts
155   */
156  rtems_interrupt_disable(level);
157  /*
158   * check, that default handler is installed now
159   */
160  if (rtemsIrqTbl[irq->name].hdl != BSP_rtems_irq_config->defaultEntry.hdl) {
161    rtems_interrupt_enable(level);
162    printk("IRQ vector %d already connected\n",irq->name);
163    return 0;
164  }
165  /*
166   * store new handler data
167   */
168  rtemsIrqTbl[irq->name] = *irq;
169
170  /*
171   * enable irq at interrupt controller
172   */
173  if (BSP_IS_IPIC_IRQ(irq->name)) {
174    BSP_irq_enable_at_ipic(irq->name);
175  }
176  /*
177   * call "on" function to enable interrupt at device
178   */
179  irq->on(irq);
180  /*
181   * reenable interrupts
182   */
183  rtems_interrupt_enable(level);
184
185  return 1;
186}
187
188int BSP_get_current_rtems_irq_handler   (rtems_irq_connect_data* irq)
189{
190  rtems_interrupt_level level;
191 
192  /*
193   * check for valid IRQ name
194   */
195  if (!BSP_IS_VALID_IRQ(irq->name)) {
196    return 0;
197  }
198  rtems_interrupt_disable(level);
199  /*
200   * return current IRQ entry
201   */
202  *irq = rtemsIrqTbl[irq->name];
203  rtems_interrupt_enable(level);
204  return 1;
205}
206
207int BSP_remove_rtems_irq_handler  (const rtems_irq_connect_data* irq)
208{
209  rtems_interrupt_level level;
210 
211  /*
212   * check for valid IRQ name
213   */
214  if (!BSP_IS_VALID_IRQ(irq->name)) {
215    return 0;
216  }
217  rtems_interrupt_disable(level);
218  /*
219   * check, that specified handler is really connected now
220   */
221  if (rtemsIrqTbl[irq->name].hdl != irq->hdl) {
222    rtems_interrupt_enable(level);
223    return 0;
224  }
225  /*
226   * disable interrupt at interrupt controller
227   */
228  if (BSP_IS_IPIC_IRQ(irq->name)) {
229    BSP_irq_disable_at_ipic(irq->name);
230  }
231  /*
232   * disable interrupt at source
233   */
234  irq->off(irq);
235  /*
236   * restore default interrupt handler
237   */
238  rtemsIrqTbl[irq->name] = BSP_rtems_irq_config->defaultEntry;
239
240  /*
241   * reenable interrupts
242   */
243  rtems_interrupt_enable(level);
244
245  return 1;
246}
247
248/***********************************************************
249 * functions to set/get the basic interrupt management setup
250 ***********************************************************/
251/*
252 * (Re) get info on current RTEMS interrupt management.
253 */
254int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** ret_ptr)
255{
256  *ret_ptr = BSP_rtems_irq_config;
257  return 0;
258}
259
260
261/*
262 * set management stuff
263 */
264int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
265{
266  int                    i;
267  rtems_interrupt_level  level;
268
269  rtems_interrupt_disable(level);
270  /*
271   * store given configuration
272   */
273  BSP_rtems_irq_config = config;
274  BSP_rtems_irq_tbl    = BSP_rtems_irq_config->irqHdlTbl;
275  /*
276   * enable any non-empty IRQ entries at OPBINTC
277   */
278  for (i =  BSP_IPIC_IRQ_LOWEST_OFFSET;
279       i <= BSP_IPIC_IRQ_MAX_OFFSET;
280       i++) {
281    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
282      BSP_irq_enable_at_ipic(i);
283      BSP_rtems_irq_tbl[i].on((&BSP_rtems_irq_tbl[i]));
284    }
285    else {
286      BSP_rtems_irq_tbl[i].off(&(BSP_rtems_irq_tbl[i]));
287      BSP_irq_disable_at_ipic(i);
288    }
289  }
290  /*
291   * store any irq-like processor exceptions
292   */
293  for (i = BSP_PROCESSOR_IRQ_LOWEST_OFFSET;
294       i < BSP_PROCESSOR_IRQ_MAX_OFFSET;
295       i++) {
296    if (BSP_rtems_irq_tbl[i].hdl != config->defaultEntry.hdl) {
297      if (BSP_rtems_irq_tbl[i].on != NULL) {
298        BSP_rtems_irq_tbl[i].on
299          (&(BSP_rtems_irq_tbl[i]));
300      }
301    }
302    else {
303      if (BSP_rtems_irq_tbl[i].off != NULL) {
304        BSP_rtems_irq_tbl[i].off
305          (&(BSP_rtems_irq_tbl[i]));
306      }
307    }
308  }
309  rtems_interrupt_enable(level);
310  return 1;
311}
312/**********************************************
313 * list of exception vectors to tap for interrupt handlers
314 */
315static rtems_raw_except_connect_data BSP_vec_desc[] = {
316#if defined(ASM_DEC_VECTOR)
317  {ASM_DEC_VECTOR,
318   {ASM_DEC_VECTOR,
319    decrementer_exception_vector_prolog_code,
320    (size_t)decrementer_exception_vector_prolog_code_size
321   },
322   exception_nop_enable,
323   exception_nop_enable,
324   exception_always_enabled
325  },
326#endif
327#if defined(ASM_60X_SYSMGMT_VECTOR)
328  {ASM_60X_SYSMGMT_VECTOR,
329   {ASM_60X_SYSMGMT_VECTOR,
330    sysmgmt_exception_vector_prolog_code,
331    (size_t)sysmgmt_exception_vector_prolog_code_size
332   },
333   exception_nop_enable,
334   exception_nop_enable,
335   exception_always_enabled
336  },
337#endif
338  {ASM_EXT_VECTOR,
339   {ASM_EXT_VECTOR,
340    external_exception_vector_prolog_code,
341    (size_t)&external_exception_vector_prolog_code_size
342   },
343   exception_nop_enable,
344   exception_nop_enable,
345   exception_always_enabled
346  }
347#if 0 /* Critical interrupts not yet supported */
348  ,{ASM_BOOKE_CRIT_VECTOR,
349   {ASM_BOOKE_CRIT_VECTOR,
350    critical_exception_vector_prolog_code,
351    critical_exception_vector_prolog_code_size
352   }
353   BSP_irq_nop_func,
354   BSP_irq_nop_func,
355   BSP_irq_true_func
356  }
357#endif
358};
359
360/*
361 * dummy for an empty IRQ handler entry
362 */
363static rtems_irq_connect_data emptyIrq = {
364  0,                     /* Irq Name                 */
365  BSP_irq_nop_hdl,       /* handler function         */
366  NULL,                  /* handle passed to handler */
367  BSP_irq_nop_func,      /* on function              */
368  BSP_irq_nop_func,      /* off function             */
369  BSP_irq_true_func      /* isOn function            */
370};
371
372static rtems_irq_global_settings initialConfig = {
373  BSP_IRQ_NUMBER,    /* irqNb */
374  {  0,                          /* Irq Name                 */
375     BSP_irq_nop_hdl,       /* handler function         */
376     NULL,                  /* handle passed to handler */
377     BSP_irq_nop_func,      /* on function              */
378     BSP_irq_nop_func,      /* off function             */
379     BSP_irq_true_func      /* isOn function            */
380  }, /* emptyIrq */
381  rtemsIrqTbl, /* irqHdlTbl  */
382  0,           /* irqBase    */
383  NULL         /* irqPrioTbl */
384};
385
386void BSP_rtems_irq_mng_init(unsigned cpuId)
387{
388  int i;
389  /*
390   * connect all exception vectors needed
391   */
392  for (i = 0;
393       i < (sizeof(BSP_vec_desc) /
394            sizeof(BSP_vec_desc[0]));
395       i++) {
396    if (!ppc_set_exception (&BSP_vec_desc[i])) {
397      BSP_panic("Unable to initialize RTEMS raw exception\n");
398    }
399  }
400  /*
401   * setup interrupt handlers table
402   */
403  for (i = 0;
404       i < BSP_IRQ_NUMBER;
405       i++) {
406    rtemsIrqTbl[i]      = emptyIrq;
407    rtemsIrqTbl[i].name = i;
408  }
409
410  /*
411   * initialize interrupt management
412   */
413  if (!BSP_rtems_irq_mngt_set(&initialConfig)) {
414    BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
415  } 
416}
417
Note: See TracBrowser for help on using the repository browser.