source: rtems/c/src/lib/libbsp/powerpc/motorola_powerpc/irq/irq_init.c @ 93180ea2

4.104.114.84.95
Last change on this file since 93180ea2 was 93180ea2, checked in by Joel Sherrill <joel.sherrill@…>, on Jul 9, 1999 at 5:16:10 PM

Patch from Eric Valette <valette@…>:

  • The same bug fix that was done on pc386 to prevent interrupt from occuring (never experienced it but who knows as I have 8259 emulation :()
  • Removed every compiler warning (except wrong ones and ones I can't do anything).
  • Removed any libc available code in code linked with mcp750 rtems executbale. Unfortunately using newlib functions for linking the bootloader does not work as the compilation options in bootloader (-mrelocatable -fixed-r13) are not compatible with newlib options. => I have put any libc external reference in one single new file (lib.c) that is linked only with the boot loader. Removing the file from ${OBJ} and using -lc crash the bootloader. Added big warning...
  • Property mode set to 100644
File size: 9.2 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
24typedef struct {
25  unsigned char bus;    /* few chance the PCI/ISA bridge is not on first bus but ... */
26  unsigned char device;
27  unsigned char function;
28} pci_isa_bridge_device;
29
30pci_isa_bridge_device* via_82c586 = 0;
31static pci_isa_bridge_device bridge;
32
33extern unsigned int external_exception_vector_prolog_code_size;
34extern void external_exception_vector_prolog_code();
35extern unsigned int decrementer_exception_vector_prolog_code_size;
36extern void decrementer_exception_vector_prolog_code();
37
38/*
39 * default on/off function
40 */
41static void nop_func(){}
42/*
43 * default isOn function
44 */
45static int not_connected() {return 0;}
46/*
47 * default possible isOn function
48 */
49static int connected() {return 1;}
50
51static rtems_irq_connect_data           rtemsIrq[BSP_IRQ_NUMBER];
52static rtems_irq_global_settings        initial_config;
53static rtems_irq_connect_data           defaultIrq = {
54  /* vectorIdex,         hdl            , on            , off           , isOn */
55  0,                     nop_func       , nop_func      , nop_func      , not_connected
56};
57static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={
58  /*
59   * actual rpiorities for interrupt :
60   *    0   means that only current interrupt is masked
61   *    255 means all other interrupts are masked
62   */
63  /*
64   * ISA interrupts.
65   * The second entry has a priority of 255 because
66   * it is the slave pic entry and is should always remain
67   * unmasked.
68   */
69  0,0,
70  255,
71  0, 0, 0, 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
72  /*
73   * PCI Interrupts
74   */
75  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* for raven prio 0 means unactive... */
76  /*
77   * Processor exceptions handled as interrupts
78   */
79  0
80};
81
82static unsigned char mcp750_openpic_initsenses[] = {
83    1,  /* MCP750_INT_PCB(8259) */
84    0,  /* MCP750_INT_FALCON_ECC_ERR */
85    1,  /* MCP750_INT_PCI_ETHERNET */
86    1,  /* MCP750_INT_PCI_PMC */
87    1,  /* MCP750_INT_PCI_WATCHDOG_TIMER1 */
88    1,  /* MCP750_INT_PCI_PRST_SIGNAL */
89    1,  /* MCP750_INT_PCI_FALL_SIGNAL */
90    1,  /* MCP750_INT_PCI_DEG_SIGNAL */
91    1,  /* MCP750_INT_PCI_BUS1_INTA */
92    1,  /* MCP750_INT_PCI_BUS1_INTB */
93    1,  /* MCP750_INT_PCI_BUS1_INTC */
94    1,  /* MCP750_INT_PCI_BUS1_INTD */
95    1,  /* MCP750_INT_PCI_BUS2_INTA */
96    1,  /* MCP750_INT_PCI_BUS2_INTB */
97    1,  /* MCP750_INT_PCI_BUS2_INTC */
98    1,  /* MCP750_INT_PCI_BUS2_INTD */
99};
100
101void isa_bridge_interrupts_setup(void)
102{
103  pci_isa_bridge_device pci_dev;
104  unsigned int temp;
105  unsigned char tmp;
106  unsigned char maxBus;
107  unsigned found = 0;
108
109  maxBus = BusCountPCI();
110  pci_dev.function      = 0; /* Assumes the bidge is the first function */
111     
112  for (pci_dev.bus = 0; pci_dev.bus < maxBus; pci_dev.bus++) {
113#ifdef SCAN_PCI_PRINT       
114    printk("isa_bridge_interrupts_setup: Scanning bus %d\n", pci_dev.bus);
115#endif       
116    for (pci_dev.device = 0; pci_dev.device < PCI_MAX_DEVICES; pci_dev.device++) {
117#ifdef SCAN_PCI_PRINT       
118      printk("isa_bridge_interrupts_setup: Scanning device %d\n", pci_dev.device);
119#endif       
120      pci_read_config_dword(pci_dev.bus, pci_dev.device,  pci_dev.function,
121                               PCI_VENDOR_ID, &temp);
122#ifdef SCAN_PCI_PRINT       
123      printk("Vendor/device = %x\n", temp);
124#endif
125      if ( (temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_1 << 16)))
126           ||
127           (temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_0 << 16)))
128         ) {
129        bridge = pci_dev;
130        via_82c586 = &bridge;
131        /*
132         * Should print : bus = 0, device = 11, function = 0 on a MCP750.
133         */
134        printk("Via PCI/ISA bridge found at bus = %d, device = %d, function = %d\n",
135               via_82c586->bus,
136               via_82c586->device,
137               via_82c586->function);
138        found = 1;
139        goto loop_exit;
140           
141      }
142    }
143  }
144loop_exit:
145  if (!found) BSP_panic("VIA_82C586 PCI/ISA bridge not found!n");
146     
147  tmp = inb(0x810);
148  if  ( !(tmp & 0x2)) {
149    printk("This is a second generation MCP750 board\n");
150    printk("We must reprogram the PCI/ISA bridge...\n");
151    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
152                         0x47,  &tmp);
153    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
154    /*
155     * Enable 4D0/4D1 ISA interrupt level/edge config registers
156     */
157    tmp |= 0x20;
158    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
159                          0x47, tmp);
160    /*
161     * Now program the ISA interrupt edge/level
162     */
163    tmp = ELCRS_INT9_LVL | ELCRS_INT10_LVL | ELCRS_INT11_LVL;
164    outb(tmp, ISA8259_S_ELCR);
165    tmp = ELCRM_INT5_LVL;
166    outb(tmp, ISA8259_M_ELCR);;
167    /*
168     * Set the Interrupt inputs to non-inverting level interrupt
169     */
170    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
171                            0x54, &tmp);
172    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
173    tmp = 0;
174    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
175                          0x54, tmp);
176  }
177  else {
178    printk("This is a first generation MCP750 board\n");
179    printk("We just show the actual value used by PCI/ISA bridge\n");
180    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
181                         0x47,  &tmp);
182    printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp);
183    /*
184     * Enable 4D0/4D1 ISA interrupt level/edge config registers
185     */
186    tmp |= 0x20;
187    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
188                          0x47, tmp);
189    tmp = inb(ISA8259_S_ELCR);
190    printk(" PCI ISA bridge slave edge/level control bit = %x\n", (unsigned) tmp);
191    tmp = inb(ISA8259_M_ELCR);;
192    printk(" PCI ISA bridge master edge/level control bit = %x\n", (unsigned) tmp);
193    /*
194     * Must disable the 4D0/4D1 ISA interrupt level/edge config registers
195     * or the card will die a soon as we we will enable external interrupts
196     */
197    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
198                         0x47,  &tmp);
199    tmp &= ~(0x20);
200    pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
201                          0x47, tmp);
202    /*
203     * Show the Interrupt inputs inverting/non-inverting level status
204     */
205    pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function,
206                         0x54, &tmp);
207    printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp);
208  }
209}
210
211  /*
212   * This code assumes the exceptions management setup has already
213   * been done. We just need to replace the exceptions that will
214   * be handled like interrupt. On mcp750/mpc750 this means the
215   * decrementer exception and the external exception.
216   */
217void BSP_rtems_irq_mng_init(unsigned cpuId)
218{
219  rtems_raw_except_connect_data vectorDesc;
220  int i;
221 
222  /*
223   * First initialize the Interrupt management hardware
224   */
225  OpenPIC_InitSenses = mcp750_openpic_initsenses;
226  OpenPIC_NumInitSenses = sizeof(mcp750_openpic_initsenses) / sizeof(char);
227  printk("Going to initialize raven interrupt controller (openpic compliant)\n");
228  openpic_init(1);
229  printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n");
230  isa_bridge_interrupts_setup();
231  printk("Going to initialize the ISA PC legacy IRQ management hardware\n");
232  BSP_i8259s_init();
233  /*
234   * Initialize Rtems management interrupt table
235   */
236    /*
237     * re-init the rtemsIrq table
238     */
239    for (i = 0; i < BSP_IRQ_NUMBER; i++) {
240      rtemsIrq[i]      = defaultIrq;
241      rtemsIrq[i].name = i;
242    }
243    /*
244     * Init initial Interrupt management config
245     */
246    initial_config.irqNb        = BSP_IRQ_NUMBER;
247    initial_config.defaultEntry = defaultIrq;
248    initial_config.irqHdlTbl    = rtemsIrq;
249    initial_config.irqBase      = BSP_ASM_IRQ_VECTOR_BASE;
250    initial_config.irqPrioTbl   = irqPrioTable;
251
252    if (!BSP_rtems_irq_mngt_set(&initial_config)) {
253      /*
254       * put something here that will show the failure...
255       */
256      BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n");
257    }
258 
259  /*
260   * We must connect the raw irq handler for the two
261   * expected interrupt sources : decrementer and external interrupts.
262   */
263    vectorDesc.exceptIndex      =       ASM_DEC_VECTOR;
264    vectorDesc.hdl.vector       =       ASM_DEC_VECTOR;
265    vectorDesc.hdl.raw_hdl      =       decrementer_exception_vector_prolog_code;
266    vectorDesc.hdl.raw_hdl_size =       (unsigned) &decrementer_exception_vector_prolog_code_size;
267    vectorDesc.on               =       nop_func;
268    vectorDesc.off              =       nop_func;
269    vectorDesc.isOn             =       connected;
270    if (!mpc60x_set_exception (&vectorDesc)) {
271      BSP_panic("Unable to initialize RTEMS decrementer raw exception\n");
272    }
273    vectorDesc.exceptIndex      =       ASM_EXT_VECTOR;
274    vectorDesc.hdl.vector       =       ASM_EXT_VECTOR;
275    vectorDesc.hdl.raw_hdl      =       external_exception_vector_prolog_code;
276    vectorDesc.hdl.raw_hdl_size =       (unsigned) &external_exception_vector_prolog_code_size;
277    if (!mpc60x_set_exception (&vectorDesc)) {
278      BSP_panic("Unable to initialize RTEMS external raw exception\n");
279    }
280    printk("RTEMS IRQ management is now operationnal\n");
281}
282
Note: See TracBrowser for help on using the repository browser.