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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [mips/] [upd985xx/] [v2_0/] [include/] [var_intr.h] - Blame information for rev 565

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#ifndef CYGONCE_HAL_VAR_INTR_H
2
#define CYGONCE_HAL_VAR_INTR_H
3
//==========================================================================
4
//
5
//      var_intr.h
6
//
7
//      VR4300 Interrupt and clock support
8
//
9
//==========================================================================
10
//####ECOSGPLCOPYRIGHTBEGIN####
11
// -------------------------------------------
12
// This file is part of eCos, the Embedded Configurable Operating System.
13
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14
//
15
// eCos is free software; you can redistribute it and/or modify it under
16
// the terms of the GNU General Public License as published by the Free
17
// Software Foundation; either version 2 or (at your option) any later version.
18
//
19
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22
// for more details.
23
//
24
// You should have received a copy of the GNU General Public License along
25
// with eCos; if not, write to the Free Software Foundation, Inc.,
26
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27
//
28
// As a special exception, if other files instantiate templates or use macros
29
// or inline functions from this file, or you compile this file and link it
30
// with other works to produce a work based on this file, this file does not
31
// by itself cause the resulting work to be covered by the GNU General Public
32
// License. However the source code for this file must still be made available
33
// in accordance with section (3) of the GNU General Public License.
34
//
35
// This exception does not invalidate any other reasons why a work based on
36
// this file might be covered by the GNU General Public License.
37
//
38
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39
// at http://sources.redhat.com/ecos/ecos-license/
40
// -------------------------------------------
41
//####ECOSGPLCOPYRIGHTEND####
42
//==========================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):    hmt, nickg
46
// Contributors: nickg, jskov,
47
//               gthomas, jlarmour
48
// Date:         2001-05-24
49
// Purpose:      uPD985xx Interrupt support
50
// Description:  The macros defined here provide the HAL APIs for handling
51
//               interrupts and the clock for variants of the NEC uPD985xx
52
//               architecture.
53
//              
54
// Usage:
55
//              #include <cyg/hal/var_intr.h>
56
//              ...
57
//              
58
//
59
//####DESCRIPTIONEND####
60
//
61
//==========================================================================
62
 
63
#include <cyg/hal/var_arch.h>
64
#include <cyg/hal/plf_intr.h>
65
 
66
//--------------------------------------------------------------------------
67
// Interrupt controller stuff.
68
 
69
#ifndef CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
70
// Interrupts dealt with via the status and cause registers
71
// must be numbered in bit order:
72
#define CYGNUM_HAL_INTERRUPT_STATUS_CAUSE_LOW  (0)
73
// The first two are the "software interrupts" - you just set a bit.
74
#define CYGNUM_HAL_INTERRUPT_SOFT_ZERO         (0)
75
#define CYGNUM_HAL_INTERRUPT_SOFT_ONE          (1)
76
#define CYGNUM_HAL_INTERRUPT_FREE_TWO          (2)
77
#define CYGNUM_HAL_INTERRUPT_USB               (3)
78
#define CYGNUM_HAL_INTERRUPT_ETHER             (4)
79
#define CYGNUM_HAL_INTERRUPT_FREE_FIVE         (5)
80
#define CYGNUM_HAL_INTERRUPT_SYSCTL            (6)
81
#define CYGNUM_HAL_INTERRUPT_COMPARE           (7)
82
 
83
// Number 6 "SYSCTL" is all external sources in the system controller and
84
// will normally be decoded into one of 8-12 instead.  If you use number 6
85
// directly, then this will disable *all* system controller sources.
86
// Startup code will ensure number 6 is unmasked by default, and it will
87
// have an arbitration routine installed to call all of the subsequent
88
// interrupts from the S_ISR register.  This has to be an external routine
89
// because the S_ISR register is read-clear, and the interrupt sources are
90
// edge-triggered so they do not re-assert themselves - so we must address
91
// multiple sources per actual interrupt, in a loop.
92
 
93
#define CYGNUM_HAL_INTERRUPT_SYSCTL_LOW        (8)
94
#define CYGNUM_HAL_INTERRUPT_SYSCTL_HI        (12)
95
 
96
#define CYGNUM_HAL_INTERRUPT_TM0               (8) // TIMER CH0 interrupt.
97
#define CYGNUM_HAL_INTERRUPT_TM1               (9) // TIMER CH1 interrupt.
98
#define CYGNUM_HAL_INTERRUPT_UART             (10) // UART interrupt.
99
#define CYGNUM_HAL_INTERRUPT_EXT              (11) // External Interrupt.
100
#define CYGNUM_HAL_INTERRUPT_WU               (12) // Wakeup Interrupt.
101
 
102
#define CYGHWR_HAL_GDB_PORT_VECTOR CYGNUM_HAL_INTERRUPT_UART
103
 
