source: rtems/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c @ 4f3e4f33

4.104.114.84.95
Last change on this file since 4f3e4f33 was 4f3e4f33, checked in by Joel Sherrill <joel.sherrill@…>, on 02/20/03 at 21:32:07

2003-02-20 Till Straumann <strauman@…>

PR 349/bsps

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