source: rtems/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c @ 95273a6

4.104.114.84.95
Last change on this file since 95273a6 was 95273a6, checked in by Joel Sherrill <joel.sherrill@…>, on Jan 3, 2000 at 2:06:42 PM

Combination of coverhd.h cleanup and MVME23xx/MCP750 patch from Eric Valette
<valette@…> and Jay Kulpinski <jskulpin@…>.

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