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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [openrisc/] [arch/] [current/] [include/] [hal_intr.h] - Blame information for rev 587

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      hal_intr.h
4
//
5
//      HAL Interrupt and clock support
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):    sfurman
44
// Contributors: 
45
// Date:         2003-01-24
46
// Purpose:      Define Interrupt support
47
// Description:  The macros defined here provide the HAL APIs for handling
48
//               both external interrupts and clock interrupts.
49
//              
50
// Usage:
51
//              #include <cyg/hal/hal_intr.h>
52
//              ...
53
//              
54
//
55
//####DESCRIPTIONEND####
56
//
57
//==========================================================================
58
 
59
#ifndef CYGONCE_HAL_HAL_INTR_H
60
#define CYGONCE_HAL_HAL_INTR_H
61
 
62
#include <cyg/hal/hal_arch.h>
63
 
64
//--------------------------------------------------------------------------
65
// OpenRISC vectors. 
66
 
67
// These are the exception/interrupt causes defined by the hardware.
68
// These values are the ones to use for HAL_VSR_GET/SET
69
 
70
// Reset
71
#define CYGNUM_HAL_VECTOR_RESET                0x01
72
 
73
// Bus Error - probably invalid physical address
74
#define CYGNUM_HAL_VECTOR_BUS_ERROR            0x02
75
 
76
// Either no matching page-table entry or protection fault
77
// while executing load/store operation
78
#define CYGNUM_HAL_VECTOR_DATA_PAGE_FAULT      0x03
79
 
80
// Either no matching page-table entry or protection fault
81
// while fetching instruction
82
#define CYGNUM_HAL_VECTOR_INSTR_PAGE_FAULT     0x04
83
 
84
// Tick Timer interrupt
85
#define CYGNUM_HAL_VECTOR_TICK_TIMER           0x05
86
 
87
// Unaligned access
88
#define CYGNUM_HAL_VECTOR_UNALIGNED_ACCESS     0x06
89
 
90
// Illegal instruction
91
#define CYGNUM_HAL_VECTOR_RESERVED_INSTRUCTION 0x07
92
 
93
// External Interrupt from PIC
94
#define CYGNUM_HAL_VECTOR_INTERRUPT            0x08
95
 
96
// D-TLB Miss
97
#define CYGNUM_HAL_VECTOR_DTLB_MISS            0x09
98
 
99
// I-TLB Miss
100
#define CYGNUM_HAL_VECTOR_ITLB_MISS            0x0A
101
 
102
// Numeric overflow, etc.
103
#define CYGNUM_HAL_VECTOR_RANGE                0x0B
104
 
105
// System Call
106
#define CYGNUM_HAL_VECTOR_SYSTEM_CALL          0x0C
107
 
108
// TRAP instruction executed
109
#define CYGNUM_HAL_VECTOR_TRAP                 0x0E
110
 
111
#define CYGNUM_HAL_VSR_MIN                     CYGNUM_HAL_VECTOR_RESET
112
#define CYGNUM_HAL_VSR_MAX                     CYGNUM_HAL_VECTOR_TRAP
113
#define CYGNUM_HAL_VSR_COUNT                   (CYGNUM_HAL_VSR_MAX-CYGNUM_HAL_VSR_MIN+1)
114
 
115
// Exception vectors. These are the values used when passed out to an
116
// external exception handler using cyg_hal_deliver_exception()
117
 
118
#define CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS \
119
          CYGNUM_HAL_VECTOR_DTLB_MISS
120
#define CYGNUM_HAL_EXCEPTION_DATA_TLBMISS_ACCESS \
121
          CYGNUM_HAL_VECTOR_DTLB_MISS
122
#define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS \
123
          CYGNUM_HAL_VECTOR_UNALIGNED_ACCESS
124
#define CYGNUM_HAL_EXCEPTION_SYSTEM_CALL    CYGNUM_HAL_VECTOR_SYSTEM_CALL
125
#define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION \
126
          CYGNUM_HAL_VECTOR_RESERVED_INSTRUCTION
