1 #ifndef CYGONCE_HAL_INTR_H
2 #define CYGONCE_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####
46 // Author(s): nickg, gthomas, hmt
47 // Contributors: nickg, gthomas, hmt,
49 // Date: 1999-02-20, 2002-03-08
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>
64 #include <pkgconf/hal_sparc.h>
66 #include <cyg/infra/cyg_type.h>
68 //---------------------------------------------------------------------------
69 // SPARC exception vectors.
71 // A note on nomenclature:
73 // SPARC has traps: interrupts are traps, and so are exceptions.
74 // There are 255 of them in the hardware: this HAL's trampoline code decodes
75 // them into the 27 listed below as CYGNUM_HAL_VECTOR_xxx.
76 // They are handled uniformly in the trampoline code in the sense that
77 // each vector has a VSR which is called in the same way.
78 // Interrupts (vectors 1-15) have one VSR by default, exceptions (vectors
80 // The interrupt VSR sets up a C stack and calls the corresponding ISR with
81 // the required arguments; this ABI is mandated by the kernel.
82 // The exception VSR sets up a C stack and calls the corresponding XSR
83 // (just an entry in the ISR[sic] table) with similar arguments, such that
84 // it (by default) can call the kernel's cyg_hal_deliver_exception().
87 // CYGNUM_HAL_VSR_MAX/MIN/COUNT describe the number of VSR entries *and*
88 // the number of ISR (and associated data) entries (including those which
89 // are XSRs, just a special case of ISRs).
90 // CYGNUM_HAL_ISR_MAX/MIN/COUNT describe the number of interrupt sources
91 // and is used for bounds checking in kernel interrupt objects.
92 // CYGNUM_HAL_EXCEPTION_MAX/MIN/COUNT describe vector numbers which have
93 // by default the exception VSR and default XSR installed.
96 // These correspond to VSRs and the values are the ones to use for
99 #define CYGNUM_HAL_VECTOR_RESERVED_0 0
100 #define CYGNUM_HAL_VECTOR_INTERRUPT_1 1 // NB: least important
101 #define CYGNUM_HAL_VECTOR_INTERRUPT_2 2 // (lowest priority)
102 #define CYGNUM_HAL_VECTOR_INTERRUPT_3 3
103 #define CYGNUM_HAL_VECTOR_INTERRUPT_4 4
104 #define CYGNUM_HAL_VECTOR_INTERRUPT_5 5
105 #define CYGNUM_HAL_VECTOR_INTERRUPT_6 6
106 #define CYGNUM_HAL_VECTOR_INTERRUPT_7 7
107 #define CYGNUM_HAL_VECTOR_INTERRUPT_8 8
108 #define CYGNUM_HAL_VECTOR_INTERRUPT_9 9
109 #define CYGNUM_HAL_VECTOR_INTERRUPT_10 10
110 #define CYGNUM_HAL_VECTOR_INTERRUPT_11 11
111 #define CYGNUM_HAL_VECTOR_INTERRUPT_12 12
112 #define CYGNUM_HAL_VECTOR_INTERRUPT_13 13
113 #define CYGNUM_HAL_VECTOR_INTERRUPT_14 14 // (highest priority)
114 #define CYGNUM_HAL_VECTOR_INTERRUPT_15 15 // NB: most important (NMI)
116 #define CYG_VECTOR_IS_INTERRUPT(v) (15 >= (v))
118 #define CYGNUM_HAL_VECTOR_USER_TRAP 16 // Ticc instructions
119 #define CYGNUM_HAL_VECTOR_FETCH_ABORT 17 // trap type 1
120 #define CYGNUM_HAL_VECTOR_ILLEGAL_OP 18 // trap type 2
121 #define CYGNUM_HAL_VECTOR_PRIV_OP 19 // tt 3: privileged op
122 #define CYGNUM_HAL_VECTOR_NOFPCP 20 // tt 4,36: FP or coproc
123 #define CYGNUM_HAL_VECTOR_RESERVED_1 21 // (not used)
124 #define CYGNUM_HAL_VECTOR_RESERVED_2 22 // (not used)
125 #define CYGNUM_HAL_VECTOR_UNALIGNED 23 // tt 7: unaligned memory access
126 #define CYGNUM_HAL_VECTOR_TT_EIGHT 24 // tt 8: not defined
127 #define CYGNUM_HAL_VECTOR_DATA_ABORT 25 // tt 9: read/write failed
129 #define CYGNUM_HAL_VECTOR_OTHERS 26 // any others
131 #define CYGNUM_HAL_VSR_MIN 0
132 #define CYGNUM_HAL_VSR_MAX 26
133 #define CYGNUM_HAL_VSR_COUNT 27
135 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
137 // Interrupt vectors. These are the values used with HAL_INTERRUPT_ATTACH()
140 #define CYGNUM_HAL_INTERRUPT_RESERVED_0 CYGNUM_HAL_VECTOR_RESERVED_0
141 #define CYGNUM_HAL_INTERRUPT_1 CYGNUM_HAL_VECTOR_INTERRUPT_1
142 #define CYGNUM_HAL_INTERRUPT_2 CYGNUM_HAL_VECTOR_INTERRUPT_2
143 #define CYGNUM_HAL_INTERRUPT_3 CYGNUM_HAL_VECTOR_INTERRUPT_3
144 #define CYGNUM_HAL_INTERRUPT_4 CYGNUM_HAL_VECTOR_INTERRUPT_4
145 #define CYGNUM_HAL_INTERRUPT_5 CYGNUM_HAL_VECTOR_INTERRUPT_5
146 #define CYGNUM_HAL_INTERRUPT_6 CYGNUM_HAL_VECTOR_INTERRUPT_6
147 #define CYGNUM_HAL_INTERRUPT_7 CYGNUM_HAL_VECTOR_INTERRUPT_7
148 #define CYGNUM_HAL_INTERRUPT_8 CYGNUM_HAL_VECTOR_INTERRUPT_8
149 #define CYGNUM_HAL_INTERRUPT_9 CYGNUM_HAL_VECTOR_INTERRUPT_9
150 #define CYGNUM_HAL_INTERRUPT_10 CYGNUM_HAL_VECTOR_INTERRUPT_10
151 #define CYGNUM_HAL_INTERRUPT_11 CYGNUM_HAL_VECTOR_INTERRUPT_11
152 #define CYGNUM_HAL_INTERRUPT_12 CYGNUM_HAL_VECTOR_INTERRUPT_12
153 #define CYGNUM_HAL_INTERRUPT_13 CYGNUM_HAL_VECTOR_INTERRUPT_13
154 #define CYGNUM_HAL_INTERRUPT_14 CYGNUM_HAL_VECTOR_INTERRUPT_14
155 #define CYGNUM_HAL_INTERRUPT_15 CYGNUM_HAL_VECTOR_INTERRUPT_15
157 #define CYGNUM_HAL_ISR_MIN 0
158 #define CYGNUM_HAL_ISR_MAX 15
159 #define CYGNUM_HAL_ISR_COUNT 16
161 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
163 // Exception vectors. These are the values used when passed out to an
164 // external exception handler using cyg_hal_deliver_exception()
165 // They can also be used with HAL_INTERRUPT_ATTACH() et al to install
168 #define CYGNUM_HAL_EXCEPTION_TRAP CYGNUM_HAL_VECTOR_USER_TRAP
169 #define CYGNUM_HAL_EXCEPTION_CODE_ACCESS CYGNUM_HAL_VECTOR_FETCH_ABORT
170 #define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION \
171 CYGNUM_HAL_VECTOR_ILLEGAL_OP
172 #define CYGNUM_HAL_EXCEPTION_PRIVILEGED_INSTRUCTION \
173 CYGNUM_HAL_VECTOR_PRIV_OP
174 #define CYGNUM_HAL_EXCEPTION_FPU_NOT_AVAIL CYGNUM_HAL_VECTOR_NOFPCP
175 #define CYGNUM_HAL_EXCEPTION_RESERVED1 CYGNUM_HAL_VECTOR_RESERVED1
176 #define CYGNUM_HAL_EXCEPTION_RESERVED2 CYGNUM_HAL_VECTOR_RESERVED2
177 #define CYGNUM_HAL_EXCEPTION_DATA_UNALIGNED_ACCESS \
178 CYGNUM_HAL_VECTOR_UNALIGNED
179 #define CYGNUM_HAL_EXCEPTION_TT_EIGHT CYGNUM_HAL_VECTOR_TT_EIGHT
180 #define CYGNUM_HAL_EXCEPTION_DATA_ACCESS CYGNUM_HAL_VECTOR_DATA_ABORT
181 #define CYGNUM_HAL_EXCEPTION_OTHERS CYGNUM_HAL_VECTOR_OTHERS
184 #define CYGNUM_HAL_EXCEPTION_MIN 16
185 #define CYGNUM_HAL_EXCEPTION_MAX (16 + 10)
186 #define CYGNUM_HAL_EXCEPTION_COUNT (1 + CYGNUM_HAL_EXCEPTION_MAX - \
187 CYGNUM_HAL_EXCEPTION_MIN)
189 //---------------------------------------------------------------------------
190 // (Null) Translation from a wider space of interrupt sources:
192 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) _index_ = (_vector_)
194 //---------------------------------------------------------------------------
195 // Routine to execute DSRs using separate interrupt stack
197 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
199 externC void hal_interrupt_stack_call_pending_DSRs(void);
200 #define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
201 hal_interrupt_stack_call_pending_DSRs()
203 // these are offered solely for stack usage testing
204 // if they are not defined, then there is no interrupt stack.
205 #define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
206 #define HAL_INTERRUPT_STACK_TOP cyg_interrupt_stack
207 // use them to declare these extern however you want:
208 // extern char HAL_INTERRUPT_STACK_BASE[];
209 // extern char HAL_INTERRUPT_STACK_TOP[];
213 //---------------------------------------------------------------------------
214 // Static data used by HAL
217 externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
219 // ISR + XSR tables - so VSR count.
220 externC volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_VSR_COUNT];
221 externC volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_VSR_COUNT];
222 externC volatile CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_VSR_COUNT];
223 // (interrupt_objects only used in the interrupt case _but_ the interrupt
224 // attach &co macros write it, so keep it full-sized)
226 //---------------------------------------------------------------------------
227 // Default ISRs for exception/interrupt handing.
229 // note that these have the same ABI apart from the extra SP parameter
232 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
233 // return code from ISR is passed to interrupt_end() in the kernel.
235 externC void cyg_hal_exception_handler(CYG_ADDRWORD vector,
237 CYG_ADDRWORD stackpointer);
239 //---------------------------------------------------------------------------
240 // Default VSRs for exception/interrupt handing.
242 // note that these do not have a C ABI as such; they are *vector* service
243 // routines and are written in assembler.
245 externC void hal_default_exception_vsr( void );
246 externC void hal_default_interrupt_vsr( void );
248 //---------------------------------------------------------------------------
249 // Interrupt state storage
251 typedef cyg_uint32 CYG_INTERRUPT_STATE;
253 //---------------------------------------------------------------------------
254 // Interrupt control macros
256 // THIS ONE IS NOT A STANDARD HAL ENTRY (HAL_DISABLE_TRAPS)
257 // (so should be unused externally)
258 #define HAL_DISABLE_TRAPS(_old_) \
261 "andn %0, 0x20, %%l7;" \
269 // THIS ONE IS NOT A STANDARD HAL ENTRY (HAL_QUERY_TRAPS)
270 // (so should be unused externally)
271 #define HAL_QUERY_TRAPS(_old_) \
274 "and %%l7, 0x020, %0" \
280 #define HAL_DISABLE_INTERRUPTS(_old_) \
283 "or %0, 0xf00, %%l7;" \
291 #define HAL_ENABLE_INTERRUPTS() \
294 "andn %%l7, 0xf00, %%l7;" \
295 "or %%l7, 0x020, %%l7;" \
303 #define HAL_RESTORE_INTERRUPTS(_old_) \
306 "andn %%l7, 0xf20, %%l7;" \
307 "and %0 , 0xf20, %%l6;" \
308 "wr %%l6, %%l7, %%psr;" \
315 #define HAL_QUERY_INTERRUPTS(_old_) \
318 "and %%l7, 0xf00, %%l7;" \
319 "xor %%l7, 0xf00, %0" \
326 //---------------------------------------------------------------------------
327 // Interrupt and VSR attachment macros
329 #define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
331 cyg_uint32 _index_; \
332 HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
334 if( (CYG_ADDRESS)hal_default_isr == hal_interrupt_handlers[_vector_] || \
335 (CYG_ADDRESS)cyg_hal_exception_handler == \
336 hal_interrupt_handlers[_vector_] ) { \
343 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
345 if( (CYG_ADDRESS)hal_default_isr == hal_interrupt_handlers[_vector_] ||\
346 (CYG_ADDRESS)cyg_hal_exception_handler == \
347 hal_interrupt_handlers[_vector_] ) \
349 hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)_isr_; \
350 hal_interrupt_data[_vector_] = (CYG_ADDRWORD) _data_; \
351 hal_interrupt_objects[_vector_] = (CYG_ADDRESS)_object_; \
355 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) CYG_MACRO_START \
356 if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)_isr_ ) \
358 hal_interrupt_handlers[_vector_] = \
359 (CYG_VECTOR_IS_INTERRUPT( _vector_ ) \
360 ? (CYG_ADDRESS)hal_default_isr \
361 : (CYG_ADDRESS)cyg_hal_exception_handler); \
362 hal_interrupt_data[_vector_] = 0; \
363 hal_interrupt_objects[_vector_] = 0; \
367 #define HAL_VSR_GET( _vector_, _pvsr_ ) \
368 *(CYG_ADDRESS *)(_pvsr_) = hal_vsr_table[_vector_];
371 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) CYG_MACRO_START \
372 if( _poldvsr_ != NULL ) \
373 *(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \
374 hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_; \
377 // This is an ugly name, but what it means is: grab the VSR back to eCos
378 // internal handling, or if you like, the default handler. But if
379 // cooperating with GDB and CygMon, the default behaviour is to pass most
380 // exceptions to CygMon. This macro undoes that so that eCos handles the
381 // exception. So use it with care.
383 #define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) CYG_MACRO_START \
384 if( _poldvsr_ != NULL ) \
385 *(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \
386 hal_vsr_table[_vector_] = ( CYG_VECTOR_IS_INTERRUPT( _vector_ ) \
387 ? (CYG_ADDRESS)hal_default_interrupt_vsr \
388 : (CYG_ADDRESS)hal_default_exception_vsr ); \
393 //---------------------------------------------------------------------------
395 // Which PIC (if any) is available is dependent on the board.
396 // This sets up that stuff:
398 #include <cyg/hal/hal_xpic.h>
400 // Ditto the clock(s)
401 // This defines all the clock macros the kernel requires:
403 #include <cyg/hal/hal_clock.h>
405 //---------------------------------------------------------------------------
406 #endif // ifndef CYGONCE_HAL_INTR_H