source: rtems/c/src/lib/libbsp/powerpc/score603e/irq/irq_init.c @ 40e7ae2

4.104.114.9
Last change on this file since 40e7ae2 was 40e7ae2, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 3, 2008 at 8:36:21 PM

2008-09-03 Joel Sherrill <joel.sherrill@…>

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