127
#define CYGNUM_HAL_EXCEPTION_OVERFLOW       CYGNUM_HAL_VECTOR_RANGE
128
#define CYGNUM_HAL_EXCEPTION_INTERRUPT      CYGNUM_HAL_VECTOR_INTERRUPT
129
 
130
// Min/Max exception numbers and how many there are
131
#define CYGNUM_HAL_EXCEPTION_MIN                CYGNUM_HAL_VSR_MIN
132
#define CYGNUM_HAL_EXCEPTION_MAX                CYGNUM_HAL_VSR_MAX
133
#define CYGNUM_HAL_EXCEPTION_COUNT           \
134
                 ( CYGNUM_HAL_EXCEPTION_MAX - CYGNUM_HAL_EXCEPTION_MIN + 1 )
135
 
136
 
137
#ifndef CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
138
#define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
139
 
140
// Interrupts 0-31 are connected to the PIC
141
#define CYGNUM_HAL_INTERRUPT_0                0
142
#define CYGNUM_HAL_INTERRUPT_1                1
143
#define CYGNUM_HAL_INTERRUPT_2                2
144
#define CYGNUM_HAL_INTERRUPT_3                3
145
#define CYGNUM_HAL_INTERRUPT_4                4
146
#define CYGNUM_HAL_INTERRUPT_5                5
147
#define CYGNUM_HAL_INTERRUPT_6                6
148
#define CYGNUM_HAL_INTERRUPT_7                7
149
#define CYGNUM_HAL_INTERRUPT_8                8
150
#define CYGNUM_HAL_INTERRUPT_9                9
151
#define CYGNUM_HAL_INTERRUPT_10               10
152
#define CYGNUM_HAL_INTERRUPT_11               11
153
#define CYGNUM_HAL_INTERRUPT_12               12
154
#define CYGNUM_HAL_INTERRUPT_13               13
155
#define CYGNUM_HAL_INTERRUPT_14               14
156
#define CYGNUM_HAL_INTERRUPT_15               15
157
#define CYGNUM_HAL_INTERRUPT_16               16
158
#define CYGNUM_HAL_INTERRUPT_17               17
159
#define CYGNUM_HAL_INTERRUPT_18               18
160
#define CYGNUM_HAL_INTERRUPT_19               19
161
#define CYGNUM_HAL_INTERRUPT_20               20
162
#define CYGNUM_HAL_INTERRUPT_21               21
163
#define CYGNUM_HAL_INTERRUPT_22               22
164
#define CYGNUM_HAL_INTERRUPT_23               23
165
#define CYGNUM_HAL_INTERRUPT_24               24
166
#define CYGNUM_HAL_INTERRUPT_25               25
167
#define CYGNUM_HAL_INTERRUPT_26               26
168
#define CYGNUM_HAL_INTERRUPT_27               27
169
#define CYGNUM_HAL_INTERRUPT_28               28
170
#define CYGNUM_HAL_INTERRUPT_29               29
171
#define CYGNUM_HAL_INTERRUPT_30               30
172
#define CYGNUM_HAL_INTERRUPT_31               31
173
 
174
// By SW convention, interrupt #32 is the tick timer
175
#define CYGNUM_HAL_INTERRUPT_32               32
176
 
177
// The interrupt vector used by the RTC, aka tick timer
178
#define CYGNUM_HAL_INTERRUPT_RTC            CYGNUM_HAL_INTERRUPT_32
179
 
180
// Min/Max ISR numbers and how many there are
181
#define CYGNUM_HAL_ISR_MIN                     0
182
#define CYGNUM_HAL_ISR_MAX                     32
183
#define CYGNUM_HAL_ISR_COUNT                   33
184
 
185
#endif
186
 
187
#ifndef __ASSEMBLER__
188
#include <pkgconf/hal.h>
189
 
190
#include <cyg/infra/cyg_type.h>
191
#include <cyg/hal/hal_io.h>
192
 
