]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/calmrisc32/arch/v2_0/include/hal_intr.h
Initial revision
[karo-tx-redboot.git] / packages / hal / calmrisc32 / arch / v2_0 / include / hal_intr.h
1 #ifndef CYGONCE_HAL_HAL_INTR_H
2 #define CYGONCE_HAL_HAL_INTR_H
3
4 //==========================================================================
5 //
6 //      hal_intr.h
7 //
8 //      HAL Interrupt and clock support
9 //
10 //==========================================================================
11 //####ECOSGPLCOPYRIGHTBEGIN####
12 // -------------------------------------------
13 // This file is part of eCos, the Embedded Configurable Operating System.
14 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
15 //
16 // eCos is free software; you can redistribute it and/or modify it under
17 // the terms of the GNU General Public License as published by the Free
18 // Software Foundation; either version 2 or (at your option) any later version.
19 //
20 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
21 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
22 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
23 // for more details.
24 //
25 // You should have received a copy of the GNU General Public License along
26 // with eCos; if not, write to the Free Software Foundation, Inc.,
27 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 //
29 // As a special exception, if other files instantiate templates or use macros
30 // or inline functions from this file, or you compile this file and link it
31 // with other works to produce a work based on this file, this file does not
32 // by itself cause the resulting work to be covered by the GNU General Public
33 // License. However the source code for this file must still be made available
34 // in accordance with section (3) of the GNU General Public License.
35 //
36 // This exception does not invalidate any other reasons why a work based on
37 // this file might be covered by the GNU General Public License.
38 //
39 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
40 // at http://sources.redhat.com/ecos/ecos-license/
41 // -------------------------------------------
42 //####ECOSGPLCOPYRIGHTEND####
43 //==========================================================================
44 //#####DESCRIPTIONBEGIN####
45 //
46 // Author(s):    nickg
47 // Contributors: nickg, jskov,
48 //               gthomas, jlarmour, msalter
49 // Date:         1999-02-16
50 // Purpose:      Define Interrupt support
51 // Description:  The macros defined here provide the HAL APIs for handling
52 //               interrupts and the clock.
53 //              
54 // Usage:
55 //              #include <cyg/hal/hal_intr.h>
56 //              ...
57 //              
58 //
59 //####DESCRIPTIONEND####
60 //
61 //==========================================================================
62
63 #include <pkgconf/hal.h>
64
65 #include <cyg/infra/cyg_type.h>
66 #include <cyg/hal/hal_io.h>
67
68 #include <cyg/hal/var_intr.h>
69
70 //--------------------------------------------------------------------------
71 // MIPS vectors. 
72
73 // These are the exception codes presented in the Cause register and
74 // correspond to VSRs. These values are the ones to use for HAL_VSR_GET/SET
75
76
77 #define CYGNUM_HAL_VECTOR_FIQ      0  // External Fast Interrupt
78 #define CYGNUM_HAL_VECTOR_IRQ      1  // External Interrupt
79 #define CYGNUM_HAL_VECTOR_COP      2  // Coprocessor Exception
80 #define CYGNUM_HAL_VECTOR_DABRT    3  // Data abort
81 #define CYGNUM_HAL_VECTOR_IABRT    4  // Instruction abort
82 #define CYGNUM_HAL_VECTOR_PRIV     5  // Privilege violation
83 #define CYGNUM_HAL_VECTOR_UNIMPL   6  // Unimplemented Insn
84 #define CYGNUM_HAL_VECTOR_TRACE    7  // Single-step
85 #define CYGNUM_HAL_VECTOR_SWI      8  // SWI
86
87 #define CYGNUM_HAL_VSR_MIN                     0
88 #define CYGNUM_HAL_VSR_MAX                     8
89 #define CYGNUM_HAL_VSR_COUNT                   9
90
91 // Min/Max exception numbers and how many there are
92 #define CYGNUM_HAL_EXCEPTION_MIN                0
93 #define CYGNUM_HAL_EXCEPTION_MAX                CYGNUM_HAL_VSR_MAX
94
95 #define CYGNUM_HAL_EXCEPTION_COUNT           \
96                  ( CYGNUM_HAL_EXCEPTION_MAX - CYGNUM_HAL_EXCEPTION_MIN + 1 )
97
98
99 #ifndef CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
100 #define CYGNUM_HAL_FAST_INTERRUPT           0
101 #define CYGNUM_HAL_INTERRUPT                1
102
103 // Min/Max ISR numbers and how many there are
104 #define CYGNUM_HAL_ISR_MIN                     0
105 #define CYGNUM_HAL_ISR_MAX                     1
106 #define CYGNUM_HAL_ISR_COUNT                   2
107
108 #define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
109 #endif
110
111 //--------------------------------------------------------------------------
112 // Static data used by HAL
113
114 // ISR tables
115 externC volatile CYG_ADDRESS    hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
116 externC volatile CYG_ADDRWORD   hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
117 externC volatile CYG_ADDRESS    hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
118
119 // VSR table
120 externC volatile CYG_ADDRESS    hal_vsr_table[CYGNUM_HAL_VSR_MAX+1];
121
122 //--------------------------------------------------------------------------
123 // Default ISR
124 // The #define is used to test whether this routine exists, and to allow
125 // us to call it.
126
127 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
128
129 #define HAL_DEFAULT_ISR hal_default_isr
130
131 //--------------------------------------------------------------------------
132 // Interrupt state storage
133
134 typedef cyg_uint32 CYG_INTERRUPT_STATE;
135
136 //--------------------------------------------------------------------------
137 // Interrupt control macros
138 // Beware of nops in this code. They fill delay slots and avoid CP0 hazards
139 // that might otherwise cause following code to run in the wrong state or
140 // cause a resource conflict.
141
142 #define HAL_DISABLE_INTERRUPTS(_old_)
143 #define HAL_ENABLE_INTERRUPTS()
144 #define HAL_RESTORE_INTERRUPTS(_old_)
145 #define HAL_QUERY_INTERRUPTS( _state_ )
146
147 //--------------------------------------------------------------------------
148 // Routine to execute DSRs using separate interrupt stack
149
150 #ifdef  CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
151 externC void hal_interrupt_stack_call_pending_DSRs(void);
152 #define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
153     hal_interrupt_stack_call_pending_DSRs()
154
155 // these are offered solely for stack usage testing
156 // if they are not defined, then there is no interrupt stack.
157 #define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
158 #define HAL_INTERRUPT_STACK_TOP  cyg_interrupt_stack
159 // use them to declare these extern however you want:
160 //       extern char HAL_INTERRUPT_STACK_BASE[];
161 //       extern char HAL_INTERRUPT_STACK_TOP[];
162 // is recommended
163 #endif
164
165 //--------------------------------------------------------------------------
166 // Vector translation.
167 // For chained interrupts we only have a single vector though which all
168 // are passed. For unchained interrupts we have a vector per interrupt.
169
170 #ifndef HAL_TRANSLATE_VECTOR
171
172 #if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN)
173
174 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = 0
175
176 #else
177
178 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_)
179
180 #endif
181
182 #endif
183
184 //--------------------------------------------------------------------------
185 // Interrupt and VSR attachment macros
186
187 #define HAL_INTERRUPT_IN_USE( _vector_, _state_)                          \
188     CYG_MACRO_START                                                       \
189     cyg_uint32 _index_;                                                   \
190     HAL_TRANSLATE_VECTOR ((_vector_), _index_);                           \
191                                                                           \
192     if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR ) \
193         (_state_) = 0;                                                    \
194     else                                                                  \
195         (_state_) = 1;                                                    \
196     CYG_MACRO_END
197
198 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ )           \
199 {                                                                           \
200     cyg_uint32 _index_;                                                     \
201     HAL_TRANSLATE_VECTOR( _vector_, _index_ );                              \
202                                                                             \
203     if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR )   \
204     {                                                                       \
205         hal_interrupt_handlers[_index_] = (CYG_ADDRESS)_isr_;               \
206         hal_interrupt_data[_index_] = (CYG_ADDRWORD)_data_;                 \
207         hal_interrupt_objects[_index_] = (CYG_ADDRESS)_object_;             \
208     }                                                                       \
209 }
210
211 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ )                         \
212 {                                                                       \
213     cyg_uint32 _index_;                                                 \
214     HAL_TRANSLATE_VECTOR( _vector_, _index_ );                          \
215                                                                         \
216     if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)_isr_ )         \
217     {                                                                   \
218         hal_interrupt_handlers[_index_] = (CYG_ADDRESS)HAL_DEFAULT_ISR; \
219         hal_interrupt_data[_index_] = 0;                                \
220         hal_interrupt_objects[_index_] = 0;                             \
221     }                                                                   \
222 }
223
224 #define HAL_VSR_GET( _vector_, _pvsr_ )                 \
225     *(_pvsr_) = (void (*)())hal_vsr_table[_vector_];
226     
227
228 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) CYG_MACRO_START         \
229     if( (void*)_poldvsr_ != NULL)                                         \
230         *(CYG_ADDRESS *)_poldvsr_ = (CYG_ADDRESS)hal_vsr_table[_vector_]; \
231     hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_;                         \
232 CYG_MACRO_END
233
234 // This is an ugly name, but what it means is: grab the VSR back to eCos
235 // internal handling, or if you like, the default handler.  But if
236 // cooperating with GDB and CygMon, the default behaviour is to pass most
237 // exceptions to CygMon.  This macro undoes that so that eCos handles the
238 // exception.  So use it with care.
239
240 externC void __default_exception_vsr(void);
241 externC void __default_interrupt_vsr(void);
242 externC void __break_vsr_springboard(void);
243
244 #define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) CYG_MACRO_START  \
245     HAL_VSR_SET( _vector_, _vector_ == CYGNUM_HAL_VECTOR_INTERRUPT          \
246                               ? (CYG_ADDRESS)__default_interrupt_vsr        \
247                               : _vector_ == CYGNUM_HAL_VECTOR_BREAKPOINT    \
248                                 ? (CYG_ADDRESS)__break_vsr_springboard      \
249                                 : (CYG_ADDRESS)__default_exception_vsr,     \
250                  _poldvsr_ );                                               \
251 CYG_MACRO_END
252
253 //--------------------------------------------------------------------------
254 // Interrupt controller access
255 // The default code here simply uses the fields present in the CP0 status
256 // and cause registers to implement this functionality.
257 // Beware of nops in this code. They fill delay slots and avoid CP0 hazards
258 // that might otherwise cause following code to run in the wrong state or
259 // cause a resource conflict.
260
261 #ifndef CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
262
263 #define HAL_INTERRUPT_MASK( _vector_ )
264
265 #define HAL_INTERRUPT_UNMASK( _vector_ )
266
267 #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )
268
269 #define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ )
270
271 #define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )
272
273 #define CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
274
275 #endif
276
277 //--------------------------------------------------------------------------
278 // Clock control.
279 // This code uses the count and compare registers that are present in many
280 // MIPS variants.
281 // Beware of nops in this code. They fill delay slots and avoid CP0 hazards
282 // that might otherwise cause following code to run in the wrong state or
283 // cause a resource conflict.
284
285 #ifndef CYGHWR_HAL_CLOCK_CONTROL_DEFINED
286
287 externC CYG_WORD32 cyg_hal_clock_period;
288 #define CYGHWR_HAL_CLOCK_PERIOD_DEFINED
289
290 #define HAL_CLOCK_INITIALIZE( _period_ )
291
292 #define HAL_CLOCK_RESET( _vector_, _period_ )
293
294 #define HAL_CLOCK_READ( _pvalue_ )
295
296 #define CYGHWR_HAL_CLOCK_CONTROL_DEFINED
297
298 #endif
299
300 //--------------------------------------------------------------------------
301 #endif // ifndef CYGONCE_HAL_HAL_INTR_H
302 // End of hal_intr.h