source: rtems/c/src/lib/libbsp/powerpc/mbx8xx/irq/irq.c @ 0c875c6a

4.115
Last change on this file since 0c875c6a was 0c875c6a, checked in by Joel Sherrill <joel.sherrill@…>, on 01/28/11 at 20:29:53

2011-01-28 Joel Sherrill <joel.sherrilL@…>

  • beatnik/include/bsp.h, beatnik/irq/irq.h, beatnik/pci/gt_pci_init.c, ep1a/console/polled_io.c, ep1a/irq/openpic_xxx_irq.c, gen5200/include/irq.h, gen5200/irq/irq.c, gen5200/startup/bspstart.c, haleakala/irq/irq.c, mbx8xx/irq/irq.c, mbx8xx/irq/irq.h, motorola_powerpc/include/bsp.h, mpc8260ads/irq/irq.c, mpc8260ads/irq/irq.h, mvme3100/include/bsp.h, mvme3100/irq/irq.h, mvme3100/start/start.S, mvme5500/include/bsp.h, mvme5500/irq/irq.h, psim/include/bsp.h, psim/include/coverhd.h, psim/irq/irq.h, psim/shmsupp/addrconv.c, psim/shmsupp/getcfg.c, psim/startup/linkcmds, psim/tools/psim-gdb-top.in, psim/tools/psim-top.in, psim/tools/runtest-top.in, qemuppc/irq/irq.h, score603e/irq/irq.c, shared/bootloader/bootldr.h, shared/bootloader/em86.c, shared/bootloader/em86real.S, shared/bootloader/exception.S, shared/bootloader/head.S, shared/bootloader/lib.c, shared/bootloader/misc.c, shared/bootloader/mm.c, shared/bootloader/pci.c, shared/console/console.c, shared/console/consoleIo.h, shared/console/inch.c, shared/console/keyboard.h, shared/console/polled_io.c, shared/irq/i8259.c, shared/irq/irq.h, shared/irq/openpic_i8259_irq.c, shared/motorola/motorola.c, shared/motorola/motorola.h, shared/openpic/openpic.c, shared/openpic/openpic.h, shared/pci/pci.c, shared/residual/residual.c, shared/start/start.S, ss555/irq/irq.h: Fix typo where license said found in found in.
  • Property mode set to 100644