193
#include <cyg/hal/plf_intr.h>
194
 
195
//--------------------------------------------------------------------------
196
// Static data used by HAL
197
 
198
// ISR tables
199
externC volatile CYG_ADDRESS    hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
200
externC volatile CYG_ADDRWORD   hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
201
externC volatile CYG_ADDRESS    hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
202
 
203
// VSR table
204
externC volatile CYG_ADDRESS    hal_vsr_table[CYGNUM_HAL_VSR_MAX+1];
205
 
206
//--------------------------------------------------------------------------
207
// Default ISR
208
// The #define is used to test whether this routine exists, and to allow
209
// us to call it.
210
 
211
externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
212
 
213
#define HAL_DEFAULT_ISR hal_default_isr
214
 
215
//--------------------------------------------------------------------------
216
// Interrupt state storage
217
 
218
typedef cyg_uint32 CYG_INTERRUPT_STATE;
219
 
220
//--------------------------------------------------------------------------
221
// Interrupt control macros
222
#ifndef CYGHWR_HAL_INTERRUPT_ENABLE_DISABLE_RESTORE_DEFINED
223
 
224
// Clear both tick timer and external interrupts in the Supervisor Register
225
#define HAL_DISABLE_INTERRUPTS(_old_)                     \
226
    CYG_MACRO_START                                       \
227
    _old_ = MFSPR(SPR_SR);                                \
228
    MTSPR(SPR_SR, _old_ & ~(SPR_SR_IEE|SPR_SR_TEE));      \
229
    CYG_MACRO_END
230
 
231
// Enable both tick timer and external interrupts in the Supervisor Register
232
#define HAL_ENABLE_INTERRUPTS()                           \
233
    MTSPR(SPR_SR, MFSPR(SPR_SR) | (SPR_SR_IEE|SPR_SR_TEE))
234
 
235
// Copy interrupt flags from argument into Supervisor Register
236
#define HAL_RESTORE_INTERRUPTS(_old_)                     \
237
    CYG_MACRO_START                                       \
238
    cyg_uint32 t1,t2;                                     \
239
    t1 = MFSPR(SPR_SR) & ~(SPR_SR_IEE|SPR_SR_TEE);        \
240
    t2 = (_old_) & (SPR_SR_IEE|SPR_SR_TEE);               \
241
    MTSPR(SPR_SR, t1 | t2);                               \
242
    CYG_MACRO_END
243
 
244
#define HAL_QUERY_INTERRUPTS( _state_ )                   \
245
    CYG_MACRO_START                                       \
246
    _state = MFSPR(SPR_SR);                               \
247
    CYG_MACRO_END
248
 
249
#endif // CYGHWR_HAL_INTERRUPT_ENABLE_DISABLE_RESTORE_DEFINED
250
 
251
//--------------------------------------------------------------------------
252
// Routine to execute DSRs using separate interrupt stack
253
 
254
#ifdef  CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
255
externC void hal_interrupt_stack_call_pending_DSRs(void);
256
#define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
257
    hal_interrupt_stack_call_pending_DSRs()
258
 
259
// these are offered solely for stack usage testing
260
// if they are not defined, then there is no interrupt stack.
261
#define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
262
#define HAL_INTERRUPT_STACK_TOP  cyg_interrupt_stack
263
// use them to declare these extern however you want:
264
//       extern char HAL_INTERRUPT_STACK_BASE[];
265
//       extern char HAL_INTERRUPT_STACK_TOP[];
266
// is recommended
267
#endif
268
 
269
//--------------------------------------------------------------------------
270
// Vector translation.
271
// For chained interrupts we only have a single vector though which all
272
// are passed. For unchained interrupts we have a vector per interrupt.
273
 
274
#ifndef HAL_TRANSLATE_VECTOR
275
 
276
#if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN)
277
 
278
#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = 0
279
 
280
#else
281
 
282
#define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_)
283
 
284
#endif
285
 
286
#endif
287
 
288
//--------------------------------------------------------------------------
289
// Interrupt and VSR attachment macros
290
 
