OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [rtems/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [ppcn_60x/] [startup/] [genpvec.c] - Blame information for rev 173

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 30 unneback
/*
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
 
40
rtems_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
 */
50
unsigned8       ucMaster8259Mask;
51
unsigned8       ucSlave8259Mask;
52
 
53
/*
54
 * Structure to for one of possible multiple interrupt handlers for
55
 * a given interrupt.
56
 */
57
typedef 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
 
72
void 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
 */
176
void 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
 */
222
rtems_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
 
279
void 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
 
317
void 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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.