source: rtems/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c @ 721fe34

4.11
Last change on this file since 721fe34 was 721fe34, checked in by Joel Sherrill <joel.sherrill@…>, on May 31, 2012 at 8:34:36 PM

Fix C files which had two semi-colons at EOL

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/* irq_init.c
2 *
3 *  This file contains the implementation of rtems initialization
4 *  related to interrupt handling.
5 *
6 *  CopyRight (C) 1999 valette@crf.canon.fr
7 *
8 * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
9 * to make it valid for MVME2300 Motorola boards.
10 *
11 * Till Straumann <strauman@slac.stanford.edu>, 12/20/2001:
12 * Use the new interface to openpic_init
13 *
14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
16 *  http://www.rtems.com/license/LICENSE.
17 */
18
19#include <libcpu/io.h>
20#include <libcpu/spr.h>
21#include <bsp/pci.h>
22#include <bsp/residual.h>
23#include <bsp/irq.h>
24#if BSP_PCI_IRQ_NUMBER > 0
25#include <bsp/openpic.h>
26#endif
27#include <bsp/irq_supp.h>
28#include <bsp.h>
29#include <bsp/motorola.h>
30#include <rtems/bspIo.h>
31
32typedef struct {
33  unsigned char bus;    /* few chance the PCI/ISA bridge is not on first bus but ... */
34  unsigned char device;
35  unsigned char function;
36} pci_isa_bridge_device;
37
38pci_isa_bridge_device* via_82c586 = 0;
39#ifndef qemu
40static pci_isa_bridge_device bridge;
41#endif
42
43/*
44 * default methods
45 */
46static void nop_hdl(rtems_irq_hdl_param ignored)
47{
48}
49
50static void nop_irq_enable(const struct __rtems_irq_connect_data__*ignored)
51{
52}
53
54static int irq_is_connected(const struct __rtems_irq_connect_data__*ignored)
55{
56  return 0;
57}
58
59
60static rtems_irq_connect_data           rtemsIrq[BSP_IRQ_NUMBER];
61static rtems_irq_global_settings        initial_config;
62static rtems_irq_connect_data           defaultIrq = {
63  0,                /* vector */
64  nop_hdl,          /* hdl */
65  NULL,             /* handle */
66  nop_irq_enable,   /* on */
67  nop_irq_enable,   /* off */
68  irq_is_connected  /* isOn */
69#ifdef BSP_SHARED_HANDLER_SUPPORT
70  , NULL /* next_handler */
71#endif
72};
73static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
74  /*
75   * actual priorities for interrupt :
76   *    0   means that only current interrupt is masked
77   *    255 means all other interrupts are masked
78   */
79  /*
80   * ISA interrupts.
81   * The second entry has a priority of 255 because
82   * it is the slave pic entry and should always remain
83   * unmasked.
84   */
85  0,0,
86  255,
87  0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
88#if BSP_PCI_IRQ_NUMBER > 0
89  /*
90   * PCI Interrupts
91   */
92  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
93#endif
94  /*
95   * Processor exceptions handled as interrupts
96   */
97  0
98};
99
100#if BSP_PCI_IRQ_NUMBER > 0
101#if defined(mvme2100)
102static unsigned char mvme2100_openpic_initpolarities[16] = {
103    0,  /* Not used - should be disabled */
104    0,  /* DEC21143 Controller */
105    0,  /* PMC/PC-MIP Type I Slot 0 */
106    0,  /* PC-MIP Type I Slot 1 */
107    0,  /* PC-MIP Type II Slot 0 */
108    0,  /* PC-MIP Type II Slot 1 */
109    0,  /* Not used - should be disabled */
110    0,  /* PCI Expansion Interrupt A/Universe II (LINT0) */
111    0,  /* PCI Expansion Interrupt B/Universe II (LINT1) */
112    0,  /* PCI Expansion Interrupt C/Universe II (LINT2) */
113    0,  /* PCI Expansion Interrupt D/Universe II (LINT3) */
114    0,  /* Not used - should be disabled */
115    0,  /* Not used - should be disabled */
116    1,  /* 16550 UART */
117    0,  /* Front panel Abort Switch */
118    0,  /* RTC IRQ */
119};
120
121static unsigned char mvme2100_openpic_initsenses[] = {
122    0,  /* Not used - should be disabled */
123    1,  /* DEC21143 Controller */
124    1,  /* PMC/PC-MIP Type I Slot 0 */
125    1,  /* PC-MIP Type I Slot 1 */
126    1,  /* PC-MIP Type II Slot 0 */
127    1,  /* PC-MIP Type II Slot 1 */
128    0,  /* Not used - should be disabled */
129    1,  /* PCI Expansion Interrupt A/Universe II (LINT0) */
130    1,  /* PCI Expansion Interrupt B/Universe II (LINT1) */
131    1,  /* PCI Expansion Interrupt C/Universe II (LINT2) */
132    1,  /* PCI Expansion Interrupt D/Universe II (LINT3) */
133    0,  /* Not used - should be disabled */
134    0,  /* Not used - should be disabled */
135    1,  /* 16550 UART */
136    0,  /* Front panel Abort Switch */
137    1,  /* RTC IRQ */
138};
139#else
140static unsigned char mcp750_openpic_initpolarities[16] = {
141    1,  /* 8259 cascade */
142    0,  /* all the rest of them */
143};
144
145static unsigned char mcp750_openpic_initsenses[] = {
146    1,  /* MCP750_INT_PCB(8259) */
147    0,  /* MCP750_INT_FALCON_ECC_ERR */
148    1,  /* MCP750_INT_PCI_ETHERNET */
149    1,  /* MCP750_INT_PCI_PMC */
150    1,  /* MCP750_INT_PCI_WATCHDOG_TIMER1 */
151    1,  /* MCP750_INT_PCI_PRST_SIGNAL */
152    1,  /* MCP750_INT_PCI_FALL_SIGNAL */
153    1,  /* MCP750_INT_PCI_DEG_SIGNAL */
154    1,  /* MCP750_INT_PCI_BUS1_INTA */
155    1,  /* MCP750_INT_PCI_BUS1_INTB */
156    1,  /* MCP750_INT_PCI_BUS1_INTC */
157    1,  /* MCP750_INT_PCI_BUS1_INTD */
158    1,  /* MCP750_INT_PCI_BUS2_INTA */
159    1,  /* MCP750_INT_PCI_BUS2_INTB */
160    1,  /* MCP750_INT_PCI_BUS2_INTC */
161    1,  /* MCP750_INT_PCI_BUS2_INTD */
162};
163#endif
164#endif
165
166#if BSP_ISA_IRQ_NUMBER > 0 && !defined(qemu)
167void VIA_isa_bridge_interrupts_setup(void)
168{
169  pci_isa_bridge_device pci_dev;
170  uint32_t temp;
171  unsigned char tmp;
172  unsigned char maxBus;
173  unsigned found = 0;
174
175  maxBus = pci_bus_count();
176  pci_dev.function      = 0; /* Assumes the bidge is the first function */
177
178  for (pci_dev.bus = 0; pci_dev.bus < maxBus; pci_dev.bus++) {
179#ifdef SCAN_PCI_PRINT
180    printk("isa_bridge_interrupts_setup: Scanning bus %d\n", pci_dev.bus);
181#endif
182    for (pci_dev.device = 0; pci_dev.device < PCI_MAX_DEVICES; pci_dev.device++) {
183#ifdef SCAN_PCI_PRINT
184      printk("isa_bridge_interrupts_setup: Scanning device %d\n", pci_dev.device);
185#endif
186      pci_read_config_dword(pci_dev.bus, pci_dev.device,  pci_dev.function,
187                               PCI_VENDOR_ID, &temp);
188#ifdef SCAN_PCI_PRINT
189      printk("Vendor/device = %x\n", temp);
190#endif
191      if ((temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_0 << 16)))
192         ) {
193        bridge = pci_dev;
194        via_82c586 = &bridge;
195#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
196        /*
197         * Should print : bus = 0, device = 11, function = 0 on a MCP750.
198         */
199        printk("Via PCI/ISA bridge found at bus = %d, device = %d, function = %d\n",
200               via_82c586->bus,
201               via_82c586->device,
202               via_82c586->function);
203#endif
204        found = 1;
205        goto loop_exit;
206
207      }
208    }
209  }
210loop_exit:
211  if (!found) BSP_panic("VIA_82C586 PCI/ISA bridge not found!n");
212
213  tmp = inb(0x810);
214  if  ( !(tmp & 0x2)) {
215#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
216    printk("This is a second generation MCP750 board\n");
217    printk("We must reprogram the PCI/ISA bridge...\n");
218#endif
219    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
220                         0x47,  &tmp);
221#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
222    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
223#endif
224    /*
225     * Enable 4D0/4D1 ISA interrupt level/edge config registers
226     */
227    tmp |= 0x20;
228    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
229                          0x47, tmp);
230    /*
231     * Now program the ISA interrupt edge/level
232     */
233    tmp = ELCRS_INT9_LVL | ELCRS_INT10_LVL | ELCRS_INT11_LVL;
234    outb(tmp, ISA8259_S_ELCR);
235    tmp = ELCRM_INT5_LVL;
236    outb(tmp, ISA8259_M_ELCR);
237    /*
238     * Set the Interrupt inputs to non-inverting level interrupt
239     */
240    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
241                            0x54, &tmp);
242#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
243    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
244#endif
245    tmp = 0;
246    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
247                          0x54, tmp);
248  }
249  else {
250#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
251    printk("This is a first generation MCP750 board\n");
252    printk("We just show the actual value used by PCI/ISA bridge\n");
253#endif
254    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
255                         0x47,  &tmp);
256#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
257    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
258#endif
259    /*
260     * Show the Interrupt inputs inverting/non-inverting level status
261     */
262    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
263                         0x54, &tmp);
264#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
265    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
266#endif
267  }
268}
269#endif
270
271  /*
272   * This code assumes the exceptions management setup has already
273   * been done. We just need to replace the exceptions that will
274   * be handled like interrupt. On mcp750/mpc750 and many PPC processors
275   * this means the decrementer exception and the external exception.
276   */
277void BSP_rtems_irq_mng_init(unsigned cpuId)
278{
279#if BSP_ISA_IRQ_NUMBER > 0 && !defined(mvme2100)
280  int known_cpi_isa_bridge = 0;
281#endif
282  int i;
283
284  /*
285   * First initialize the Interrupt management hardware
286   */
287#if defined(mvme2100)
288#ifdef TRACE_IRQ_INIT
289  printk("Going to initialize EPIC interrupt controller (openpic compliant)\n");
290#endif
291  /* EPIC sources don't start at the regular place; define appropriate offset
292   * prior to initializing the PIC.
293   */
294  openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses, 16, 16, BSP_bus_frequency);
295#else
296#if BSP_PCI_IRQ_NUMBER > 0
297#ifdef TRACE_IRQ_INIT
298  printk("Going to initialize raven interrupt controller (openpic compliant)\n");
299#endif
300  openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses, 0, 0, 0);
301#ifdef TRACE_IRQ_INIT
302  printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
303#endif
304#endif
305
306#if BSP_ISA_IRQ_NUMBER > 0
307  if ( currentBoard == MESQUITE ) {
308#ifndef qemu
309    VIA_isa_bridge_interrupts_setup();
310#endif
311    known_cpi_isa_bridge = 1;
312  }
313  if ( currentBoard == MVME_2300 ) {
314    /* nothing to do for W83C553 bridge */
315    known_cpi_isa_bridge = 1;
316  }
317  if ( currentBoard == MTX_WO_PP || currentBoard == MTX_W_PP ) {
318     /* W83C554, don't to anything at the moment.  gregm 11/6/2002 */
319     known_cpi_isa_bridge = 1;
320  }
321
322  if (!known_cpi_isa_bridge) {
323    printk("Please add code for PCI/ISA bridge init to libbsp/powerpc/shared/irq/irq_init.c\n");
324    printk("If your card works correctly please add a test and set known_cpi_isa_bridge to true\n");
325    printk("currentBoard = %i\n", currentBoard);
326  }
327#ifdef TRACE_IRQ_INIT
328  printk("Going to initialize the ISA PC legacy IRQ management hardware\n");
329#endif
330  BSP_i8259s_init();
331#endif
332
333#endif
334
335  /*
336   * Initialize RTEMS management interrupt table
337   */
338    /*
339     * re-init the rtemsIrq table
340     */
341    for (i = 0; i < BSP_IRQ_NUMBER; i++) {
342      rtemsIrq[i]      = defaultIrq;
343      rtemsIrq[i].name = i;
344    }
345    /*
346     * Init initial Interrupt management config
347     */
348    initial_config.irqNb        = BSP_IRQ_NUMBER;
349    initial_config.defaultEntry = defaultIrq;
350    initial_config.irqHdlTbl    = rtemsIrq;
351    initial_config.irqBase      = BSP_LOWEST_OFFSET;
352    initial_config.irqPrioTbl   = irqPrioTable;
353
354    if (!BSP_rtems_irq_mngt_set(&initial_config)) {
355      /*
356       * put something here that will show the failure...
357       */
358      BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
359    }
360
361#ifdef TRACE_IRQ_INIT
362    printk("RTEMS IRQ management is now operational\n");
363#endif
364}
Note: See TracBrowser for help on using the repository browser.