291
#define HAL_INTERRUPT_IN_USE( _vector_, _state_)                          \
292
    CYG_MACRO_START                                                       \
293
    cyg_uint32 _index_;                                                   \
294
    HAL_TRANSLATE_VECTOR ((_vector_), _index_);                           \
295
                                                                          \
296
    if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR ) \
297
        (_state_) = 0;                                                    \
298
    else                                                                  \
299
        (_state_) = 1;                                                    \
300
    CYG_MACRO_END
301
 
302
#define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ )           \
303
{                                                                           \
304
    cyg_uint32 _index_;                                                     \
305
    HAL_TRANSLATE_VECTOR( _vector_, _index_ );                              \
306
                                                                            \
307
    if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR )   \
308
    {                                                                       \
309
        hal_interrupt_handlers[_index_] = (CYG_ADDRESS)_isr_;               \
310
        hal_interrupt_data[_index_] = (CYG_ADDRWORD)_data_;                 \
311
        hal_interrupt_objects[_index_] = (CYG_ADDRESS)_object_;             \
312
    }                                                                       \
313
}
314
 
315
#define HAL_INTERRUPT_DETACH( _vector_, _isr_ )                         \
316
{                                                                       \
317
    cyg_uint32 _index_;                                                 \
318
    HAL_TRANSLATE_VECTOR( _vector_, _index_ );                          \
319
                                                                        \
320
    if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)_isr_ )         \
321
    {                                                                   \
322
        hal_interrupt_handlers[_index_] = (CYG_ADDRESS)HAL_DEFAULT_ISR; \
323
        hal_interrupt_data[_index_] = 0;                                \
324
        hal_interrupt_objects[_index_] = 0;                             \
325
    }                                                                   \
326
}
327
 
328
#define HAL_VSR_GET( _vector_, _pvsr_ )                 \
329
    *(_pvsr_) = (void (*)())hal_vsr_table[_vector_];
330
 
331
 
332
#define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) CYG_MACRO_START         \
333
    if( (void*)_poldvsr_ != NULL)                                         \
334
        *(CYG_ADDRESS *)_poldvsr_ = (CYG_ADDRESS)hal_vsr_table[_vector_]; \
335
    hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_;                         \
336
CYG_MACRO_END
337
 
338
// This is an ugly name, but what it means is: grab the VSR back to eCos
339
// internal handling, or if you like, the default handler.  But if
340
// cooperating with GDB and CygMon, the default behaviour is to pass most
341
// exceptions to CygMon.  This macro undoes that so that eCos handles the
342
// exception.  So use it with care.
343
 
344
externC void cyg_hal_default_exception_vsr(void);
345
externC void cyg_hal_default_interrupt_vsr(void);
346
 
347
#define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) CYG_MACRO_START  \
348
    HAL_VSR_SET( _vector_, _vector_ == CYGNUM_HAL_VECTOR_INTERRUPT          \
349
                              ? (CYG_ADDRESS)cyg_hal_default_interrupt_vsr  \
350
                              : (CYG_ADDRESS)cyg_hal_default_exception_vsr, \
351
                 _poldvsr_ );                                               \
352
CYG_MACRO_END
353
 
354
//--------------------------------------------------------------------------
355
// Interrupt controller access
356
 
357
#ifndef CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
358
#define CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
359
 
360
// Mask (disable) interrupts from specified source
361
#define HAL_INTERRUPT_MASK( _vector_ )            \
362
CYG_MACRO_START                                   \
363
    int mask;                                     \
364
    if ((_vector_) == CYGNUM_HAL_INTERRUPT_RTC) { \
365
        /* The tick timer interrupt isn't */      \
366
        /* controlled by the PIC; It has its own*/\
367
        /* enable bit in the SR. */               \
368
        MTSPR(SPR_SR, MFSPR(SPR_SR)& ~SPR_SR_TEE);\
369
    } else {                                      \
370
        mask = ~(1 << (_vector_));                \
371
        MTSPR(SPR_PICMR, MFSPR(SPR_PICMR)& mask); \
372
    }                                             \
