]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/sparc/arch/v2_0/include/hal_intr.h
Initial revision
[karo-tx-redboot.git] / packages / hal / sparc / arch / v2_0 / include / hal_intr.h
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