104
// Min/Max ISR numbers and how many there are
105
#define CYGNUM_HAL_ISR_MIN                     0
106
#define CYGNUM_HAL_ISR_MAX                     12
107
#define CYGNUM_HAL_ISR_COUNT                   13
108
 
109
// The vector used by the Real time clock. The default here is to use
110
// interrupt 5, which is connected to the counter/comparator registers
111
// in many MIPS variants.
112
 
113
#ifndef CYGNUM_HAL_INTERRUPT_RTC
114
#define CYGNUM_HAL_INTERRUPT_RTC            CYGNUM_HAL_INTERRUPT_COMPARE
115
#endif
116
 
117
#define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
118
 
119
#endif // CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
120
 
121
#ifndef __ASSEMBLER__
122
 
123
// ------------------------------------------------------------------------
124
 
125
// This is placed in memory at a fixed location because we must share it
126
// with RedBoot, along with the VSR table and Virtual Vector table.
127
// It has to be an array to get the correct code generation to access it
128
// over all that distance.
129
externC volatile cyg_uint32 hal_interrupt_sr_mask_shadow_base[];
130
#define hal_interrupt_sr_mask_shadow (hal_interrupt_sr_mask_shadow_base[0])
131
 
132
// We have to have local versions of these to preserve the mask bits in the
133
// SR correctly when an interrupt occurs within one of these code sequences
134
// which are doing a read-modify-write to the main interrupt bit of the SR.
135
 
136
// Disable, it doesn't matter what the SR IM bits are - but it is possible
137
// for control to return with interrupts enabled if a context switch occurs
138
// away from the thread that disabled interrupts.  Therefore we also make
139
// sure the contents of the SR match the shadow variable at the end.
140
 
141
#define HAL_DISABLE_INTERRUPTS(_old_)                                   \
142
CYG_MACRO_START                                                         \
143
    register int _tmp;                                                  \
144
    asm volatile (                                                      \
145
        "mfc0   $8,$12; nop;"                                           \
146
        "move   %0,$8;"                                                 \
147
        "and    $8,$8,0xfffffffe;"                                      \
148
        "mtc0   $8,$12;"                                                \
149
        "nop; nop; nop;"                                                \
150
        : "=r"(_tmp)                                                    \
151
        :                                                               \
152
        : "$8"                                                          \
153
        );                                                              \
154
    /* interrupts disabled so can now inject the correct IM bits */     \
155
    (_old_) = _tmp & 1;                                                 \
156
    _tmp &= 0xffff00fe;                                                 \
157
    _tmp |= (hal_interrupt_sr_mask_shadow & 0xff00);                    \
158
    asm volatile (                                                      \
159
        "mtc0   %0,$12;"                                                \
160
        "nop; nop; nop;"                                                \
161
        :                                                               \
162
        : "r"(_tmp)                                                     \
163
        );                                                              \
164
CYG_MACRO_END
165
 
166
// Enable and restore, we must pick up hal_interrupt_sr_mask_shadow because
167
// it contains the truth.  This is also for the convenience of the
168
// mask/unmask macros below.
169
#define HAL_ENABLE_INTERRUPTS() HAL_RESTORE_INTERRUPTS(1)
170
 
171
#define HAL_RESTORE_INTERRUPTS(_old_)                                   \
172
CYG_MACRO_START                                                         \
173
    asm volatile (                                                      \
174
        "mfc0   $8,$12; nop;"                                           \
175
        "or     $8,$8,%0;"         /* inject IE bit  */                 \
176
        "and    $8,$8,0xffff00ff;" /* clear IM bits  */                 \
177
        "or     $8,$8,%1;"         /* insert true IM */                 \
178
        "mtc0   $8,$12;"                                                \
179
        "nop; nop; nop;"                                                \
180
        :                                                               \
181
        : "r"((_old_) & 1),"r"(hal_interrupt_sr_mask_shadow & 0xff00)   \
182
        : "$8"                                                          \
183
        );                                                              \
184
CYG_MACRO_END
185
 
186
#define HAL_QUERY_INTERRUPTS( _state_ )         \
187
CYG_MACRO_START                                 \
188
    asm volatile (                              \
189
        "mfc0   %0,$12; nop;"                   \
190
        "and    %0,%0,0x1;"                     \
191
        : "=r"(_state_)                         \
192
        );                                      \
193
CYG_MACRO_END
194
 
195
#define CYGHWR_HAL_INTERRUPT_ENABLE_DISABLE_RESTORE_DEFINED
196
 
197
// ------------------------------------------------------------------------
198
 
199
// For the bits which are in the SR, we only need to diddle the shadow
200
// variable; restore interrupts will pick that up at the end of the macro.
201
// Neat, huh.
202
 
