source: rtems/c/src/lib/libbsp/powerpc/ppcn_60x/startup/genpvec.c @ eba2e4f

4.104.114.84.95
Last change on this file since eba2e4f was 0c04c377, checked in by Joel Sherrill <joel.sherrill@…>, on 02/18/99 at 16:48:14

./clock/Makefile.in,v
./clock/clock.c,v
./console/Makefile.in,v
./console/config.c,v
./console/console.c,v
./console/console.h,v
./console/debugio.c,v
./console/i8042.c,v
./console/i8042_p.h,v
./console/i8042vga.c,v
./console/i8042vga.h,v
./console/ns16550.c,v
./console/ns16550.h,v
./console/ns16550_p.h,v
./console/ns16550cfg.c,v
./console/ns16550cfg.h,v
./console/vga.c,v
./console/vga_p.h,v
./console/z85c30.c,v
./console/z85c30.h,v
./console/z85c30_p.h,v
./console/z85c30cfg.c,v
./console/z85c30cfg.h,v
./include/Makefile.in,v
./include/bsp.h,v
./include/chain.h,v
./include/coverhd.h,v
./include/extisrdrv.h,v
./include/nvram.h,v
./include/pci.h,v
./include/tod.h,v
./network/Makefile.in,v
./network/amd79c970.c,v
./network/amd79c970.h,v
./nvram/Makefile.in,v
./nvram/ds1385.h,v
./nvram/mk48t18.h,v
./nvram/nvram.c,v
./nvram/prepnvr.h,v
./nvram/stk11c68.h,v
./pci/Makefile.in,v
./pci/pci.c,v
./start/Makefile.in,v
./start/start.s,v
./startup/Makefile.in,v
./startup/bspclean.c,v
./startup/bspstart.c,v
./startup/bsptrap.s,v
./startup/device-tree,v
./startup/genpvec.c,v
./startup/linkcmds,v
./startup/rtems-ctor.cc,v
./startup/sbrk.c,v
./startup/setvec.c,v
./startup/spurious.c,v
./startup/swap.c,v
./timer/Makefile.in,v
./timer/timer.c,v
./tod/Makefile.in,v
./tod/cmos.h,v
./tod/tod.c,v
./universe/Makefile.in,v
./universe/universe.c,v
./vectors/Makefile.in,v
./vectors/README,v
./vectors/align_h.s,v
./vectors/vectors.s,v
./wrapup/Makefile.in,v
./Makefile.in,v
./README,v
./STATUS,v
./bsp_specs,v

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 *  COPYRIGHT (c) 1998 by Radstone Technology
3 *
4 *
5 * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
6 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
7 * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
8 * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
9 *
10 * You are hereby granted permission to use, copy, modify, and distribute
11 * this file, provided that this notice, plus the above copyright notice
12 * and disclaimer, appears in all copies. Radstone Technology will provide
13 * no support for this code.
14 *
15 */
16/*  genpvec.c
17 *
18 *  These routines handle the external exception.  Multiple ISRs occur off
19 *  of this one interrupt.
20 *
21 *  COPYRIGHT (c) 1989-1997.
22 *  On-Line Applications Research Corporation (OAR).
23 *  Copyright assigned to U.S. Government, 1994.
24 *
25 *  The license and distribution terms for this file may in
26 *  the file LICENSE in this distribution or at
27 *  http://www.OARcorp.com/rtems/license.html.
28 *
29 *  $Id:
30 */
31
32#include <bsp.h>
33#include "chain.h"
34#include <assert.h>
35
36/*
37 * Proto types for this file                                         
38 */
39
40rtems_isr external_exception_ISR (
41  rtems_vector_number   vector                                  /* IN  */
42);
43
44#define   NUM_LIRQ_HANDLERS   20
45#define   NUM_LIRQ            ( MAX_BOARD_IRQS - PPC_IRQ_LAST )
46
47/*
48 * Current 8259 masks
49 */
50unsigned8       ucMaster8259Mask;
51unsigned8       ucSlave8259Mask;
52
53/*
54 * Structure to for one of possible multiple interrupt handlers for
55 * a given interrupt.
56 */
57typedef struct
58{
59  Chain_Node          Node;
60  rtems_isr_entry     handler;                  /* isr routine        */
61  rtems_vector_number vector;                   /* vector number      */
62} EE_ISR_Type;
63
64
65/* Note:  The following will not work if we add a method to remove
66 *        handlers at a later time.
67 */
68  EE_ISR_Type       ISR_Nodes [NUM_LIRQ_HANDLERS];
69  rtems_unsigned16  Nodes_Used;
70  Chain_Control     ISR_Array  [NUM_LIRQ];
71
72void initialize_external_exception_vector()
73{
74        rtems_isr_entry previous_isr;
75        rtems_status_code status;
76        int i;
77
78        Nodes_Used = 0;
79
80        for (i=0; i <NUM_LIRQ; i++)
81        {
82                Chain_Initialize_empty( &ISR_Array[i] );
83        }
84
85        /*
86         * Initialise the 8259s
87         */
88        outport_byte(ISA8259_M_CTRL, 0x11); /* ICW1 */
89        outport_byte(ISA8259_S_CTRL, 0x11); /* ICW1 */
90        outport_byte(ISA8259_M_MASK, 0x00); /* ICW2 vectors 0-7 */
91        outport_byte(ISA8259_S_MASK, 0x08); /* ICW2 vectors 8-15 */
92        outport_byte(ISA8259_M_MASK, 0x04); /* ICW3 cascade on IRQ2 */
93        outport_byte(ISA8259_S_MASK, 0x02); /* ICW3 cascade on IRQ2 */
94        outport_byte(ISA8259_M_MASK, 0x01); /* ICW4 x86 normal EOI */
95        outport_byte(ISA8259_S_MASK, 0x01); /* ICW4 x86 normal EOI */
96
97        /*
98         * Enable IRQ2 cascade and disable all other interrupts
99         */
100        ucMaster8259Mask=0xfb;
101        ucSlave8259Mask=0xff;
102
103        outport_byte(ISA8259_M_MASK, ucMaster8259Mask);
104        outport_byte(ISA8259_S_MASK, ucSlave8259Mask);
105
106        /*
107         * Set up edge/level
108         */
109        switch(ucSystemType)
110        {
111                case SYS_TYPE_PPC1:
112                {
113                        if(ucBoardRevMaj<5)
114                        {
115                                outport_byte(ISA8259_S_ELCR,
116                                             ELCRS_INT15_LVL);
117                        }
118                        else
119                        {
120                                outport_byte(ISA8259_S_ELCR,
121                                             ELCRS_INT9_LVL |
122                                             ELCRS_INT11_LVL |
123                                             ELCRS_INT14_LVL |
124                                             ELCRS_INT15_LVL);
125                        }
126                        outport_byte(ISA8259_M_ELCR,
127                                     ELCRM_INT5_LVL |
128                                     ELCRM_INT7_LVL);
129                        break;
130                }
131
132                case SYS_TYPE_PPC1a:
133                {
134                        outport_byte(ISA8259_S_ELCR,
135                                     ELCRS_INT9_LVL |
136                                     ELCRS_INT11_LVL |
137                                     ELCRS_INT14_LVL |
138                                     ELCRS_INT15_LVL);
139                        outport_byte(ISA8259_M_ELCR,
140                                     ELCRM_INT5_LVL);
141                        break;
142                }
143               
144                case SYS_TYPE_PPC2:
145                case SYS_TYPE_PPC2a:
146                case SYS_TYPE_PPC4:
147                default:
148                {
149                        outport_byte(ISA8259_S_ELCR,
150                                     ELCRS_INT9_LVL |
151                                     ELCRS_INT10_LVL |
152                                     ELCRS_INT11_LVL |
153                                     ELCRS_INT14_LVL |
154                                     ELCRS_INT15_LVL);
155                        outport_byte(ISA8259_M_ELCR,
156                                     ELCRM_INT5_LVL |
157                                     ELCRM_INT7_LVL);
158                        break;
159                }
160        }
161
162        /* 
163         * Install external_exception_ISR () as the handler for
164         *  the General Purpose Interrupt.
165         */
166
167        status = rtems_interrupt_catch( external_exception_ISR,
168                                        PPC_IRQ_EXTERNAL,
169                                        (rtems_isr_entry *) &previous_isr );
170}
171
172/*
173 *  This routine installs one of multiple ISRs for the general purpose
174 *  inerrupt.
175 */
176void set_EE_vector(
177  rtems_isr_entry     handler,      /* isr routine        */
178  rtems_vector_number vector        /* vector number      */
179)
180{
181        rtems_unsigned16 vec_idx  = vector - PPCN_60X_8259_IRQ_BASE;
182        rtems_unsigned32 index;
183
184        assert  (Nodes_Used < NUM_LIRQ_HANDLERS);
185
186        /*
187         *  If we have already installed this handler for this vector, then
188         *  just reset it.
189         */
190
191        for ( index=0 ; index < Nodes_Used ; index++ )
192        {
193                if(ISR_Nodes[index].vector == vector &&
194                   ISR_Nodes[index].handler == handler)
195                {
196                        return;
197                }
198        }
199
200        /*
201         *  Doing things in this order makes them more atomic
202         */
203
204        Nodes_Used++;
205
206        index = Nodes_Used - 1;
207
208        ISR_Nodes[index].handler = handler;
209        ISR_Nodes[index].vector  = vector;
210
211        Chain_Append( &ISR_Array[vec_idx], &ISR_Nodes[index].Node );
212
213        /*
214         * Enable the interrupt
215         */
216        En_Ext_Interrupt(vector);
217}
218
219/*
220 * This interrupt service routine is called for an External Exception.
221 */
222rtems_isr external_exception_ISR (
223  rtems_vector_number   vector             /* IN  */
224)
225{
226        unsigned16      index;
227        unsigned8       ucISr;
228        EE_ISR_Type     *node;
229
230        index = *((volatile unsigned8 *)IRQ_VECTOR_BASE);
231
232        /*
233         * check for spurious interrupt
234         */
235        if(index==7)
236        {
237                /*
238                 * OCW3 select IS register
239                 */
240                outport_byte(ISA8259_M_CTRL, 0x0b);
241                /*
242                 * Read IS register
243                 */
244                inport_byte(ISA8259_M_CTRL, ucISr);
245                if(!(ucISr & 0x80))
246                {
247                        /*
248                         * Spurious interrupt
249                         */
250                        return;
251                }
252        }
253
254        node=(EE_ISR_Type *)ISR_Array[index].first;
255        while(!_Chain_Is_tail(&ISR_Array[index], (Chain_Node *)node))
256        {
257                (*node->handler)( node->vector );
258                node = (EE_ISR_Type *)node->Node.next;
259        }
260
261        /*
262         * Dismiss the interrupt
263         */
264        if(index&8)
265        {
266                /*
267                 * Dismiss the interrupt in Slave first as it
268                 * is cascaded
269                 */
270                outport_byte(ISA8259_S_CTRL, NONSPECIFIC_EOI);
271        }
272
273        /*
274         * Dismiss the interrupt in Master
275         */
276        outport_byte(ISA8259_M_CTRL, NONSPECIFIC_EOI);
277}
278
279void Dis_Ext_Interrupt(int level)
280{
281        ISR_Level Irql;
282
283        level-=PPCN_60X_8259_IRQ_BASE;
284
285        if(level==2)
286        {
287                /*
288                 * Level 2 is for cascade and must not be fiddled with
289                 */
290                return;
291        }
292
293        /*
294         * Ensure that accesses to the mask are indivisible
295         */
296        _ISR_Disable(Irql);
297
298        if(level<8)
299        {
300                /*
301                 * Interrupt is handled by Master
302                 */
303                ucMaster8259Mask|=1<<level;
304                outport_byte(ISA8259_M_MASK, ucMaster8259Mask);
305        }
306        else
307        {
308                /*
309                 * Interrupt is handled by Slave
310                 */
311                ucSlave8259Mask|=1<<(level-8);
312                outport_byte(ISA8259_S_MASK, ucSlave8259Mask);
313        }
314        _ISR_Enable(Irql);
315}
316
317void En_Ext_Interrupt(int level)
318{
319        ISR_Level Irql;
320
321        level-=PPCN_60X_8259_IRQ_BASE;
322
323        if(level==2)
324        {
325                /*
326                 * Level 2 is for cascade and must not be fiddled with
327                 */
328                return;
329        }
330
331        /*
332         * Ensure that accesses to the mask are indivisible
333         */
334        _ISR_Disable(Irql);
335
336        if(level<8)
337        {
338                /*
339                 * Interrupt is handled by Master
340                 */
341                ucMaster8259Mask&=~(1<<level);
342                outport_byte(ISA8259_M_MASK, ucMaster8259Mask);
343        }
344        else
345        {
346                /*
347                 * Interrupt is handled by Slave
348                 */
349                ucSlave8259Mask&=~(1<<(level-8));
350                outport_byte(ISA8259_S_MASK, ucSlave8259Mask);
351        }
352
353        _ISR_Enable(Irql);
354}
355
Note: See TracBrowser for help on using the repository browser.