source: rtems/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c @ 048fd36

4.115
Last change on this file since 048fd36 was 048fd36, checked in by Till Straumann <strauman@…>, on 07/16/11 at 01:15:06

2011-07-15 Till Straumann <strauman@…>

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