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

4.104.114.84.95
Last change on this file since acc25ee was acc25ee, checked in by Joel Sherrill <joel.sherrill@…>, on 12/02/99 at 14:31:19

Merged of mcp750 and mvme2307 BSP by Eric Valette <valette@…>.
As part of this effort, the mpc750 libcpu code is now shared with the
ppc6xx.

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