source: rtems/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c @ 6128a4a

4.104.114.84.95
Last change on this file since 6128a4a was 6128a4a, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/21/04 at 10:43:04

Remove stray white spaces.

  • Property mode set to 100644
File size: 9.7 KB
RevLine 
[acc25ee]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 *
[95273a6]8 * Enhanced by Jay Kulpinski <jskulpin@eng01.gdds.com>
9 * to make it valid for MVME2300 Motorola boards.
10 *
[69ed59f]11 * Till Straumann <strauman@slac.stanford.edu>, 12/20/2001:
12 * Use the new interface to openpic_init
13 *
[acc25ee]14 *  The license and distribution terms for this file may be
15 *  found in the file LICENSE in this distribution or at
[e831de8]16 *  http://www.rtems.com/license/LICENSE.
[acc25ee]17 *
18 *  $Id$
19 */
[cd35cf9]20
[acc25ee]21#include <libcpu/io.h>
22#include <libcpu/spr.h>
23#include <bsp/pci.h>
24#include <bsp/residual.h>
25#include <bsp/openpic.h>
26#include <bsp/irq.h>
27#include <bsp.h>
28#include <libcpu/raw_exception.h>
29#include <bsp/motorola.h>
[cd35cf9]30#include <rtems/bspIo.h>
[acc25ee]31
[338f1dc]32/*
33#define SHOW_ISA_PCI_BRIDGE_SETTINGS
34*/
35
[acc25ee]36typedef struct {
37  unsigned char bus;    /* few chance the PCI/ISA bridge is not on first bus but ... */
38  unsigned char device;
39  unsigned char function;
40} pci_isa_bridge_device;
41
42pci_isa_bridge_device* via_82c586 = 0;
43static pci_isa_bridge_device bridge;
44
[64f8ae4]45extern unsigned int external_exception_vector_prolog_code_size[];
[acc25ee]46extern void external_exception_vector_prolog_code();
[64f8ae4]47extern unsigned int decrementer_exception_vector_prolog_code_size[];
[acc25ee]48extern void decrementer_exception_vector_prolog_code();
49
50/*
51 * default on/off function
52 */
53static void nop_func(){}
54/*
55 * default isOn function
56 */
57static int not_connected() {return 0;}
58/*
59 * default possible isOn function
60 */
61static int connected() {return 1;}
62
63static rtems_irq_connect_data           rtemsIrq[BSP_IRQ_NUMBER];
64static rtems_irq_global_settings        initial_config;
65static rtems_irq_connect_data           defaultIrq = {
66  /* vectorIdex,         hdl            , on            , off           , isOn */
67  0,                     nop_func       , nop_func      , nop_func      , not_connected
68};
69static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
70  /*
71   * actual rpiorities for interrupt :
72   *    0   means that only current interrupt is masked
73   *    255 means all other interrupts are masked
74   */
75  /*
76   * ISA interrupts.
77   * The second entry has a priority of 255 because
78   * it is the slave pic entry and is should always remain
79   * unmasked.
80   */
81  0,0,
82  255,
83  0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
84  /*
85   * PCI Interrupts
86   */
[ec6422e]87  8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */
[acc25ee]88  /*
89   * Processor exceptions handled as interrupts
90   */
91  0
92};
93
[69ed59f]94static unsigned char mcp750_openpic_initpolarities[16] = {
95    1,  /* 8259 cascade */
96    0,  /* all the rest of them */
97};
98
[acc25ee]99static unsigned char mcp750_openpic_initsenses[] = {
100    1,  /* MCP750_INT_PCB(8259) */
101    0,  /* MCP750_INT_FALCON_ECC_ERR */
102    1,  /* MCP750_INT_PCI_ETHERNET */
103    1,  /* MCP750_INT_PCI_PMC */
104    1,  /* MCP750_INT_PCI_WATCHDOG_TIMER1 */
105    1,  /* MCP750_INT_PCI_PRST_SIGNAL */
106    1,  /* MCP750_INT_PCI_FALL_SIGNAL */
107    1,  /* MCP750_INT_PCI_DEG_SIGNAL */
108    1,  /* MCP750_INT_PCI_BUS1_INTA */
109    1,  /* MCP750_INT_PCI_BUS1_INTB */
110    1,  /* MCP750_INT_PCI_BUS1_INTC */
111    1,  /* MCP750_INT_PCI_BUS1_INTD */
112    1,  /* MCP750_INT_PCI_BUS2_INTA */
113    1,  /* MCP750_INT_PCI_BUS2_INTB */
114    1,  /* MCP750_INT_PCI_BUS2_INTC */
115    1,  /* MCP750_INT_PCI_BUS2_INTD */
116};
117
118void VIA_isa_bridge_interrupts_setup(void)
119{
120  pci_isa_bridge_device pci_dev;
121  unsigned int temp;
122  unsigned char tmp;
123  unsigned char maxBus;
124  unsigned found = 0;
125
126  maxBus = BusCountPCI();
127  pci_dev.function      = 0; /* Assumes the bidge is the first function */
[6128a4a]128
[acc25ee]129  for (pci_dev.bus = 0; pci_dev.bus < maxBus; pci_dev.bus++) {
[6128a4a]130#ifdef SCAN_PCI_PRINT
[acc25ee]131    printk("isa_bridge_interrupts_setup: Scanning bus %d\n", pci_dev.bus);
[6128a4a]132#endif
[acc25ee]133    for (pci_dev.device = 0; pci_dev.device < PCI_MAX_DEVICES; pci_dev.device++) {
[6128a4a]134#ifdef SCAN_PCI_PRINT
[acc25ee]135      printk("isa_bridge_interrupts_setup: Scanning device %d\n", pci_dev.device);
[6128a4a]136#endif
[acc25ee]137      pci_read_config_dword(pci_dev.bus, pci_dev.device,  pci_dev.function,
138                               PCI_VENDOR_ID, &temp);
[6128a4a]139#ifdef SCAN_PCI_PRINT
[acc25ee]140      printk("Vendor/device = %x\n", temp);
141#endif
[338f1dc]142      if ((temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_0 << 16)))
[acc25ee]143         ) {
144        bridge = pci_dev;
145        via_82c586 = &bridge;
[6128a4a]146#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
[acc25ee]147        /*
148         * Should print : bus = 0, device = 11, function = 0 on a MCP750.
149         */
150        printk("Via PCI/ISA bridge found at bus = %d, device = %d, function = %d\n",
151               via_82c586->bus,
152               via_82c586->device,
153               via_82c586->function);
[6128a4a]154#endif
[acc25ee]155        found = 1;
156        goto loop_exit;
[6128a4a]157
[acc25ee]158      }
159    }
160  }
161loop_exit:
162  if (!found) BSP_panic("VIA_82C586 PCI/ISA bridge not found!n");
[6128a4a]163
[acc25ee]164  tmp = inb(0x810);
165  if  ( !(tmp & 0x2)) {
[6128a4a]166#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
[acc25ee]167    printk("This is a second generation MCP750 board\n");
168    printk("We must reprogram the PCI/ISA bridge...\n");
[6128a4a]169#endif
[acc25ee]170    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
171                         0x47,  &tmp);
[6128a4a]172#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
[acc25ee]173    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
[6128a4a]174#endif
[acc25ee]175    /*
176     * Enable 4D0/4D1 ISA interrupt level/edge config registers
177     */
178    tmp |= 0x20;
179    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
180                          0x47, tmp);
181    /*
182     * Now program the ISA interrupt edge/level
183     */
184    tmp = ELCRS_INT9_LVL | ELCRS_INT10_LVL | ELCRS_INT11_LVL;
185    outb(tmp, ISA8259_S_ELCR);
186    tmp = ELCRM_INT5_LVL;
187    outb(tmp, ISA8259_M_ELCR);;
188    /*
189     * Set the Interrupt inputs to non-inverting level interrupt
190     */
191    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
192                            0x54, &tmp);
[6128a4a]193#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
[acc25ee]194    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
[6128a4a]195#endif
[acc25ee]196    tmp = 0;
197    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
198                          0x54, tmp);
199  }
200  else {
[6128a4a]201#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
[acc25ee]202    printk("This is a first generation MCP750 board\n");
203    printk("We just show the actual value used by PCI/ISA bridge\n");
[6128a4a]204#endif
[acc25ee]205    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
206                         0x47,  &tmp);
[6128a4a]207#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
[acc25ee]208    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
[6128a4a]209#endif
[acc25ee]210    /*
211     * Show the Interrupt inputs inverting/non-inverting level status
212     */
213    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
214                         0x54, &tmp);
[6128a4a]215#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS
[acc25ee]216    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
[6128a4a]217#endif
[acc25ee]218  }
219}
220
221  /*
222   * This code assumes the exceptions management setup has already
223   * been done. We just need to replace the exceptions that will
224   * be handled like interrupt. On mcp750/mpc750 and many PPC processors
225   * this means the decrementer exception and the external exception.
226   */
227void BSP_rtems_irq_mng_init(unsigned cpuId)
228{
229  rtems_raw_except_connect_data vectorDesc;
230  int known_cpi_isa_bridge = 0;
231  int i;
[6128a4a]232
[acc25ee]233  /*
234   * First initialize the Interrupt management hardware
235   */
[6128a4a]236#ifdef TRACE_IRQ_INIT
[acc25ee]237  printk("Going to initialize raven interrupt controller (openpic compliant)\n");
[6128a4a]238#endif
[4f3e4f33]239  openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses);
[6128a4a]240#ifdef TRACE_IRQ_INIT
[acc25ee]241  printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
242#endif
[95273a6]243  if ( currentBoard == MESQUITE ) {
[acc25ee]244    VIA_isa_bridge_interrupts_setup();
245    known_cpi_isa_bridge = 1;
246  }
[95273a6]247  if ( currentBoard == MVME_2300 ) {
248    /* nothing to do for W83C553 bridge */
249    known_cpi_isa_bridge = 1;
250  }
[5d740bb]251  if ( currentBoard == MTX_WO_PP || currentBoard == MTX_W_PP ) {
252     /* W83C554, don't to anything at the moment.  gregm 11/6/2002 */
253     known_cpi_isa_bridge = 1;
254  }
255
[acc25ee]256  if (!known_cpi_isa_bridge) {
[5d740bb]257    printk("Please add code for PCI/ISA bridge init to libbsp/powerpc/shared/irq/irq_init.c\n");
[acc25ee]258    printk("If your card works correctly please add a test and set known_cpi_isa_bridge to true\n");
[5d740bb]259    printk("currentBoard = %i\n", currentBoard);
[acc25ee]260  }
[6128a4a]261#ifdef TRACE_IRQ_INIT
[acc25ee]262  printk("Going to initialize the ISA PC legacy IRQ management hardware\n");
[6128a4a]263#endif
[acc25ee]264  BSP_i8259s_init();
265  /*
266   * Initialize Rtems management interrupt table
267   */
268    /*
269     * re-init the rtemsIrq table
270     */
271    for (i = 0; i < BSP_IRQ_NUMBER; i++) {
272      rtemsIrq[i]      = defaultIrq;
273      rtemsIrq[i].name = i;
274    }
275    /*
276     * Init initial Interrupt management config
277     */
278    initial_config.irqNb        = BSP_IRQ_NUMBER;
279    initial_config.defaultEntry = defaultIrq;
280    initial_config.irqHdlTbl    = rtemsIrq;
281    initial_config.irqBase      = BSP_ASM_IRQ_VECTOR_BASE;
282    initial_config.irqPrioTbl   = irqPrioTable;
283
284    if (!BSP_rtems_irq_mngt_set(&initial_config)) {
285      /*
286       * put something here that will show the failure...
287       */
288      BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
289    }
[6128a4a]290
[acc25ee]291  /*
292   * We must connect the raw irq handler for the two
293   * expected interrupt sources : decrementer and external interrupts.
294   */
295    vectorDesc.exceptIndex      =       ASM_DEC_VECTOR;
296    vectorDesc.hdl.vector       =       ASM_DEC_VECTOR;
297    vectorDesc.hdl.raw_hdl      =       decrementer_exception_vector_prolog_code;
[64f8ae4]298    vectorDesc.hdl.raw_hdl_size =       (unsigned) decrementer_exception_vector_prolog_code_size;
[acc25ee]299    vectorDesc.on               =       nop_func;
300    vectorDesc.off              =       nop_func;
301    vectorDesc.isOn             =       connected;
302    if (!mpc60x_set_exception (&vectorDesc)) {
303      BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
304    }
305    vectorDesc.exceptIndex      =       ASM_EXT_VECTOR;
306    vectorDesc.hdl.vector       =       ASM_EXT_VECTOR;
307    vectorDesc.hdl.raw_hdl      =       external_exception_vector_prolog_code;
[64f8ae4]308    vectorDesc.hdl.raw_hdl_size =       (unsigned) external_exception_vector_prolog_code_size;
[acc25ee]309    if (!mpc60x_set_exception (&vectorDesc)) {
310      BSP_panic("Unable to initialize RTEMS external raw exception\n");
311    }
[6128a4a]312#ifdef TRACE_IRQ_INIT
[acc25ee]313    printk("RTEMS IRQ management is now operationnal\n");
314#endif
315}
Note: See TracBrowser for help on using the repository browser.