203
#ifndef CYGOPT_HAL_MIPS_UPD985XX_HARDWARE_BUGS_S2
204
// Vanilla versions here: trick versions with the workaround follow:
205
 
206
#define HAL_INTERRUPT_MASK( _vector_ )                                  \
207
CYG_MACRO_START                                                         \
208
register int _intstate;                                                 \
209
register int _shift;                                                    \
210
HAL_DISABLE_INTERRUPTS( _intstate );                                    \
211
if ( CYGNUM_HAL_INTERRUPT_SYSCTL_LOW > (_vector_) ) {                   \
212
    /* mask starts at bit 8 */                                          \
213
    _shift = 8 + (_vector_) - CYGNUM_HAL_INTERRUPT_STATUS_CAUSE_LOW;    \
214
    hal_interrupt_sr_mask_shadow &=~(1 << _shift);                      \
215
}                                                                       \
216
else {                                                                  \
217
    _shift = (_vector_) - CYGNUM_HAL_INTERRUPT_SYSCTL_LOW;              \
218
    *S_IMR &=~(1 << _shift);                                            \
219
}                                                                       \
220
HAL_RESTORE_INTERRUPTS( _intstate );                                    \
221
CYG_MACRO_END
222
 
223
 
224
#define HAL_INTERRUPT_UNMASK( _vector_ )                                \
225
CYG_MACRO_START                                                         \
226
register int _intstate;                                                 \
227
register int _shift;                                                    \
228
HAL_DISABLE_INTERRUPTS( _intstate );                                    \
229
if ( CYGNUM_HAL_INTERRUPT_SYSCTL_LOW > (_vector_) ) {                   \
230
    /* mask starts at bit 8 */                                          \
231
    _shift = 8 + (_vector_) - CYGNUM_HAL_INTERRUPT_STATUS_CAUSE_LOW;    \
232
    hal_interrupt_sr_mask_shadow |= (1 << _shift);                      \
233
}                                                                       \
234
else {                                                                  \
235
    _shift = (_vector_) - CYGNUM_HAL_INTERRUPT_SYSCTL_LOW;              \
236
    *S_IMR |= (1 << _shift);                                            \
237
}                                                                       \
238
HAL_RESTORE_INTERRUPTS( _intstate );                                    \
239
CYG_MACRO_END
240
 
241
 
242
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )                           \
243
CYG_MACRO_START                                                         \
244
register int _intstate;                                                          \
245
HAL_DISABLE_INTERRUPTS( _intstate );                                    \
246
/* Default clears the bit in the cause register.  But VR4120 doc   */   \
247
/* says this is a NOP so we ignore low numbered sources except the */   \
248
/* software interrupt bits.                                        */   \
249
if ( CYGNUM_HAL_INTERRUPT_SYSCTL_LOW <= (_vector_) ||                   \
250
     CYGNUM_HAL_INTERRUPT_SYSCTL     == (_vector_) ) {                  \
251
    register int i;                                                     \
252
    i = *S_ISR; /* This is read-clear! */                               \
253
}                                                                       \
254
else if ( CYGNUM_HAL_INTERRUPT_SOFT_ZERO ==  (_vector_) ||              \
255
          CYGNUM_HAL_INTERRUPT_SOFT_ONE  ==  (_vector_) ) {             \
256
    /* These two are acknowledged by writing the bit to zero in */      \
257
    /* the cause register.  NB not the status register!         */      \
258
    asm volatile (                                                      \
259
        "mfc0   $3,$13\n"                                               \
260
        "la     $2,0x00000100\n"                                        \
261
        "sllv   $2,$2,%0\n"                                             \
262
        "andi   $2,$2,0x0300\n"                                         \
263
        "nor    $2,$2,$0\n"                                             \
264
        "and    $3,$3,$2\n"                                             \
265
        "mtc0   $3,$13\n"                                               \
266
        "nop; nop; nop\n"                                               \
267
        :                                                               \
268
        : "r"((_vector_)-CYGNUM_HAL_INTERRUPT_STATUS_CAUSE_LOW)         \
269
        : "$2", "$3"                                                    \
270
        );                                                              \
271
}                                                                       \
272
HAL_RESTORE_INTERRUPTS( _intstate );                                    \
273
CYG_MACRO_END
274
 
275
#else // DEFINED:  CYGOPT_HAL_MIPS_UPD985XX_HARDWARE_BUGS_S2
276
 
277
#ifdef __cplusplus
278
extern "C" {
279
#endif
280
extern void cyg_hal_interrupt_unmask( int vec );
281
extern void cyg_hal_interrupt_mask( int vec );
282
extern void cyg_hal_interrupt_acknowledge( int vec );
283
#ifdef __cplusplus
284
}      /* extern "C" */
285
#endif
286
 
