source: rtems/c/src/lib/libbsp/powerpc/virtex/opbintctrl/opbintctrl.c @ 862c2317

4.104.114.84.95
Last change on this file since 862c2317 was 862c2317, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on Jul 4, 2007 at 12:37:36 PM

added virtex BSP support and some missing files for common PPC
exception handling

  • Property mode set to 100644
File size: 3.4 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 msr_value;
104  uint32_t i, mask = 0;
105
106  /* mask off all interrupts */
107  set_ier(0x0);
108
109  for (i = 0; i < OPB_INTC_IRQ_MAX; i++) {
110    mask |= (1 << i);
111  }
112  printk("opb_intc_init: mask = 0x%x\n", (unsigned) mask);
113
114  /* make sure interupt status register is clear before we enable the interrupt controller */
115  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_ISR)) = 0;
116
117  /* acknowledge all interrupt sources */
118  set_iar(mask);
119
120  /* Turn on normal hardware operation of interrupt controller */
121  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
122    (OPB_INTC_MER_HIE);
123
124  /* Enable master interrupt switch for the interrupt controller */
125  *((volatile uint32_t *) (OPB_INTC_BASE + OPB_INTC_MER)) =
126    (OPB_INTC_MER_HIE | OPB_INTC_MER_ME);
127
128#if 0 /* EB: we do it somewhere else */
129  /*
130   * enable (non-critical) exceptions
131   */
132
133   _CPU_MSR_GET(msr_value);
134   msr_value |= PPC_MSR_EE;
135   _CPU_MSR_SET(msr_value);
136
137  /* install exit handler to close opb_intc when program atexit called */
138  /* atexit(opb_intc_exit); */
139#endif
140
141  return RTEMS_SUCCESSFUL;
142}
143
Note: See TracBrowser for help on using the repository browser.