1 #ifndef CYGONCE_HAL_HAL_INTR_H
2 #define CYGONCE_HAL_HAL_INTR_H
4 //==========================================================================
8 // ColdFire interrupt/exception support
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.
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.
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
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.
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.
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####
44 // Author(s): Enrico Piria
47 // Purpose: Provide ColdFire-specific interrupt and exception
49 // Usage: #include <cyg/hal/hal_intr.h>
51 //####DESCRIPTIONEND####
52 //========================================================================
54 #include <pkgconf/hal.h>
55 #include <cyg/infra/cyg_type.h>
56 #include <cyg/hal/hal_arch.h>
58 #include <cyg/hal/var_intr.h>
60 #include <cyg/infra/cyg_ass.h> // CYG_FAIL
62 // -------------------------------------------------------------------------
63 // ColdFire exception vectors. These correspond to VSRs and are the values
64 // to use for HAL_VSR_GET/SET.
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
73 // Exception vectors 6-7 are reserved
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
84 // Exception vectors 16-23 are reserved
86 #define CYGNUM_HAL_VECTOR_SPURINT 24
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
97 #define CYGNUM_HAL_VECTOR_TRAPFIRST 32
98 #define CYGNUM_HAL_VECTOR_TRAPLAST 47
99 #define CYGNUM_HAL_NUMTRAPS 16
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
110 // Exception vectors 56-60 are reserved
112 #define CYGNUM_HAL_VECTOR_UNSUPINST 61
114 // Exception vectors 62-63 are reserved
116 #define CYGNUM_HAL_VECTOR_USERINTRFIRST 64
117 #define CYGNUM_HAL_VECTOR_USERINTRLAST 255
118 #define CYGNUM_HAL_NUMUSERINTR 192
120 // -------------------------------------------------------------------------
121 // Interrupt and exception vector table definitions.
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)
127 // To simplify things in interrupt handling code, we don't take into account
128 // autovectored, spurious and uninitialized interrupts.
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)
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)
143 // -------------------------------------------------------------------------
144 // Equivalence between ColdFire exception names and target independent
146 // These are the values used when passed out to an
147 // external exception handler using cyg_hal_deliver_exception().
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
154 // -------------------------------------------------------------------------
155 // Spurious interrupt definition.
157 #ifndef CYGNUM_HAL_SPURIOUS_INTERRUPT
158 #define CYGNUM_HAL_SPURIOUS_INTERRUPT CYGNUM_HAL_VECTOR_SPURINT
161 // -------------------------------------------------------------------------
162 // Static data used by HAL.
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];
170 externC volatile CYG_ADDRESS cyg_hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
173 externC CYG_ADDRESS rom_vsr_table[CYGNUM_HAL_VSR_COUNT];
175 // -------------------------------------------------------------------------
176 // Interrupt stack definitions.
178 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
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()
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.
190 #define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
191 #define HAL_INTERRUPT_STACK_TOP cyg_interrupt_stack
193 externC char HAL_INTERRUPT_STACK_BASE[];
194 externC char HAL_INTERRUPT_STACK_TOP[];
196 // --------------------------------------------------------------------------
197 // Translate a vector number into an ISR table index.
199 #ifndef HAL_TRANSLATE_VECTOR
200 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_- CYGNUM_HAL_ISR_MIN)
203 // -------------------------------------------------------------------------
204 // Interrupt state storage.
206 typedef cyg_uint16 CYG_INTERRUPT_STATE;
208 // --------------------------------------------------------------------------
209 // Interrupt and VSR attachment macros.
211 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
213 externC void hal_default_exception_handler(CYG_WORD vector,
214 HAL_SavedRegisters *regs);
216 #define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
218 cyg_uint32 _index_; \
219 HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
221 if (cyg_hal_interrupt_handlers[_index_] \
222 == (CYG_ADDRESS) &hal_default_isr) \
228 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
230 cyg_uint32 _index_; \
231 HAL_TRANSLATE_VECTOR((_vector_), _index_); \
233 if (cyg_hal_interrupt_handlers[_index_] \
234 == (CYG_ADDRESS) &hal_default_isr) \
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_); \
242 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
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_)) \
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; \
257 #define HAL_VSR_GET( _vector_, _pvsr_ ) \
258 *((CYG_ADDRESS *)(_pvsr_)) = cyg_hal_vsr_table[(_vector_)];
261 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \
263 if( (_poldvsr_) != NULL ) \
264 *(CYG_ADDRESS *)(_poldvsr_) = cyg_hal_vsr_table[(_vector_)]; \
265 cyg_hal_vsr_table[(_vector_)] = (CYG_ADDRESS)(_vsr_); \
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.
275 #define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) \
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_]; \
282 // -------------------------------------------------------------------------
283 // Interrupt control macros.
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.
289 #ifndef HAL_CF_SET_SR
290 #define HAL_CF_SET_SR(__newsr__) \
292 asm volatile ("move.w %0,%%sr\n" \
294 : "d" ((CYG_INTERRUPT_STATE)(__newsr__))); \
296 #endif // HAL_CF_SET_SR
298 #ifndef HAL_ENABLE_INTERRUPTS
299 #define HAL_ENABLE_INTERRUPTS() \
301 CYG_INTERRUPT_STATE _msk_; \
302 HAL_QUERY_INTERRUPTS(_msk_); \
303 HAL_CF_SET_SR((_msk_ & (CYG_INTERRUPT_STATE)0xf8ff)); \
305 #endif // HAL_ENABLE_INTERRUPTS
307 #ifndef HAL_DISABLE_INTERRUPTS
308 #define HAL_DISABLE_INTERRUPTS(_old_) \
310 HAL_QUERY_INTERRUPTS(_old_); \
311 HAL_CF_SET_SR((_old_ | (CYG_INTERRUPT_STATE)0x0700)); \
313 #endif //HAL_DISABLE_INTERRUPTS
315 #ifndef HAL_RESTORE_INTERRUPTS
316 #define HAL_RESTORE_INTERRUPTS(_prev_) \
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" \
327 #endif // HAL_RESTORE_INTERRUPTS
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__) \
334 CYG_INTERRUPT_STATE _omsk_ = (CYG_INTERRUPT_STATE)(__oldmask__); \
335 asm volatile ("move.w %%sr,%0\n" \
338 (__oldmask__) = (__typeof__(__oldmask__))_omsk_; \
340 #endif // HAL_QUERY_INTERRUPTS
342 // ---------------------------------------------------------------------------
344 #endif // ifndef CYGONCE_HAL_HAL_INTR_H