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

4.104.114.84.95
Last change on this file since 8da27232 was 0505504, checked in by Ralf Corsepius <ralf.corsepius@…>, on 04/01/04 at 10:11:00

2004-04-01 Ralf Corsepius <ralf_corsepius@…>

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