source: rtems/c/src/lib/libbsp/powerpc/tqm8xx/irq/irq.c @ 2d2de4eb

4.104.115
Last change on this file since 2d2de4eb was 2d2de4eb, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 10/23/09 at 07:32:46

Update for exception support changes.

  • Property mode set to 100644
File size: 6.6 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 <bsp/vectors.h>
30
31#include <bsp.h>
32#include <bsp/irq.h>
33#include <bsp/irq-generic.h>
34/*
35 * functions to enable/disable a source at the SIU/CPM irq controller
36 */
37
38rtems_status_code bsp_irq_disable_at_SIU(rtems_vector_number irqnum)
39{
40  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
41  m8xx.simask &= ~(1 << (31 - vecnum));
42  return RTEMS_SUCCESSFUL;
43}
44
45rtems_status_code bsp_irq_enable_at_SIU(rtems_vector_number irqnum)
46{
47  rtems_vector_number vecnum = irqnum - BSP_SIU_IRQ_LOWEST_OFFSET;
48  m8xx.simask |= (1 << (31 - vecnum));
49  return RTEMS_SUCCESSFUL;
50}
51
52rtems_status_code bsp_irq_disable_at_CPM(rtems_vector_number irqnum)
53{
54  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
55  m8xx.cimr &= ~(1 << (31 - vecnum));
56  return RTEMS_SUCCESSFUL;
57}
58
59rtems_status_code bsp_irq_enable_at_CPM(rtems_vector_number irqnum)
60{
61  rtems_vector_number vecnum = irqnum - BSP_CPM_IRQ_LOWEST_OFFSET;
62  m8xx.cimr |= (1 << (31 - vecnum));
63  return RTEMS_SUCCESSFUL;
64}
65
66rtems_status_code bsp_interrupt_vector_enable( rtems_vector_number irqnum)
67{
68  if (BSP_IS_CPM_IRQ(irqnum)) {
69    bsp_irq_enable_at_CPM(irqnum);
70    return RTEMS_SUCCESSFUL;
71  }
72  else if (BSP_IS_SIU_IRQ(irqnum)) {
73    bsp_irq_enable_at_SIU(irqnum);
74    return RTEMS_SUCCESSFUL;
75  }
76  return RTEMS_INVALID_ID;
77}
78
79rtems_status_code bsp_interrupt_vector_disable( rtems_vector_number irqnum)
80{
81  if (BSP_IS_CPM_IRQ(irqnum)) {
82    bsp_irq_disable_at_CPM(irqnum);
83    return RTEMS_SUCCESSFUL;
84  }
85  else if (BSP_IS_SIU_IRQ(irqnum)) {
86    bsp_irq_disable_at_SIU(irqnum);
87    return RTEMS_SUCCESSFUL;
88  }
89  return RTEMS_INVALID_ID;
90}
91
92/*
93 *  IRQ Handler: this is called from the primary exception dispatcher
94 */
95static int BSP_irq_handle_at_cpm(void)
96{
97  int32_t  cpvecnum;
98  uint32_t msr;
99
100  /* Get vector number: write IACK=1, then read vectir */
101  m8xx.civr = 1;
102  cpvecnum  = (m8xx.civr >> 11) + BSP_CPM_IRQ_LOWEST_OFFSET;
103 
104  /*
105   * Check the vector number,
106   * enable exceptions and dispatch the handler.
107   * NOTE: lower-prio interrupts are automatically masked in CPIC
108   */
109  if (BSP_IS_CPM_IRQ(cpvecnum)) {     
110    /* Enable all interrupts */
111    msr = ppc_external_exceptions_enable();
112    /* Dispatch interrupt handlers */
113    bsp_interrupt_handler_dispatch(cpvecnum);
114    /* Restore machine state */
115    ppc_external_exceptions_disable(msr);
116  }
117  else {
118    /* not valid vector */
119    bsp_interrupt_handler_default(cpvecnum);
120  }
121  /*
122   * clear "in-service" bit
123   */
124  m8xx.cisr = 1 << (cpvecnum - BSP_CPM_IRQ_LOWEST_OFFSET);
125
126  return 0;
127}
128
129static int BSP_irq_handle_at_siu( unsigned excNum)
130{
131  int32_t  sivecnum;
132  uint32_t msr;
133  bool  is_cpm_irq;
134  uint32_t simask_save;
135  /*
136   * check, if interrupt is pending
137   * and repeat as long as valid interrupts are pending
138   */
139  while (0 != (m8xx.simask & m8xx.sipend)) {
140    /* Get vector number */
141    sivecnum     = (m8xx.sivec >> 26);
142    is_cpm_irq = (sivecnum == BSP_CPM_INTERRUPT);
143    /*
144     * Check the vector number, mask lower priority interrupts, enable
145     * exceptions and dispatch the handler.
146     */
147    if (BSP_IS_SIU_IRQ(sivecnum)) {     
148      simask_save = m8xx.simask;
149      /*
150       * if this is the CPM interrupt, mask lower prio interrupts at SIU
151       * else mask lower and same priority interrupts
152       */
153      m8xx.simask &= ~0 << (32
154                            - sivecnum
155                            - ((is_cpm_irq) ? 1 : 0));
156   
157      if (is_cpm_irq) {
158        BSP_irq_handle_at_cpm();
159      }
160      else {
161        /* Enable all interrupts */
162        msr = ppc_external_exceptions_enable();
163        /* Dispatch interrupt handlers */
164        bsp_interrupt_handler_dispatch(sivecnum + BSP_SIU_IRQ_LOWEST_OFFSET);
165        /* Restore machine state */
166        ppc_external_exceptions_disable(msr);
167        /*
168         * clear pending bit, if edge triggered interrupt input
169         */
170        m8xx.sipend = 1 << (31 - sivecnum);
171      }
172     
173   
174      /* Restore initial masks */
175      m8xx.simask = simask_save;
176    } else {
177      /* not valid vector */
178      bsp_interrupt_handler_default(sivecnum);
179    }
180  }
181  return 0;
182}
183
184/*
185 * Activate the CPIC
186 */
187rtems_status_code mpc8xx_cpic_initialize( void)
188{
189  /*
190   * mask off all interrupts
191   */
192  m8xx.cimr   = 0;
193  /*
194   * make sure CPIC request proper level at SIU interrupt controller
195   */
196  m8xx.cicr  = (0x00e41f00 |
197                ((BSP_CPM_INTERRUPT/2) << 13));
198
199  return RTEMS_SUCCESSFUL;
200}
201
202/*
203 * Activate the SIU interrupt controller
204 */
205rtems_status_code mpc8xx_siu_int_initialize( void)
206{
207  /*
208   * mask off all interrupts
209   */
210  m8xx.simask = 0;
211
212  return RTEMS_SUCCESSFUL;
213}
214
215int mpc8xx_exception_handler(BSP_Exception_frame *frame,
216                             unsigned exception_number)
217{
218  return BSP_irq_handle_at_siu(exception_number);
219}
220
221rtems_status_code bsp_interrupt_facility_initialize()
222{
223  /* Install exception handler */
224  if (ppc_exc_set_handler(ASM_EXT_VECTOR, mpc8xx_exception_handler)) {
225    return RTEMS_IO_ERROR;
226  }
227  /* Initialize the SIU interrupt controller */
228  if (mpc8xx_siu_int_initialize()) {
229    return RTEMS_IO_ERROR;   
230  }
231  /* Initialize the CPIC interrupt controller */
232  return mpc8xx_cpic_initialize();
233}
234
235void bsp_interrupt_handler_default( rtems_vector_number vector)
236{
237        printk( "Spurious interrupt: 0x%08x\n", vector);
238}
Note: See TracBrowser for help on using the repository browser.