File size: 9.0 KB
Line 
1/*
2 *
3 *  This file contains the implementation of the function described in irq.h
4 *
5 *  Copyright (c) 2009 embedded brains GmbH.
6 *
7 *  Copyright (C) 1998, 1999 valette@crf.canon.fr
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.rtems.com/license/LICENSE.
12 *
13 *  $Id$
14 */
15
16#include <rtems/system.h>
17#include <bsp.h>
18#include <bsp/irq.h>
19#include <bsp/irq-generic.h>
20#include <bsp/vectors.h>
21#include <bsp/8xx_immap.h>
22#include <bsp/mbx.h>
23#include <bsp/commproc.h>
24
25volatile unsigned int ppc_cached_irq_mask;
26
27/*
28 * Check if symbolic IRQ name is an SIU IRQ
29 */
30static inline int is_siu_irq(const rtems_irq_number irqLine)
31{
32  return (((int) irqLine <= BSP_SIU_IRQ_MAX_OFFSET) &
33    ((int) irqLine >= BSP_SIU_IRQ_LOWEST_OFFSET)
34   );
35}
36
37/*
38 * Check if symbolic IRQ name is an CPM IRQ
39 */
40static inline int is_cpm_irq(const rtems_irq_number irqLine)
41{
42  return (((int) irqLine <= BSP_CPM_IRQ_MAX_OFFSET) &
43    ((int) irqLine >= BSP_CPM_IRQ_LOWEST_OFFSET)
44   );
45}
46
47/*
48 * masks used to mask off the interrupts. For exmaple, for ILVL2, the
49 * mask is used to mask off interrupts ILVL2, IRQ3, ILVL3, ... IRQ7
50 * and ILVL7.
51 *
52 */
53const static unsigned int SIU_IvectMask[BSP_SIU_IRQ_NUMBER] =
54{
55     /* IRQ0      ILVL0       IRQ1        ILVL1  */
56     0x00000000, 0x80000000, 0xC0000000, 0xE0000000,
57
58     /* IRQ2      ILVL2       IRQ3        ILVL3  */
59     0xF0000000, 0xF8000000, 0xFC000000, 0xFE000000,
60
61     /* IRQ4      ILVL4       IRQ5        ILVL5  */
62     0xFF000000, 0xFF800000, 0xFFC00000, 0xFFE00000,
63
64     /* IRQ6      ILVL6       IRQ7        ILVL7  */
65     0xFFF00000, 0xFFF80000, 0xFFFC0000, 0xFFFE0000
66};
67
68int BSP_irq_enable_at_cpm(const rtems_irq_number irqLine)
69{
70  int cpm_irq_index;
71
72  if (!is_cpm_irq(irqLine))
73    return 1;
74
75  cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
76  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr |= (1 << cpm_irq_index);
77
78  return 0;
79}
80
81int BSP_irq_disable_at_cpm(const rtems_irq_number irqLine)
82{
83  int cpm_irq_index;
84
85  if (!is_cpm_irq(irqLine))
86    return 1;
87
88  cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
89  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << cpm_irq_index);
90
91  return 0;
92}
93
94int BSP_irq_enabled_at_cpm(const rtems_irq_number irqLine)
95{
96  int cpm_irq_index;
97
98  if (!is_cpm_irq(irqLine))
99    return 0;
100
101  cpm_irq_index = ((int) (irqLine) - BSP_CPM_IRQ_LOWEST_OFFSET);
102  return (((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr & (1 << cpm_irq_index));
103}
104
105int BSP_irq_enable_at_siu(const rtems_irq_number irqLine)
106{
107  int siu_irq_index;
108
109  if (!is_siu_irq(irqLine))
110    return 1;
111
112  siu_irq_index = ((int) (irqLine) - BSP_SIU_IRQ_LOWEST_OFFSET);
113  ppc_cached_irq_mask |= (1 << (31-siu_irq_index));
114  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
115
116  return 0;
117}
118
119int BSP_irq_disable_at_siu(const rtems_irq_number irqLine)
120{
121  int siu_irq_index;
122
123  if (!is_siu_irq(irqLine))
124    return 1;
125
126  siu_irq_index = ((int) (irqLine) - BSP_SIU_IRQ_LOWEST_OFFSET);
127  ppc_cached_irq_mask &= ~(1 << (31-siu_irq_index));
128  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
129
130  return 0;
131}
132
133int BSP_irq_enabled_at_siu       (const rtems_irq_number irqLine)
134{
135  int siu_irq_index;
136
137  if (!is_siu_irq(irqLine))
138    return 0;
139
140  siu_irq_index = ((int) (irqLine) - BSP_SIU_IRQ_LOWEST_OFFSET);
141  return ppc_cached_irq_mask & (1 << (31-siu_irq_index));
142}
143
144#ifdef DISPATCH_HANDLER_STAT
145volatile unsigned int maxLoop = 0;
146#endif
147
148/*
149 * High level IRQ handler called from shared_raw_irq_code_entry
150 */
151int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
152{
153  register unsigned int irq;
154  register unsigned cpmIntr;                  /* boolean */
155  register unsigned oldMask;          /* old siu pic masks */
156  register unsigned msr;
157  register unsigned new_msr;
158#ifdef DISPATCH_HANDLER_STAT
159  unsigned loopCounter;
160#endif
161  /*
162   * Handle decrementer interrupt
163   */
164  if (excNum == ASM_DEC_VECTOR) {
165    _CPU_MSR_GET(msr);
166    new_msr = msr | MSR_EE;
167    _CPU_MSR_SET(new_msr);
168
169    bsp_interrupt_handler_dispatch(BSP_DECREMENTER);
170
171    _CPU_MSR_SET(msr);
172    return 0;
173  }
174  /*
175   * Handle external interrupt generated by SIU on PPC core
176   */
177#ifdef DISPATCH_HANDLER_STAT
178  loopCounter = 0;
179#endif
180  while (1) {
181    if ((ppc_cached_irq_mask & ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend) == 0) {
182#ifdef DISPATCH_HANDLER_STAT
183      if (loopCounter >  maxLoop) maxLoop = loopCounter;
184#endif
185      break;
186    }
187    irq = (((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sivec >> 26);
188    cpmIntr = (irq == BSP_CPM_INTERRUPT);
189    /*
190     * Disable the interrupt of the same and lower priority.
191     */
192    oldMask = ppc_cached_irq_mask;
193    ppc_cached_irq_mask = oldMask & SIU_IvectMask[irq];
194    ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
195    /*
196     * Acknowledge current interrupt. This has no effect on internal level interrupt.
197     */
198    ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = (1 << (31 - irq));
199
200    if (cpmIntr)  {
201      /*
202       * We will reenable the SIU CPM interrupt to allow nesting of CPM interrupt.
203       * We must before acknowledege the current irq at CPM level to avoid trigerring
204       * the interrupt again.
205       */
206      /*
207       * Acknowledge and get the vector.
208       */
209      ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr = 1;
210      irq = (((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_civr >> 11);
211      /*
212       * transform IRQ to normalized irq table index.
213       */
214      irq += BSP_CPM_IRQ_LOWEST_OFFSET;
215      /*
216       * Unmask CPM interrupt at SIU level
217       */
218      ppc_cached_irq_mask |= (1 << (31 - BSP_CPM_INTERRUPT));
219      ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
220    }
221    /*
222     * make sure, that the masking operations in
223     * ICTL and MSR are executed in order
224     */
225    asm volatile("sync":::"memory");
226
227    _CPU_MSR_GET(msr);
228    new_msr = msr | MSR_EE;
229    _CPU_MSR_SET(new_msr);
230
231    bsp_interrupt_handler_dispatch(irq);
232
233    _CPU_MSR_SET(msr);
234
235    /*
236     * make sure, that the masking operations in
237     * ICTL and MSR are executed in order
238     */
239    asm volatile("sync":::"memory");
240
241    if (cpmIntr)  {
242      irq -= BSP_CPM_IRQ_LOWEST_OFFSET;
243      ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cisr = (1 << irq);
244    }
245    ppc_cached_irq_mask = oldMask;
246    ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = ppc_cached_irq_mask;
247#ifdef DISPATCH_HANDLER_STAT
248    ++ loopCounter;
249#endif
250  }
251  return 0;
252}
253
254void BSP_SIU_irq_init(void)
255{
256  /*
257   * In theory we should initialize two registers at least :
258   * SIMASK, SIEL. SIMASK is reset at 0 value meaning no interrupt. But
259   * we should take care that a monitor may have restoreed to another value.
260   * If someone find a reasonnable value for SIEL, AND THE NEED TO CHANGE IT
261   * please feel free to add it here.
262   */
263  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_simask = 0;
264  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_sipend = 0xffff0000;
265  ppc_cached_irq_mask = 0;
266  ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel = ((volatile immap_t *)IMAP_ADDR)->im_siu_conf.sc_siel;
267}
268
269/*
270 * Initialize CPM interrupt management
271 */
272void
273BSP_CPM_irq_init(void)
274{
275  /*
276   * Initialize the CPM interrupt controller.
277   */
278  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr =
279#ifdef mpc860
280    (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
281#else
282    (CICR_SCB_SCC2 | CICR_SCA_SCC1) |
283#endif
284    ((BSP_CPM_INTERRUPT/2) << 13) | CICR_HP_MASK;
285  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr = 0;
286
287  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
288}
289
290rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number irqnum)
291{
292  if (is_cpm_irq(irqnum)) {
293    /*
294     * Enable interrupt at PIC level
295     */
296    BSP_irq_enable_at_cpm (irqnum);
297  }
298
299  if (is_siu_irq(irqnum)) {
300    /*
301     * Enable interrupt at SIU level
302     */
303    BSP_irq_enable_at_siu (irqnum);
304  }
305
306  return RTEMS_SUCCESSFUL;
307}
308
309rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum)
310{
311  if (is_cpm_irq(irqnum)) {
312    /*
313     * disable interrupt at PIC level
314     */
315    BSP_irq_disable_at_cpm (irqnum);
316  }
317  if (is_siu_irq(irqnum)) {
318    /*
319     * disable interrupt at OPENPIC level
320     */
321    BSP_irq_disable_at_siu (irqnum);
322  }
323
324  return RTEMS_SUCCESSFUL;
325}
326
327rtems_status_code bsp_interrupt_facility_initialize()
328{
329  /* Install exception handler */
330  if (ppc_exc_set_handler( ASM_EXT_VECTOR, C_dispatch_irq_handler)) {
331    return RTEMS_IO_ERROR;
332  }
333  if (ppc_exc_set_handler( ASM_DEC_VECTOR, C_dispatch_irq_handler)) {
334    return RTEMS_IO_ERROR;
335  }
336
337  /* Initialize the interrupt controller */
338  BSP_SIU_irq_init();
339  BSP_CPM_irq_init();
340
341  /*
342   * Must enable CPM interrupt on SIU. CPM on SIU Interrupt level has already been
343   * set up in BSP_CPM_irq_init.
344   */
345  ((volatile immap_t *)IMAP_ADDR)->im_cpic.cpic_cicr |= CICR_IEN;
346  BSP_irq_enable_at_siu (BSP_CPM_INTERRUPT);
347
348  return RTEMS_SUCCESSFUL;
349}
350
351void bsp_interrupt_handler_default( rtems_vector_number vector)
352{
353  printk( "Spurious interrupt: 0x%08x\n", vector);
354}
Note: See TracBrowser for help on using the repository browser.