]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/coldfire/arch/v2_0/include/hal_intr.h
Initial revision
[karo-tx-redboot.git] / packages / hal / coldfire / 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 //      ColdFire interrupt/exception 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 // Copyright (C) 2006 eCosCentric Ltd.
16 //
17 // eCos is free software; you can redistribute it and/or modify it under
18 // the terms of the GNU General Public License as published by the Free
19 // Software Foundation; either version 2 or (at your option) any later version.
20 //
21 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
22 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24 // for more details.
25 //
26 // You should have received a copy of the GNU General Public License along
27 // with eCos; if not, write to the Free Software Foundation, Inc.,
28 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
29 //
30 // As a special exception, if other files instantiate templates or use macros
31 // or inline functions from this file, or you compile this file and link it
32 // with other works to produce a work based on this file, this file does not
33 // by itself cause the resulting work to be covered by the GNU General Public
34 // License. However the source code for this file must still be made available
35 // in accordance with section (3) of the GNU General Public License.
36 //
37 // This exception does not invalidate any other reasons why a work based on
38 // this file might be covered by the GNU General Public License.
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):     Enrico Piria
45 // Contributors:
46 // Date:          2005-25-06
47 // Purpose:       Provide ColdFire-specific interrupt and exception
48 //                definitions.
49 // Usage:         #include <cyg/hal/hal_intr.h>
50 //
51 //####DESCRIPTIONEND####
52 //========================================================================
53
54 #include <pkgconf/hal.h>
55 #include <cyg/infra/cyg_type.h>
56 #include <cyg/hal/hal_arch.h>
57
58 #include <cyg/hal/var_intr.h>
59
60 #include <cyg/infra/cyg_ass.h>      // CYG_FAIL
61
62 // -------------------------------------------------------------------------
63 // ColdFire exception vectors. These correspond to VSRs and are the values
64 // to use for HAL_VSR_GET/SET.
65
66 #define CYGNUM_HAL_VECTOR_RESETSP           0
67 #define CYGNUM_HAL_VECTOR_RESETPC           1
68 #define CYGNUM_HAL_VECTOR_BUSERR            2
69 #define CYGNUM_HAL_VECTOR_ADDRERR           3
70 #define CYGNUM_HAL_VECTOR_ILLINST           4
71 #define CYGNUM_HAL_VECTOR_ZERODIV           5
72
73 // Exception vectors 6-7 are reserved
74
75 #define CYGNUM_HAL_VECTOR_PRIVVIOLATION     8
76 #define CYGNUM_HAL_VECTOR_TRACE             9
77 #define CYGNUM_HAL_VECTOR_L1010             10
78 #define CYGNUM_HAL_VECTOR_L1111             11
79 #define CYGNUM_HAL_VECTOR_DEBUG12           12
80 #define CYGNUM_HAL_VECTOR_DEBUG13           13
81 #define CYGNUM_HAL_VECTOR_FORMAT            14
82 #define CYGNUM_HAL_VECTOR_UNINITINT         15
83
84 // Exception vectors 16-23 are reserved
85
86 #define CYGNUM_HAL_VECTOR_SPURINT           24
87
88 #define CYGNUM_HAL_VECTOR_AUTOVEC1          25
89 #define CYGNUM_HAL_VECTOR_AUTOVEC2          26
90 #define CYGNUM_HAL_VECTOR_AUTOVEC3          27
91 #define CYGNUM_HAL_VECTOR_AUTOVEC4          28
92 #define CYGNUM_HAL_VECTOR_AUTOVEC5          29
93 #define CYGNUM_HAL_VECTOR_AUTOVEC6          30
94 #define CYGNUM_HAL_VECTOR_AUTOVEC7          31
95 #define CYGNUM_HAL_NUMAUTOVEC               7
96
97 #define CYGNUM_HAL_VECTOR_TRAPFIRST         32
98 #define CYGNUM_HAL_VECTOR_TRAPLAST          47
99 #define CYGNUM_HAL_NUMTRAPS                 16
100
101 #define CYGNUM_HAL_VECTOR_FP_BRANCH         48
102 #define CYGNUM_HAL_VECTOR_FP_INEXACT        49
103 #define CYGNUM_HAL_VECTOR_FP_ZERODIV        50
104 #define CYGNUM_HAL_VECTOR_FP_UNDERFLOW      51
105 #define CYGNUM_HAL_VECTOR_FP_OPERAND        52
106 #define CYGNUM_HAL_VECTOR_FP_OVERFLOW       53
107 #define CYGNUM_HAL_VECTOR_FP_NAN            54
108 #define CYGNUM_HAL_VECTOR_FP_DENORM         55
109
110 // Exception vectors 56-60 are reserved
111
112 #define CYGNUM_HAL_VECTOR_UNSUPINST         61
113
114 // Exception vectors 62-63 are reserved
115
116 #define CYGNUM_HAL_VECTOR_USERINTRFIRST     64
117 #define CYGNUM_HAL_VECTOR_USERINTRLAST      255
118 #define CYGNUM_HAL_NUMUSERINTR              192
119
120 // -------------------------------------------------------------------------
121 // Interrupt and exception vector table definitions.
122
123 #define CYGNUM_HAL_VSR_MIN                  0
124 #define CYGNUM_HAL_VSR_MAX                  255
125 #define CYGNUM_HAL_VSR_COUNT                (CYGNUM_HAL_VSR_MAX - CYGNUM_HAL_VSR_MIN + 1)
126
127 // To simplify things in interrupt handling code, we don't take into account
128 // autovectored, spurious and uninitialized interrupts.
129
130 #ifndef CYGNUM_HAL_ISR_RANGE_DEFINED
131 #define CYGNUM_HAL_ISR_MIN                   CYGNUM_HAL_VECTOR_USERINTRFIRST
132 #define CYGNUM_HAL_ISR_MAX                   CYGNUM_HAL_VECTOR_USERINTRLAST
133 #define CYGNUM_HAL_ISR_COUNT                 (CYGNUM_HAL_ISR_MAX - CYGNUM_HAL_ISR_MIN + 1)
134 #endif
135
136 #ifndef CYGNUM_HAL_EXCEPTION_RANGE_DEFINED
137 #define CYGNUM_HAL_EXCEPTION_MIN             CYGNUM_HAL_VECTOR_BUSERR
138 #define CYGNUM_HAL_EXCEPTION_MAX             CYGNUM_HAL_VECTOR_UNSUPINST
139 #define CYGNUM_HAL_EXCEPTION_COUNT           (CYGNUM_HAL_EXCEPTION_MAX -\
140     CYGNUM_HAL_EXCEPTION_MIN + 1)
141 #endif
142
143 // -------------------------------------------------------------------------
144 // Equivalence between ColdFire exception names and target independent
145 // exception names.
146 // These are the values used when passed out to an
147 // external exception handler using cyg_hal_deliver_exception().
148
149 #define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION CYGNUM_HAL_VECTOR_ILLINST
150 #define CYGNUM_HAL_EXCEPTION_DIV_BY_ZERO         CYGNUM_HAL_VECTOR_ZERODIV
151 #define CYGNUM_HAL_EXCEPTION_DATA_ACCESS         CYGNUM_HAL_VECTOR_BUSERR
152 #define CYGNUM_HAL_EXCEPTION_CODE_ACCESS         CYGNUM_HAL_VECTOR_BUSERR
153
154 // -------------------------------------------------------------------------
155 // Spurious interrupt definition.
156
157 #ifndef CYGNUM_HAL_SPURIOUS_INTERRUPT
158 #define CYGNUM_HAL_SPURIOUS_INTERRUPT CYGNUM_HAL_VECTOR_SPURINT
159 #endif
160
161 // -------------------------------------------------------------------------
162 // Static data used by HAL.
163
164 // ISR tables
165 externC volatile CYG_ADDRESS  cyg_hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
166 externC volatile CYG_ADDRWORD cyg_hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
167 externC volatile CYG_ADDRESS  cyg_hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
168
169 // VSR table
170 externC volatile CYG_ADDRESS  cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
171
172 // ROM VSR table
173 externC CYG_ADDRESS rom_vsr_table[CYGNUM_HAL_VSR_COUNT];
174
175 // -------------------------------------------------------------------------
176 // Interrupt stack definitions.
177
178 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
179
180 externC void hal_interrupt_stack_call_pending_DSRs(void);
181 #define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
182     hal_interrupt_stack_call_pending_DSRs()
183
184 #endif
185
186 // A separate stack always exist to allow the processor to initialize itself.
187 // It depends on CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK macro
188 // definition if this stack is used for interrupts too.
189
190 #define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
191 #define HAL_INTERRUPT_STACK_TOP  cyg_interrupt_stack
192
193 externC char HAL_INTERRUPT_STACK_BASE[];
194 externC char HAL_INTERRUPT_STACK_TOP[];
195
196 // --------------------------------------------------------------------------
197 // Translate a vector number into an ISR table index.
198
199 #ifndef HAL_TRANSLATE_VECTOR
200 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_- CYGNUM_HAL_ISR_MIN)
201 #endif
202
203 // -------------------------------------------------------------------------
204 // Interrupt state storage.
205
206 typedef cyg_uint16 CYG_INTERRUPT_STATE;
207
208 // --------------------------------------------------------------------------
209 // Interrupt and VSR attachment macros.
210
211 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
212
213 externC void hal_default_exception_handler(CYG_WORD vector,
214                                            HAL_SavedRegisters *regs);
215
216 #define HAL_INTERRUPT_IN_USE( _vector_, _state_)        \
217 CYG_MACRO_START                                         \
218     cyg_uint32 _index_;                                 \
219     HAL_TRANSLATE_VECTOR ((_vector_), _index_);         \
220                                                         \
221     if (cyg_hal_interrupt_handlers[_index_]             \
222         == (CYG_ADDRESS) &hal_default_isr)              \
223         (_state_) = 0;                                  \
224     else                                                \
225         (_state_) = 1;                                  \
226 CYG_MACRO_END
227
228 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ )       \
229 CYG_MACRO_START                                                         \
230     cyg_uint32 _index_;                                                 \
231     HAL_TRANSLATE_VECTOR((_vector_), _index_);                          \
232                                                                         \
233     if (cyg_hal_interrupt_handlers[_index_]                             \
234         == (CYG_ADDRESS) &hal_default_isr)                              \
235     {                                                                   \
236         cyg_hal_interrupt_handlers[_index_] = (CYG_ADDRESS)(_isr_);     \
237         cyg_hal_interrupt_data[_index_] = (CYG_ADDRWORD)(_data_);       \
238         cyg_hal_interrupt_objects[_index_] = (CYG_ADDRESS)(_object_);   \
239     }                                                                   \
240 CYG_MACRO_END
241
242 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ )                         \
243 CYG_MACRO_START                                                         \
244     cyg_uint32 _index_;                                                 \
245     HAL_INTERRUPT_MASK(_vector_);                                       \
246     HAL_TRANSLATE_VECTOR((_vector_), _index_);                          \
247     if (cyg_hal_interrupt_handlers[_index_]                             \
248         == (CYG_ADDRESS)(_isr_))                                        \
249     {                                                                   \
250         cyg_hal_interrupt_handlers[_index_] =                           \
251             (CYG_ADDRESS)&hal_default_isr;                              \
252         cyg_hal_interrupt_data[_index_] = 0;                            \
253         cyg_hal_interrupt_objects[_index_] = 0;                         \
254     }                                                                   \
255 CYG_MACRO_END
256
257 #define HAL_VSR_GET( _vector_, _pvsr_ )                                 \
258     *((CYG_ADDRESS *)(_pvsr_)) = cyg_hal_vsr_table[(_vector_)];
259
260
261 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ )                       \
262 CYG_MACRO_START                                                         \
263     if( (_poldvsr_) != NULL )                                           \
264         *(CYG_ADDRESS *)(_poldvsr_) = cyg_hal_vsr_table[(_vector_)];    \
265     cyg_hal_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_);               \
266 CYG_MACRO_END
267
268
269 // This is an ugly name, but what it means is: grab the VSR back to eCos
270 // internal handling, or if you like, the default handler. But if
271 // cooperating with a ROM monitor, the default behaviour is to pass most
272 // exceptions to it. This macro undoes that so that eCos handles the
273 // exception. So use it with care.
274
275 #define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ )              \
276     CYG_MACRO_START                                                     \
277     if( (void*)_poldvsr_ != (void*)NULL )                               \
278         *(CYG_ADDRESS *)_poldvsr_ = cyg_hal_vsr_table[_vector_];        \
279     cyg_hal_vsr_table[_vector_] = rom_vsr_table[_vector_];              \
280     CYG_MACRO_END
281
282 // -------------------------------------------------------------------------
283 // Interrupt control macros.
284
285 // The following interrupt control macros are the default for the ColdFire
286 // architecture. Some processor variants will override these definitions in
287 // their var_intr.h file.
288
289 #ifndef HAL_CF_SET_SR
290 #define HAL_CF_SET_SR(__newsr__)                                            \
291     CYG_MACRO_START                                                         \
292     asm volatile ("move.w   %0,%%sr\n"                                      \
293                   :                                                         \
294                   : "d" ((CYG_INTERRUPT_STATE)(__newsr__)));                \
295     CYG_MACRO_END
296 #endif // HAL_CF_SET_SR
297
298 #ifndef HAL_ENABLE_INTERRUPTS
299 #define HAL_ENABLE_INTERRUPTS()                                             \
300     CYG_MACRO_START                                                         \
301     CYG_INTERRUPT_STATE _msk_;                                              \
302     HAL_QUERY_INTERRUPTS(_msk_);                                            \
303     HAL_CF_SET_SR((_msk_ & (CYG_INTERRUPT_STATE)0xf8ff));                   \
304     CYG_MACRO_END
305 #endif // HAL_ENABLE_INTERRUPTS
306
307 #ifndef HAL_DISABLE_INTERRUPTS
308 #define HAL_DISABLE_INTERRUPTS(_old_)                                       \
309     CYG_MACRO_START                                                         \
310     HAL_QUERY_INTERRUPTS(_old_);                                            \
311     HAL_CF_SET_SR((_old_ | (CYG_INTERRUPT_STATE)0x0700));                   \
312     CYG_MACRO_END
313 #endif //HAL_DISABLE_INTERRUPTS
314
315 #ifndef HAL_RESTORE_INTERRUPTS
316 #define HAL_RESTORE_INTERRUPTS(_prev_)                                      \
317     CYG_MACRO_START                                                         \
318     CYG_INTERRUPT_STATE _msk_;                                              \
319     HAL_QUERY_INTERRUPTS(_msk_);                                            \
320     _msk_ &= (CYG_INTERRUPT_STATE)0xf8ff;                                   \
321     _msk_ |= (((CYG_INTERRUPT_STATE)(_prev_))                               \
322               & (CYG_INTERRUPT_STATE)0x0700);                               \
323     asm volatile ("move.w   %0,%%sr\n"                                      \
324                   :                                                         \
325                   : "d" (_msk_));                                           \
326     CYG_MACRO_END
327 #endif // HAL_RESTORE_INTERRUPTS
328
329 // Use the extra assignment to avoid warnings.
330 // The compiler should optimize it out.
331 #ifndef HAL_QUERY_INTERRUPTS
332 #define HAL_QUERY_INTERRUPTS(__oldmask__)                                   \
333     CYG_MACRO_START                                                         \
334     CYG_INTERRUPT_STATE _omsk_ = (CYG_INTERRUPT_STATE)(__oldmask__);        \
335     asm volatile ("move.w   %%sr,%0\n"                                      \
336                   : "=d" (_omsk_)                                           \
337                   : );                                                      \
338     (__oldmask__) = (__typeof__(__oldmask__))_omsk_;                        \
339     CYG_MACRO_END
340 #endif // HAL_QUERY_INTERRUPTS
341
342 // ---------------------------------------------------------------------------
343 // End of hal_intr.h
344 #endif // ifndef CYGONCE_HAL_HAL_INTR_H