1 #ifndef CYGONCE_HAL_HAL_INTR_H
2 #define CYGONCE_HAL_HAL_INTR_H
4 //==========================================================================
8 // HAL Interrupt and clock 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.
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.
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
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.
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.
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.
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####
47 // Contributors: nickg, jskov,
48 // gthomas, jlarmour, msalter
50 // Purpose: Define Interrupt support
51 // Description: The macros defined here provide the HAL APIs for handling
52 // interrupts and the clock.
55 // #include <cyg/hal/hal_intr.h>
59 //####DESCRIPTIONEND####
61 //==========================================================================
63 #include <pkgconf/hal.h>
65 #include <cyg/infra/cyg_type.h>
66 #include <cyg/hal/hal_io.h>
68 #include <cyg/hal/var_intr.h>
70 //--------------------------------------------------------------------------
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
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
87 #define CYGNUM_HAL_VSR_MIN 0
88 #define CYGNUM_HAL_VSR_MAX 8
89 #define CYGNUM_HAL_VSR_COUNT 9
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
95 #define CYGNUM_HAL_EXCEPTION_COUNT \
96 ( CYGNUM_HAL_EXCEPTION_MAX - CYGNUM_HAL_EXCEPTION_MIN + 1 )
99 #ifndef CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
100 #define CYGNUM_HAL_FAST_INTERRUPT 0
101 #define CYGNUM_HAL_INTERRUPT 1
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
108 #define CYGHWR_HAL_INTERRUPT_VECTORS_DEFINED
111 //--------------------------------------------------------------------------
112 // Static data used by HAL
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];
120 externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_MAX+1];
122 //--------------------------------------------------------------------------
124 // The #define is used to test whether this routine exists, and to allow
127 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
129 #define HAL_DEFAULT_ISR hal_default_isr
131 //--------------------------------------------------------------------------
132 // Interrupt state storage
134 typedef cyg_uint32 CYG_INTERRUPT_STATE;
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.
142 #define HAL_DISABLE_INTERRUPTS(_old_)
143 #define HAL_ENABLE_INTERRUPTS()
144 #define HAL_RESTORE_INTERRUPTS(_old_)
145 #define HAL_QUERY_INTERRUPTS( _state_ )
147 //--------------------------------------------------------------------------
148 // Routine to execute DSRs using separate interrupt stack
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()
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[];
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.
170 #ifndef HAL_TRANSLATE_VECTOR
172 #if defined(CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN)
174 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = 0
178 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) (_index_) = (_vector_)
184 //--------------------------------------------------------------------------
185 // Interrupt and VSR attachment macros
187 #define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
189 cyg_uint32 _index_; \
190 HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
192 if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR ) \
198 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
200 cyg_uint32 _index_; \
201 HAL_TRANSLATE_VECTOR( _vector_, _index_ ); \
203 if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR ) \
205 hal_interrupt_handlers[_index_] = (CYG_ADDRESS)_isr_; \
206 hal_interrupt_data[_index_] = (CYG_ADDRWORD)_data_; \
207 hal_interrupt_objects[_index_] = (CYG_ADDRESS)_object_; \
211 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
213 cyg_uint32 _index_; \
214 HAL_TRANSLATE_VECTOR( _vector_, _index_ ); \
216 if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)_isr_ ) \
218 hal_interrupt_handlers[_index_] = (CYG_ADDRESS)HAL_DEFAULT_ISR; \
219 hal_interrupt_data[_index_] = 0; \
220 hal_interrupt_objects[_index_] = 0; \
224 #define HAL_VSR_GET( _vector_, _pvsr_ ) \
225 *(_pvsr_) = (void (*)())hal_vsr_table[_vector_];
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_; \
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.
240 externC void __default_exception_vsr(void);
241 externC void __default_interrupt_vsr(void);
242 externC void __break_vsr_springboard(void);
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, \
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.
261 #ifndef CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
263 #define HAL_INTERRUPT_MASK( _vector_ )
265 #define HAL_INTERRUPT_UNMASK( _vector_ )
267 #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )
269 #define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ )
271 #define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )
273 #define CYGHWR_HAL_INTERRUPT_CONTROLLER_ACCESS_DEFINED
277 //--------------------------------------------------------------------------
279 // This code uses the count and compare registers that are present in many
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.
285 #ifndef CYGHWR_HAL_CLOCK_CONTROL_DEFINED
287 externC CYG_WORD32 cyg_hal_clock_period;
288 #define CYGHWR_HAL_CLOCK_PERIOD_DEFINED
290 #define HAL_CLOCK_INITIALIZE( _period_ )
292 #define HAL_CLOCK_RESET( _vector_, _period_ )
294 #define HAL_CLOCK_READ( _pvalue_ )
296 #define CYGHWR_HAL_CLOCK_CONTROL_DEFINED
300 //--------------------------------------------------------------------------
301 #endif // ifndef CYGONCE_HAL_HAL_INTR_H