287
#define HAL_INTERRUPT_MASK( _vector_ )                                  \
288
CYG_MACRO_START                                                         \
289
register int _intstate;                                                 \
290
register int _shift;                                                    \
291
HAL_DISABLE_INTERRUPTS( _intstate );                                    \
292
if ( CYGNUM_HAL_INTERRUPT_SYSCTL_LOW > (_vector_) ) {                   \
293
    /* mask starts at bit 8 */                                          \
294
    _shift = 8 + (_vector_) - CYGNUM_HAL_INTERRUPT_STATUS_CAUSE_LOW;    \
295
    hal_interrupt_sr_mask_shadow &=~(1 << _shift);                      \
296
}                                                                       \
297
else {                                                                  \
298
    cyg_hal_interrupt_mask( (_vector_) );                               \
299
}                                                                       \
300
HAL_RESTORE_INTERRUPTS( _intstate );                                    \
301
CYG_MACRO_END
302
 
303
 
304
#define HAL_INTERRUPT_UNMASK( _vector_ )                                \
305
CYG_MACRO_START                                                         \
306
register int _intstate;                                                 \
307
register int _shift;                                                    \
308
HAL_DISABLE_INTERRUPTS( _intstate );                                    \
309
if ( CYGNUM_HAL_INTERRUPT_SYSCTL_LOW > (_vector_) ) {                   \
310
    /* mask starts at bit 8 */                                          \
311
    _shift = 8 + (_vector_) - CYGNUM_HAL_INTERRUPT_STATUS_CAUSE_LOW;    \
312
    hal_interrupt_sr_mask_shadow |= (1 << _shift);                      \
313
}                                                                       \
314
else {                                                                  \
315
    cyg_hal_interrupt_unmask( (_vector_) );                             \
316
}                                                                       \
317
HAL_RESTORE_INTERRUPTS( _intstate );                                    \
318
CYG_MACRO_END
319
 
320
 
321
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )                           \
322
CYG_MACRO_START                                                         \
323
register int _intstate;                                                          \
324
HAL_DISABLE_INTERRUPTS( _intstate );                                    \
325
/* Default clears the bit in the cause register.  But VR4120 doc   */   \
326
/* says this is a NOP so we ignore low numbered sources except the */   \
327
/* software interrupt bits.                                        */   \
328
if ( CYGNUM_HAL_INTERRUPT_SYSCTL_LOW <= (_vector_) ||                   \
329
     CYGNUM_HAL_INTERRUPT_SYSCTL     == (_vector_) ) {                  \
330
    cyg_hal_interrupt_acknowledge( (_vector_) );                        \
331
}                                                                       \
332
else if ( CYGNUM_HAL_INTERRUPT_SOFT_ZERO ==  (_vector_) ||              \
333
          CYGNUM_HAL_INTERRUPT_SOFT_ONE  ==  (_vector_) ) {             \
334
    /* These two are acknowledged by writing the bit to zero in */      \
335
    /* the cause register.  NB not the status register!         */      \
336
    asm volatile (                                                      \
337
        "mfc0   $3,$13\n"                                               \
338
        "la     $2,0x00000100\n"                                        \
339
        "sllv   $2,$2,%0\n"                                             \
340
        "andi   $2,$2,0x0300\n"                                         \
341
        "nor    $2,$2,$0\n"                                             \
342
        "and    $3,$3,$2\n"                                             \
343
        "mtc0   $3,$13\n"                                               \
344
        "nop; nop; nop\n"                                               \
345
        :                                                               \
346
        : "r"((_vector_)-CYGNUM_HAL_INTERRUPT_STATUS_CAUSE_LOW)         \
347
        : "$2", "$3"                                                    \
348
        );                                                              \
349
}                                                                       \
350
HAL_RESTORE_INTERRUPTS( _intstate );                                    \
351
CYG_MACRO_END
352
 
353
#endif // CYGOPT_HAL_MIPS_UPD985XX_HARDWARE_BUGS_S2
354
 
355
#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ )
356
 
357
#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )
358
 
359
#define CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
360
 
361
//--------------------------------------------------------------------------
362
// Useful for debugging...
363
 
364
#define HAL_READ_INTR_REGS( _status, _cause )   \
365
{                                               \
366
    asm volatile (                              \
367
        "mfc0   %0,$12; nop;"                   \
368
        : "=r"(_status)                         \
369
        );                                      \
370
    asm volatile (                              \
371
        "mfc0   %0,$13; nop;"                   \
372
        : "=r"(_cause)                          \
373
        );                                      \
374
}
375
 
376
//--------------------------------------------------------------------------
377
#endif // ! __ASSEMBLER__
378
 
379
#endif // ifndef CYGONCE_HAL_VAR_INTR_H
380
// End of var_intr.h

powered by: WebSVN 2.1.0

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