source: rtems/bsps/powerpc/tqm8xx/irq/irq.c @ 762fa62

5
Last change on this file since 762fa62 was 8f8ccee, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 23, 2018 at 7:50:39 AM

bsps: Move interrupt controller support to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

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