373
CYG_MACRO_END
374
 
375
// Allow interrupts from specified source
376
#define HAL_INTERRUPT_UNMASK( _vector_ )          \
377
CYG_MACRO_START                                   \
378
    int bit;                                      \
379
    if ((_vector_) == CYGNUM_HAL_INTERRUPT_RTC) { \
380
        /* The tick timer interrupt isn't */      \
381
        /* controlled by the PIC; It has its own*/\
382
        /* enable bit in the SR. */               \
383
        MTSPR(SPR_SR, MFSPR(SPR_SR) | SPR_SR_TEE);\
384
    } else {                                      \
385
        bit = (1 << (_vector_));                  \
386
        MTSPR(SPR_PICMR, MFSPR(SPR_PICMR) | bit); \
387
    }                                             \
388
CYG_MACRO_END
389
 
390
// Reset interrupt request in the PIC for specified device
391
#define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )     \
392
CYG_MACRO_START                                   \
393
    int mask;                                     \
394
    if ((_vector_) != CYGNUM_HAL_INTERRUPT_RTC) { \
395
        mask = ~(1 << (_vector_));                \
396
        MTSPR(SPR_PICSR, MFSPR(SPR_PICSR) & mask);\
397
    }                                             \
398
CYG_MACRO_END
399
 
400
#define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) CYG_EMPTY_STATEMENT
401
 
402
#define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )  CYG_EMPTY_STATEMENT
403
 
404
#endif
405
 
406
//--------------------------------------------------------------------------
407
// Clock control.
408
 
409
externC CYG_WORD32 cyg_hal_clock_period;
410
#define CYGHWR_HAL_CLOCK_PERIOD_DEFINED
411
 
412
// Start tick timer interrupts
413
#define HAL_CLOCK_INITIALIZE( _period_ )        \
414
CYG_MACRO_START                                 \
415
{                                               \
416
    int ttmr_new = _period_ | 0x60000000;       \
417
    MTSPR(SPR_TTMR, 0);                         \
418
    MTSPR(SPR_TTCR, 0);                         \
419
    MTSPR(SPR_TTMR, ttmr_new);                  \
420
    cyg_hal_clock_period = _period_;            \
421
}                                               \
422
CYG_MACRO_END
423
 
424
// Acknowledge clock timer interrupt
425
#define HAL_CLOCK_RESET( _vector_, _period_ )   \
426
CYG_MACRO_START                                 \
427
    int ttmr_new = _period_ | 0x60000000;       \
428
    MTSPR(SPR_TTMR, ttmr_new);                  \
429
CYG_MACRO_END
430
 
431
// Read the current value of the tick timer
432
#define HAL_CLOCK_READ( _pvalue_ )              \
433
CYG_MACRO_START                                 \
434
    *(_pvalue_) = MFSPR(SPR_TTCR);              \
435
CYG_MACRO_END
436
 
437
#if defined(CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY) && \
438
    !defined(HAL_CLOCK_LATENCY)
439
#define HAL_CLOCK_LATENCY( _pvalue_ )                   \
440
CYG_MACRO_START                                         \
441
    register CYG_WORD32 _cval_;                         \
442
    HAL_CLOCK_READ(&_cval_);                            \
443
    *(_pvalue_) = _cval_ - cyg_hal_clock_period;        \
444
CYG_MACRO_END
445
#endif
446
 
447
 
448
//--------------------------------------------------------------------------
449
// Microsecond delay function provided in hal_misc.c
450
externC void hal_delay_us(int us);
451
 
452
#define HAL_DELAY_US(n)          hal_delay_us(n)
453
 
454
#endif /* #ifndef __ASSEMBLER__ */
455
 
456
//--------------------------------------------------------------------------
457
#endif // ifndef CYGONCE_HAL_HAL_INTR_H
458
// End of hal_intr.h

powered by: WebSVN 2.1.0

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