source: rtems/c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.c @ 4d6ad9e

4.9
Last change on this file since 4d6ad9e was 4d6ad9e, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 10/02/08 at 12:43:10

switch to decrementer clock driver
add U-Boot support
remove dead code
adjust console clock routing
fix CPIC interrupts

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/*===============================================================*\
2| Project: RTEMS TQM8xx BSP                                       |
3+-----------------------------------------------------------------+
4| This file has been adapted to MPC8xx by                         |
5|    Thomas Doerfler <Thomas.Doerfler@embedded-brains.de>         |
6|                    Copyright (c) 2008                           |
7|                    Embedded Brains GmbH                         |
8|                    Obere Lagerstr. 30                           |
9|                    D-82178 Puchheim                             |
10|                    Germany                                      |
11|                    rtems@embedded-brains.de                     |
12|                                                                 |
13| See the other copyright notice below for the original parts.    |
14+-----------------------------------------------------------------+
15| The license and distribution terms for this file may be         |
16| found in the file LICENSE in this distribution or at            |
17|                                                                 |
18| http://www.rtems.com/license/LICENSE.                           |
19|                                                                 |
20+-----------------------------------------------------------------+
21| this file contains the console driver                           |
22\*===============================================================*/
23/* derived from: generic MPC83xx BSP */
24
25#include <rtems.h>
26#include <mpc8xx.h>
27
28#include <libcpu/powerpc-utility.h>
29#include <libcpu/raw_exception.h>
30
31#include <bsp.h>
32#include <bsp/irq.h>
33#include <bsp/vectors.h>
34#include <bsp/ppc_exc_bspsupp.h>
35#include <bsp/irq-generic.h>
36/*
37 * functions to enable/disable a source at the SIU/CPM irq controller
38 */
39
40rtems_status_code bsp_irq_disable_at_SIU(rtems_vector_number irqnum)
41{
42  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
43  m8xx.simask &= ~(1 << (31 - vecnum));
44  return RTEMS_SUCCESSFUL;
45}
46
47rtems_status_code bsp_irq_enable_at_SIU(rtems_vector_number irqnum)
48{
49  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
50  m8xx.simask |= (1 << (31 - vecnum));
51  return RTEMS_SUCCESSFUL;
52}
53
54rtems_status_code bsp_irq_disable_at_CPM(rtems_vector_number irqnum)
55{
56  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
57  m8xx.cimr &= ~(1 << vecnum);
58  return RTEMS_SUCCESSFUL;
59}
60
61rtems_status_code bsp_irq_enable_at_CPM(rtems_vector_number irqnum)
62{
63  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
64  m8xx.cimr |= (1 << vecnum);
65  return RTEMS_SUCCESSFUL;
66}
67
68rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number irqnum)
69{
70  if (BSP_IS_CPM_IRQ(irqnum)) {
71    bsp_irq_enable_at_CPM(irqnum);
72    return RTEMS_SUCCESSFUL;
73  }
74  else if (BSP_IS_SIU_IRQ(irqnum)) {
75    bsp_irq_enable_at_SIU(irqnum);
76    return RTEMS_SUCCESSFUL;
77  }
78  return RTEMS_INVALID_ID;
79}
80
81rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum)
82{
83  if (BSP_IS_CPM_IRQ(irqnum)) {
84    bsp_irq_disable_at_CPM(irqnum);
85    return RTEMS_SUCCESSFUL;
86  }
87  else if (BSP_IS_SIU_IRQ(irqnum)) {
88    bsp_irq_disable_at_SIU(irqnum);
89    return RTEMS_SUCCESSFUL;
90  }
91  return RTEMS_INVALID_ID;
92}
93
94/*
95 *  IRQ Handler: this is called from the primary exception dispatcher
96 */
97static int BSP_irq_handle_at_cpm(void)
98{
99  int32_t  cpvecnum;
100  uint32_t msr;
101  rtems_interrupt_level level;
102
103  /* Get vector number: write IACK=1, then read vectir */
104  m8xx.civr = 1;
105  cpvecnum  = (m8xx.civr >> 11) + BSP_CPM_IRQ_LOWEST_OFFSET;
106 
107  /*
108   * Check the vector number, mask lower priority interrupts, enable
109   * exceptions and dispatch the handler.
110   */
111  if (BSP_IS_CPM_IRQ(cpvecnum)) {     
112    /* Enable all interrupts */
113    msr = ppc_external_exceptions_enable();
114    /* Dispatch interrupt handlers */
115    bsp_interrupt_handler_dispatch(cpvecnum);
116    /* Restore machine state */
117    ppc_external_exceptions_disable(msr);
118    /*
119     * clear "in-service" bit
120     */
121    m8xx.cisr = 1 << (cpvecnum - BSP_CPM_IRQ_LOWEST_OFFSET);
122  }
123  else {
124    /* not valid vector */
125    bsp_interrupt_handler_default(cpvecnum);
126  }
127  return 0;
128}
129
130static int BSP_irq_handle_at_siu( unsigned excNum)
131{
132  int32_t  sivecnum;
133  uint32_t msr;
134  rtems_interrupt_level level;
135  bool  is_cpm_irq;
136  uint32_t simask_save;
137  /*
138   * check, if interrupt is pending
139   * and repeat as long as valid interrupts are pending
140   */
141  while (0 != (m8xx.simask & m8xx.sipend)) {
142    /* Get vector number */
143    sivecnum     = (m8xx.sivec >> 26);
144    is_cpm_irq = (sivecnum == BSP_CPM_INTERRUPT);
145    /*
146     * Check the vector number, mask lower priority interrupts, enable
147     * exceptions and dispatch the handler.
148     */
149    if (BSP_IS_SIU_IRQ(sivecnum)) {     
150      simask_save = m8xx.simask;
151      /*
152       * if this is the CPM interrupt, mask lower prio interrupts at SIU
153       * else mask lower and same priority interrupts
154       */
155      m8xx.simask &= ~0 << (32
156                            - sivecnum
157                            - ((is_cpm_irq) ? 1 : 0));
158   
159      if (is_cpm_irq) {
160        BSP_irq_handle_at_cpm();
161      }
162      else {
163        /* Enable all interrupts */
164        msr = ppc_external_exceptions_enable();
165        /* Dispatch interrupt handlers */
166        bsp_interrupt_handler_dispatch(sivecnum + BSP_SIU_IRQ_LOWEST_OFFSET);
167        /* Restore machine state */
168        ppc_external_exceptions_disable(msr);
169        /*
170         * clear pending bit, if edge triggered interrupt input
171         */
172        m8xx.sipend = 1 << (31 - sivecnum);
173      }
174     
175   
176      /* Restore initial masks */
177      m8xx.simask = simask_save;
178    } else {
179      /* not valid vector */
180      bsp_interrupt_handler_default(sivecnum);
181    }
182  }
183  return 0;
184}
185
186/*
187 * Activate the CPIC
188 */
189rtems_status_code mpc8xx_cpic_initialize( void)
190{
191  /*
192   * mask off all interrupts
193   */
194  m8xx.cimr   = 0;
195  /*
196   * make sure CPIC request proper level at SIU interrupt controller
197   */
198  m8xx.cicr  = (0x00e41f80 |
199                ((BSP_CPM_INTERRUPT/2) << 13));
200
201  /*
202   * enable CPIC interrupts at SIU
203   */
204  bsp_irq_enable_at_SIU(BSP_CPM_INTERRUPT);
205
206  return RTEMS_SUCCESSFUL;
207}
208
209/*
210 * Activate the SIU interrupt controller
211 */
212rtems_status_code mpc8xx_siu_int_initialize( void)
213{
214  /*
215   * mask off all interrupts
216   */
217  m8xx.simask = 0;
218
219  return RTEMS_SUCCESSFUL;
220}
221
222int mpc8xx_exception_handler(BSP_Exception_frame *frame,
223                             unsigned exception_number)
224{
225  return BSP_irq_handle_at_siu(exception_number);
226}
227
228rtems_status_code bsp_interrupt_facility_initialize()
229{
230  /* Install exception handler */
231  if (ppc_exc_set_handler(ASM_EXT_VECTOR, mpc8xx_exception_handler)) {
232    return RTEMS_IO_ERROR;
233  }
234  /* Initialize the SIU interrupt controller */
235  if (mpc8xx_siu_int_initialize()) {
236    return RTEMS_IO_ERROR;   
237  }
238  /* Initialize the CPIC interrupt controller */
239  return mpc8xx_cpic_initialize();
240}
241
242void bsp_interrupt_handler_default( rtems_vector_number vector)
243{
244        printk( "Spurious interrupt: 0x%08x\n", vector);
245}
Note: See TracBrowser for help on using the repository browser.