source: rtems/c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c @ 78f96ab

4.104.114.84.95
Last change on this file since 78f96ab was 78f96ab, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jul 5, 2007 at 8:32:43 PM

fixed some problems with shared PPC exception handling code

  • Property mode set to 100644
File size: 3.1 KB
Line 
1/*  opbintctrl.c
2 *
3 *  This file contains definitions and declarations for the
4 *  Xilinx Off Processor Bus (OPB) Interrupt Controller
5 *
6 *  Author: Keith Robertson <kjrobert@alumni.uwaterloo.ca>
7 *  COPYRIGHT (c) 2005 Linn Products Ltd, Scotland.
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
14#include <bsp/opbintctrl.h>
15#include <rtems.h>
16#include <rtems/bspIo.h>
17#include <bsp/irq.h>
18#include <rtems/powerpc/powerpc.h>
19
20/*
21 * Acknowledge a mask of interrupts.
22 */
23RTEMS_INLINE_ROUTINE void set_iar(uint32_t mask)
24{
25  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IAR)) = mask;
26}
27
28/*
29 * Set IER state.  Used to (dis)enable a mask of vectors.
30 * If you only have to do one, use enable/disable_vector.
31 */
32RTEMS_INLINE_ROUTINE void set_ier(uint32_t mask)
33{
34  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IER)) = mask;
35}
36
37/*
38 * Retrieve contents of Interrupt Pending Register
39 */
40RTEMS_INLINE_ROUTINE uint32_t get_ipr()
41{
42  uint32_t c = *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_IPR));
43  return c;
44}
45
46void BSP_irq_enable_at_opbintc (rtems_irq_number irqnum)
47{
48  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_SIE)) 
49    = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
50}
51
52void BSP_irq_disable_at_opbintc (rtems_irq_number irqnum)
53{
54  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_CIE))
55    = 1 << (irqnum - BSP_OPBINTC_IRQ_LOWEST_OFFSET);
56}
57
58/*
59 *  IRQ Handler: this is called from the primary exception dispatcher
60 */
61void BSP_irq_handle_at_opbintc(void)
62{
63  uint32_t ipr, iprcopy, mask, i, c;
64  rtems_irq_connect_data *tbl_entry;
65  iprcopy = ipr = get_ipr();
66
67  c = 0;
68  mask = 0;
69
70  for (i = 0; 
71       (i < BSP_OPBINTC_PER_IRQ_NUMBER) 
72         && (ipr != 0); 
73       i++) {
74    c = (1 << i);
75
76    if ((ipr & c) != 0) {
77      /* interrupt is asserted */
78      mask |= c;
79      ipr &= ~c;
80
81      tbl_entry = &BSP_rtems_irq_tbl[i+BSP_OPBINTC_IRQ_LOWEST_OFFSET];
82      if (tbl_entry->hdl != NULL) {
83        (tbl_entry->hdl) (tbl_entry->handle);
84      } else {
85        printk("opbintctrl: Spurious interrupt; IPR 0x%08X, vector 0x%x\n\r",
86               iprcopy, i);
87      }
88    }
89  }
90
91  if (mask) {
92    /* ack all the interrupts we serviced */
93    set_iar(mask);
94  }
95}
96
97
98/*
99 * activate the interrupt controller
100 */
101rtems_status_code opb_intc_init(void)
102{
103  uint32_t i, mask = 0;
104
105  /* mask off all interrupts */
106  set_ier(0x0);
107
108  for (i = 0; i < OPB_INTC_IRQ_MAX; i++) {
109    mask |= (1 << i);
110  }
111  printk("opb_intc_init: mask = 0x%x\n", (unsigned) mask);
112
113  /* make sure interupt status register is clear before we enable the interrupt controller */
114  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0;
115
116  /* acknowledge all interrupt sources */
117  set_iar(mask);
118
119  /* Turn on normal hardware operation of interrupt controller */
120  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
121    (OPB_INTC_MER_HIE);
122
123  /* Enable master interrupt switch for the interrupt controller */
124  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
125    (OPB_INTC_MER_HIE | OPB_INTC_MER_ME);
126
127  return RTEMS_SUCCESSFUL;
128}
129
Note: See TracBrowser for help on using the repository browser.