comparison packages/hal/sparc/arch/current/include/hal_intr.h @ 208:e0c0827131d1 ecos

Merge from eCos master repository on 2002-05-20-20:11:54-BST
author jlarmour
date Mon, 20 May 2002 22:19:26 +0000
parents
children d2c90368aeef
comparison
equal deleted inserted replaced
207:74c807ddde34 208:e0c0827131d1
1 #ifndef CYGONCE_HAL_INTR_H
2 #define CYGONCE_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, gthomas, hmt
47 // Contributors: nickg, gthomas, hmt,
48 // jlarmour
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.
53 //
54 // Usage:
55 // #include <cyg/hal/hal_intr.h>
56 // ...
57 //
58 //
59 //####DESCRIPTIONEND####
60 //
61 //===========================================================================
62
63 #include <pkgconf/hal.h>
64 #include <pkgconf/hal_sparc.h>
65
66 #include <cyg/infra/cyg_type.h>
67
68 //---------------------------------------------------------------------------
69 // SPARC exception vectors.
70 //
71 // A note on nomenclature:
72 //
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
79 // 16-26) another.
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().
85 //
86 // So:
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.
94
95
96 // These correspond to VSRs and the values are the ones to use for
97 // HAL_VSR_GET/SET
98
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)
115
116 #define CYG_VECTOR_IS_INTERRUPT(v) (15 >= (v))
117
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
128
129 #define CYGNUM_HAL_VECTOR_OTHERS 26 // any others
130
131 #define CYGNUM_HAL_VSR_MIN 0
132 #define CYGNUM_HAL_VSR_MAX 26
133 #define CYGNUM_HAL_VSR_COUNT 27
134
135 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
136
137 // Interrupt vectors. These are the values used with HAL_INTERRUPT_ATTACH()
138 // et al
139
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
156
157 #define CYGNUM_HAL_ISR_MIN 0
158 #define CYGNUM_HAL_ISR_MAX 15
159 #define CYGNUM_HAL_ISR_COUNT 16
160
161 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
162
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
166 // different XSRs.
167
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
182
183
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)
188
189 //---------------------------------------------------------------------------
190 // (Null) Translation from a wider space of interrupt sources:
191
192 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) _index_ = (_vector_)
193
194 //---------------------------------------------------------------------------
195 // Routine to execute DSRs using separate interrupt stack
196
197 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
198
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()
202
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[];
210 // is recommended
211 #endif
212
213 //---------------------------------------------------------------------------
214 // Static data used by HAL
215
216 // VSR table
217 externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
218
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)
225
226 //---------------------------------------------------------------------------
227 // Default ISRs for exception/interrupt handing.
228
229 // note that these have the same ABI apart from the extra SP parameter
230 // for exceptions.
231
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.
234
235 externC void cyg_hal_exception_handler(CYG_ADDRWORD vector,
236 CYG_ADDRWORD data,
237 CYG_ADDRWORD stackpointer);
238
239 //---------------------------------------------------------------------------
240 // Default VSRs for exception/interrupt handing.
241
242 // note that these do not have a C ABI as such; they are *vector* service
243 // routines and are written in assembler.
244
245 externC void hal_default_exception_vsr( void );
246 externC void hal_default_interrupt_vsr( void );
247
248 //---------------------------------------------------------------------------
249 // Interrupt state storage
250
251 typedef cyg_uint32 CYG_INTERRUPT_STATE;
252
253 //---------------------------------------------------------------------------
254 // Interrupt control macros
255
256 // THIS ONE IS NOT A STANDARD HAL ENTRY (HAL_DISABLE_TRAPS)
257 // (so should be unused externally)
258 #define HAL_DISABLE_TRAPS(_old_) \
259 asm volatile ( \
260 "rd %%psr, %0;" \
261 "andn %0, 0x20, %%l7;" \
262 "wr %%l7, %%psr;" \
263 "nop; nop; nop" \
264 : "=r"(_old_) \
265 : \
266 : "l7" \
267 );
268
269 // THIS ONE IS NOT A STANDARD HAL ENTRY (HAL_QUERY_TRAPS)
270 // (so should be unused externally)
271 #define HAL_QUERY_TRAPS(_old_) \
272 asm volatile ( \
273 "rd %%psr, %%l7;" \
274 "and %%l7, 0x020, %0" \
275 : "=r"(_old_) \
276 : \
277 : "l7" \
278 );
279
280 #define HAL_DISABLE_INTERRUPTS(_old_) \
281 asm volatile ( \
282 "rd %%psr, %0;" \
283 "or %0, 0xf00, %%l7;" \
284 "wr %%l7, %%psr;" \
285 "nop; nop; nop" \
286 : "=r"(_old_) \
287 : \
288 : "l7" \
289 );
290
291 #define HAL_ENABLE_INTERRUPTS() \
292 asm volatile ( \
293 "rd %%psr, %%l7;" \
294 "andn %%l7, 0xf00, %%l7;" \
295 "or %%l7, 0x020, %%l7;" \
296 "wr %%l7, %%psr;" \
297 "nop; nop; nop" \
298 : \
299 : \
300 : "l7" \
301 );
302
303 #define HAL_RESTORE_INTERRUPTS(_old_) \
304 asm volatile ( \
305 "rd %%psr, %%l7;" \
306 "andn %%l7, 0xf20, %%l7;" \
307 "and %0 , 0xf20, %%l6;" \
308 "wr %%l6, %%l7, %%psr;" \
309 "nop; nop; nop" \
310 : \
311 : "r"(_old_) \
312 : "l6","l7" \
313 );
314
315 #define HAL_QUERY_INTERRUPTS(_old_) \
316 asm volatile ( \
317 "rd %%psr, %%l7;" \
318 "and %%l7, 0xf00, %%l7;" \
319 "xor %%l7, 0xf00, %0" \
320 : "=r"(_old_) \
321 : \
322 : "l7" \
323 );
324
325
326 //---------------------------------------------------------------------------
327 // Interrupt and VSR attachment macros
328
329 #define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
330 CYG_MACRO_START \
331 cyg_uint32 _index_; \
332 HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
333 \
334 if( (CYG_ADDRESS)hal_default_isr == hal_interrupt_handlers[_vector_] || \
335 (CYG_ADDRESS)cyg_hal_exception_handler == \
336 hal_interrupt_handlers[_vector_] ) { \
337 (_state_) = 0; \
338 } else { \
339 (_state_) = 1; \
340 } \
341 CYG_MACRO_END
342
343 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
344 CYG_MACRO_START \
345 if( (CYG_ADDRESS)hal_default_isr == hal_interrupt_handlers[_vector_] ||\
346 (CYG_ADDRESS)cyg_hal_exception_handler == \
347 hal_interrupt_handlers[_vector_] ) \
348 { \
349 hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)_isr_; \
350 hal_interrupt_data[_vector_] = (CYG_ADDRWORD) _data_; \
351 hal_interrupt_objects[_vector_] = (CYG_ADDRESS)_object_; \
352 } \
353 CYG_MACRO_END
354
355 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) CYG_MACRO_START \
356 if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)_isr_ ) \
357 { \
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; \
364 } \
365 CYG_MACRO_END
366
367 #define HAL_VSR_GET( _vector_, _pvsr_ ) \
368 *(CYG_ADDRESS *)(_pvsr_) = hal_vsr_table[_vector_];
369
370
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_; \
375 CYG_MACRO_END
376
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.
382
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 ); \
389 CYG_MACRO_END
390
391
392
393 //---------------------------------------------------------------------------
394
395 // Which PIC (if any) is available is dependent on the board.
396 // This sets up that stuff:
397
398 #include <cyg/hal/hal_xpic.h>
399
400 // Ditto the clock(s)
401 // This defines all the clock macros the kernel requires:
402
403 #include <cyg/hal/hal_clock.h>
404
405 //---------------------------------------------------------------------------
406 #endif // ifndef CYGONCE_HAL_INTR_H
407 // End of hal_intr.h