source: rtems/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c @ f85ad076

4.104.11
Last change on this file since f85ad076 was f85ad076, checked in by Till Straumann <strauman@…>, on Sep 11, 2009 at 4:57:07 PM

2009-09-11 Till Straumann <strauman@…>

  • irq/openpic_i8259_irq.c: Do not include <bsp/VMEConfig.h> if the bsp.h defines HAVE_NO_VME so that BSPs w/o VME do not have to create a dummy VMEConfig.h header.
  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 *
3 *  This file contains the i8259/openpic-specific implementation of
4 *  the function described in irq.h
5 *
6 *  Copyright (C) 1998, 1999 valette@crf.canon.fr
7 *
8 *  The license and distribution terms for this file may be
9 *  found in found in the file LICENSE in this distribution or at
10 *  http://www.rtems.com/license/LICENSE.
11 *
12 *  $Id$
13 */
14
15#include <stdlib.h>
16
17#include <bsp.h>
18#include <bsp/irq.h>
19#include <bsp/irq_supp.h>
20#ifndef BSP_HAS_NO_VME
21#include <bsp/VMEConfig.h>
22#endif
23#include <bsp/openpic.h>
24#include <libcpu/raw_exception.h>
25#include <libcpu/io.h>
26#include <bsp/vectors.h>
27#include <stdlib.h>
28
29#include <rtems/bspIo.h> /* for printk */
30#define RAVEN_INTR_ACK_REG 0xfeff0030
31
32#ifdef BSP_PCI_ISA_BRIDGE_IRQ
33/*
34 * pointer to the mask representing the additionnal irq vectors
35 * that must be disabled when a particular entry is activated.
36 * They will be dynamically computed from the priority table given
37 * in BSP_rtems_irq_mngt_set();
38 * CAUTION : this table is accessed directly by interrupt routine
39 *           prologue.
40 */
41rtems_i8259_masks       irq_mask_or_tbl[BSP_IRQ_NUMBER];
42#endif
43
44/*
45 * default handler connected on each irq after bsp initialization
46 */
47static rtems_irq_connect_data   default_rtems_entry;
48
49static rtems_irq_connect_data*          rtems_hdl_tbl;
50
51#ifdef BSP_PCI_ISA_BRIDGE_IRQ
52/*
53 * Check if IRQ is an ISA IRQ
54 */
55static inline int is_isa_irq(const rtems_irq_number irqLine)
56{
57  return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) &
58          ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET)
59         );
60}
61#endif
62
63/*
64 * Check if IRQ is an OPENPIC IRQ
65 */
66static inline int is_pci_irq(const rtems_irq_number irqLine)
67{
68  return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) &
69          ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET)
70         );
71}
72
73/*
74 * ------------------------ RTEMS Irq helper functions ----------------
75 */
76
77#ifdef BSP_PCI_ISA_BRIDGE_IRQ
78/*
79 * Caution : this function assumes the variable "*config"
80 * is already set and that the tables it contains are still valid
81 * and accessible.
82 */
83static void compute_i8259_masks_from_prio (rtems_irq_global_settings* config)
84{
85  int i;
86  int j;
87  /*
88   * Always mask at least current interrupt to prevent re-entrance
89   */
90  for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
91    * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
92    for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) {
93      /*
94       * Mask interrupts at i8259 level that have a lower priority
95       */
96      if (config->irqPrioTbl [i] > config->irqPrioTbl [j]) {
97        * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
98      }
99    }
100  }
101}
102#endif
103
104void
105BSP_enable_irq_at_pic(const rtems_irq_number name)
106{
107#ifdef BSP_PCI_ISA_BRIDGE_IRQ
108    if (is_isa_irq(name)) {
109      /*
110       * Enable interrupt at PIC level
111       */
112      BSP_irq_enable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
113    }
114#endif
115   
116    if (is_pci_irq(name)) {
117      /*
118       * Enable interrupt at OPENPIC level
119       */
120      openpic_enable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
121    }
122}
123
124int
125BSP_disable_irq_at_pic(const rtems_irq_number name)
126{
127#ifdef BSP_PCI_ISA_BRIDGE_IRQ
128    if (is_isa_irq(name)) {
129      /*
130       * disable interrupt at PIC level
131       */
132      return BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET);
133    }
134#endif
135    if (is_pci_irq(name)) {
136      /*
137       * disable interrupt at OPENPIC level
138       */
139      return openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET);
140    }
141        return -1;
142}
143
144/*
145 * RTEMS Global Interrupt Handler Management Routines
146 */
147int BSP_setup_the_pic(rtems_irq_global_settings* config)
148{
149    int i;
150   /*
151    * Store various code accelerators
152    */
153    default_rtems_entry = config->defaultEntry;
154    rtems_hdl_tbl               = config->irqHdlTbl;
155
156    /*
157     * set up internal tables used by rtems interrupt prologue
158     */
159
160#ifdef BSP_PCI_ISA_BRIDGE_IRQ
161    /*
162     * start with ISA IRQ
163     */
164    compute_i8259_masks_from_prio (config);
165
166    for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) {
167      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
168         BSP_irq_enable_at_i8259s (i);
169      }
170      else {
171         BSP_irq_disable_at_i8259s (i);
172      }
173    }
174
175        if ( BSP_ISA_IRQ_NUMBER > 0 ) {
176        /*
177                 * must enable slave pic anyway
178                 */
179                BSP_irq_enable_at_i8259s (2);
180        }
181#endif
182
183    /*
184     * continue with PCI IRQ
185     */
186    for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) {
187      /*
188       * Note that openpic_set_priority() sets the TASK priority of the PIC
189       */
190      openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET,
191                                  config->irqPrioTbl[i]);
192      if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) {
193         openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
194      }
195      else {
196         openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET);
197      }
198    }
199
200#ifdef BSP_PCI_ISA_BRIDGE_IRQ
201        if ( BSP_ISA_IRQ_NUMBER > 0 ) {
202        /*
203             * Must enable PCI/ISA bridge IRQ
204             */
205        openpic_enable_irq (0);
206        }
207#endif
208
209    return 1;
210}
211
212int _BSP_vme_bridge_irq = -1;
213
214unsigned BSP_spuriousIntr = 0;
215
216/*
217 * High level IRQ handler called from shared_raw_irq_code_entry
218 */
219int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum)
220{
221  register unsigned int irq;
222#ifdef BSP_PCI_ISA_BRIDGE_IRQ
223  register unsigned isaIntr;                  /* boolean */
224  register unsigned oldMask = 0;              /* old isa pic masks */
225  register unsigned newMask;                  /* new isa pic masks */
226#endif
227
228  if (excNum == ASM_DEC_VECTOR) {
229
230        bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl);
231
232    return 0;
233
234  }
235  irq = openpic_irq(0);
236  if (irq == OPENPIC_VEC_SPURIOUS) {
237    ++BSP_spuriousIntr;
238    return 0;
239  }
240
241  /* some BSPs might want to use a different numbering... */
242  irq = irq - OPENPIC_VEC_SOURCE + BSP_PCI_IRQ_LOWEST_OFFSET;
243
244#ifdef BSP_PCI_ISA_BRIDGE_IRQ
245  isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ);
246  if (isaIntr)  {
247    /*
248     * Acknowledge and read 8259 vector
249     */
250    irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG);
251    /*
252     * store current PIC mask
253     */
254    oldMask = i8259s_cache;
255    newMask = oldMask | irq_mask_or_tbl [irq];
256    i8259s_cache = newMask;
257    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
258    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
259    BSP_irq_ack_at_i8259s (irq);
260    openpic_eoi(0);
261  }
262#endif
263
264  /* dispatch handlers */
265  bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
266
267#ifdef BSP_PCI_ISA_BRIDGE_IRQ
268  if (isaIntr)  {
269    i8259s_cache = oldMask;
270    outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff);
271    outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8));
272  }
273  else
274#endif
275  {
276#ifdef BSP_PCI_VME_DRIVER_DOES_EOI
277        /* leave it to the VME bridge driver to do EOI, so
278     * it can re-enable the openpic while handling
279     * VME interrupts (-> VME priorities in software)
280         */
281        if (_BSP_vme_bridge_irq != irq)
282#endif
283                openpic_eoi(0);
284  }
285  return 0;
286}
Note: See TracBrowser for help on using the repository browser.