]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/frv/arch/v2_0/include/hal_intr.h
Initial revision
[karo-tx-redboot.git] / packages / hal / frv / 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
47 // Contributors: nickg, gthomas,
48 //               jlarmour
49 // Date:         1999-02-20
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:        #include <cyg/hal/hal_intr.h>
55 //               ...
56 //              
57 //
58 //####DESCRIPTIONEND####
59 //
60 //==========================================================================
61
62 #include <pkgconf/hal.h>
63
64 #include <cyg/infra/cyg_type.h>
65
66 // This is to allow a variant to decide that there is no platform-specific
67 // interrupts file; and that in turn can be overridden by a platform that
68 // refines the variant's ideas.
69 #ifdef    CYGBLD_HAL_PLF_INTS_H
70 # include CYGBLD_HAL_PLF_INTS_H // should include variant data as required
71 #else 
72 # ifdef    CYGBLD_HAL_VAR_INTS_H
73 #  include CYGBLD_HAL_VAR_INTS_H
74 # else
75 #  include <cyg/hal/plf_ints.h> // default less-complex platforms
76 # endif
77 #endif
78
79 // Spurious interrupt (no interrupt source could be found)
80 #define CYGNUM_HAL_INTERRUPT_NONE -1
81
82 //--------------------------------------------------------------------------
83 // FUJITSU exception vectors.
84
85 // The Fujitsu FR-V architecture supports up to 256 interrupt/exceptions.
86 // Each vectors to a specific VSR which is 16 bytes (4 instructions) long.
87
88 // These vectors correspond to VSRs. These values are the ones to use for
89 // HAL_VSR_GET/SET
90
91 #define CYGNUM_HAL_VECTOR_RESET                       0x00
92 #define CYGNUM_HAL_VECTOR_INSTR_ACCESS_MMU_MISS       0x01
93 #define CYGNUM_HAL_VECTOR_INSTR_ACCESS_ERROR          0x02
94 #define CYGNUM_HAL_VECTOR_INSTR_ACCESS_EXCEPTION      0x03
95 #define CYGNUM_HAL_VECTOR_PRIVELEDGED_INSTRUCTION     0x06
96 #define CYGNUM_HAL_VECTOR_ILLEGAL_INSTRUCTION         0x07
97 #define CYGNUM_HAL_VECTOR_REGISTER_EXCEPTION          0x08
98 #define CYGNUM_HAL_VECTOR_FP_DISABLED                 0x0A
99 #define CYGNUM_HAL_VECTOR_MP_DISABLED                 0x0B
100 #define CYGNUM_HAL_VECTOR_FP_EXCEPTION                0x0D
101 #define CYGNUM_HAL_VECTOR_MP_EXCEPTION                0x0E
102 #define CYGNUM_HAL_VECTOR_MEMORY_ADDRESS_NOT_ALIGNED  0x10
103 #define CYGNUM_HAL_VECTOR_DATA_ACCESS_ERROR           0x11
104 #define CYGNUM_HAL_VECTOR_DATA_ACCESS_MMU_MISS        0x12
105 #define CYGNUM_HAL_VECTOR_DATA_ACCESS_EXCEPTION       0x13
106 #define CYGNUM_HAL_VECTOR_DATA_STORE_ERROR            0x14
107 #define CYGNUM_HAL_VECTOR_DIVISION_EXCEPTION          0x17
108 #define CYGNUM_HAL_VECTOR_COMMIT_EXCEPTION            0x19
109 #define CYGNUM_HAL_VECTOR_COMPOUND_EXCEPTION          0x20
110 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1  0x21
111 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_2  0x22
112 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_3  0x23
113 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_4  0x24
114 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_5  0x25
115 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_6  0x26
116 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_7  0x27
117 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_8  0x28
118 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_9  0x29
119 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_10 0x2A
120 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_11 0x2B
121 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_12 0x2C
122 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_13 0x2D
123 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_14 0x2E
124 #define CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15 0x2F
125 #define CYGNUM_HAL_VECTOR_SYSCALL                     0x80  // tira gr0,#0
126 #define CYGNUM_HAL_VECTOR_BREAKPOINT_TRAP             0x81  // tira gr0,#1
127 #define CYGNUM_HAL_VECTOR_BREAKPOINT                  0xFF  // break
128
129 #define CYGNUM_HAL_VSR_MIN                     0
130 #define CYGNUM_HAL_VSR_MAX                   255
131 #define CYGNUM_HAL_VSR_COUNT                 256
132 #define CYGNUM_HAL_ISR_COUNT                 256  // 1-1 mapping
133
134 // Exception vectors. These are the values used when passed out to an
135 // external exception handler using cyg_hal_deliver_exception()
136
137 #define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION \
138           CYGNUM_HAL_VECTOR_ILLEGAL_INSTRUCTION
139 #define CYGNUM_HAL_EXCEPTION_INTERRUPT \
140           CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
141
142 #define CYGNUM_HAL_EXCEPTION_CODE_ACCESS    CYGNUM_HAL_VECTOR_INSTR_ACCESS_ERROR
143 #define CYGNUM_HAL_EXCEPTION_DATA_ACCESS    CYGNUM_HAL_VECTOR_DATA_ACCESS_ERROR
144
145 #define CYGNUM_HAL_EXCEPTION_MIN     CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
146 #define CYGNUM_HAL_EXCEPTION_MAX     CYGNUM_HAL_EXCEPTION_DATA_ACCESS
147 #define CYGNUM_HAL_EXCEPTION_COUNT   (CYGNUM_HAL_EXCEPTION_MAX - \
148                                       CYGNUM_HAL_EXCEPTION_MIN + 1)
149
150 #define CYGNUM_HAL_ISR_MIN CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_1
151 #define CYGNUM_HAL_ISR_MAX CYGNUM_HAL_VECTOR_EXTERNAL_INTERRUPT_LEVEL_15
152
153 //--------------------------------------------------------------------------
154 // Static data used by HAL
155
156 // ISR tables
157 externC CYG_ADDRESS    hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
158 externC CYG_ADDRWORD   hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
159 externC CYG_ADDRESS    hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
160
161 // VSR table
162 externC CYG_ADDRESS    hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
163
164 // Platform setup memory size (0 if unknown by hardware)
165 externC CYG_ADDRWORD   hal_dram_size;
166 // what, if anything, this means, is platform dependent:
167 externC CYG_ADDRWORD   hal_dram_type; 
168
169 #if CYGINT_HAL_FRV_MEM_REAL_REGION_TOP
170
171 externC cyg_uint8 *hal_frv_mem_real_region_top( cyg_uint8 *_regionend_ );
172                                                 
173 # define HAL_MEM_REAL_REGION_TOP( _regionend_ ) \
174     hal_frv_mem_real_region_top( _regionend_ )
175 #endif
176
177 //--------------------------------------------------------------------------
178 // Default ISR
179 // The #define is used to test whether this routine exists, and to allow
180 // code outside the HAL to call it.
181  
182 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
183
184 #define HAL_DEFAULT_ISR hal_default_isr
185
186 //--------------------------------------------------------------------------
187 // Interrupt state storage
188
189 typedef cyg_uint32 CYG_INTERRUPT_STATE;
190
191 //--------------------------------------------------------------------------
192 // Interrupt control macros
193
194 externC cyg_uint32 hal_disable_interrupts(void);
195 externC void       hal_enable_interrupts(void);
196 externC void       hal_restore_interrupts(cyg_uint32);
197 externC cyg_uint32 hal_query_interrupts(void);
198
199 // On this processor, interrupts are controlled by level.  Since eCos
200 // only has the notion of "off" and "on", this will be emulated by
201 // NONE-level and ALL-level.
202 #define HAL_DISABLE_INTERRUPTS(_old_)           \
203 CYG_MACRO_START                                 \
204     register cyg_uint32 reg;                    \
205     asm volatile (                              \
206         "movsg psr,%0\n"                        \
207         "\tsetlos (0x0F<<3),gr5\n"              \
208         "\tor %0,gr5,gr5\n"                     \
209         "\tmovgs gr5,psr\n"                     \
210         : "=r" (reg)                            \
211         :                                       \
212         : "gr5" /* Clobber list */              \
213         );                                      \
214     (_old_) = (reg);                            \
215 CYG_MACRO_END
216
217 #define HAL_ENABLE_INTERRUPTS()                 \
218 CYG_MACRO_START                                 \
219     asm volatile (                              \
220         "movsg psr,gr4\n"                       \
221         "\tsetlos (0x0F<<3),gr5\n"              \
222         "\tnot gr5,gr5\n"                       \
223         "\tand gr4,gr5,gr5\n"                   \
224         "\tmovgs gr5,psr\n"                     \
225         :                                       \
226         :                                       \
227         : "gr4","gr5" /* Clobber list */        \
228         );                                      \
229 CYG_MACRO_END
230
231 // This should work, but breaks compiler
232 #if 0
233 #define HAL_RESTORE_INTERRUPTS(_old_)           \
234 CYG_MACRO_START                                 \
235     asm volatile (                              \
236         "movsg psr,gr4\n"                       \
237         "\tsetlos 1,gr5\n"                      \
238         "\tand %0,gr5,gr5\n"                    \
239         "\tor gr5,gr4,gr4\n"                    \
240         "\tmovgs gr4,psr\n"                     \
241         :                                       \
242         : "g" (_old_)                           \
243         : "gr4","gr5" /* Clobber list */        \
244         );                                      \
245 CYG_MACRO_END
246 #else
247 #define HAL_RESTORE_INTERRUPTS(_old_)           \
248    hal_restore_interrupts(_old_)
249 #endif
250
251 #define HAL_QUERY_INTERRUPTS(_old_)             \
252   _old_ = hal_query_interrupts()
253
254 //--------------------------------------------------------------------------
255 // Routine to execute DSRs using separate interrupt stack
256
257 #ifdef  CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
258 externC void hal_interrupt_stack_call_pending_DSRs(void);
259 #define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
260     hal_interrupt_stack_call_pending_DSRs()
261
262 #if 0 // Interrupt stacks not implemented yet
263 // these are offered solely for stack usage testing
264 // if they are not defined, then there is no interrupt stack.
265 #define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
266 #define HAL_INTERRUPT_STACK_TOP  cyg_interrupt_stack
267 // use them to declare these extern however you want:
268 //       extern char HAL_INTERRUPT_STACK_BASE[];
269 //       extern char HAL_INTERRUPT_STACK_TOP[];
270 // is recommended
271 #endif // 0
272 #endif
273
274 //--------------------------------------------------------------------------
275 // Vector translation.
276
277 #ifndef HAL_TRANSLATE_VECTOR
278 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) \
279     (_index_) = (_vector_)
280 #endif
281
282 //--------------------------------------------------------------------------
283 // Interrupt and VSR attachment macros
284
285 #define HAL_INTERRUPT_IN_USE( _vector_, _state_)                          \
286     CYG_MACRO_START                                                       \
287     cyg_uint32 _index_;                                                   \
288     HAL_TRANSLATE_VECTOR ((_vector_), _index_);                           \
289                                                                           \
290     if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)hal_default_isr ) \
291         (_state_) = 0;                                                    \
292     else                                                                  \
293         (_state_) = 1;                                                    \
294     CYG_MACRO_END
295
296 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ )          \
297     CYG_MACRO_START                                                        \
298     if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)hal_default_isr ) \
299     {                                                                      \
300         hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)_isr_;             \
301         hal_interrupt_data[_vector_] = (CYG_ADDRWORD) _data_;              \
302         hal_interrupt_objects[_vector_] = (CYG_ADDRESS)_object_;           \
303     }                                                                      \
304     CYG_MACRO_END
305
306 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ )                            \
307     CYG_MACRO_START                                                        \
308     if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)_isr_ )           \
309     {                                                                      \
310         hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)hal_default_isr;   \
311         hal_interrupt_data[_vector_] = 0;                                  \
312         hal_interrupt_objects[_vector_] = 0;                               \
313     }                                                                      \
314     CYG_MACRO_END
315
316 #define HAL_VSR_GET( _vector_, _pvsr_ )                         \
317     *(CYG_ADDRESS *)(_pvsr_) = hal_vsr_table[_vector_];
318     
319
320 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ )               \
321     CYG_MACRO_START                                             \
322     if( _poldvsr_ != NULL )                                     \
323         *(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_];    \
324     hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_;               \
325     CYG_MACRO_END
326
327 //--------------------------------------------------------------------------
328 // Interrupt controller access
329
330 externC void hal_interrupt_mask(int);
331 externC void hal_interrupt_unmask(int);
332 externC void hal_interrupt_acknowledge(int);
333 externC void hal_interrupt_configure(int, int, int);
334 externC void hal_interrupt_set_level(int, int);
335
336 #define HAL_INTERRUPT_MASK( _vector_ )                     \
337     hal_interrupt_mask( _vector_ ) 
338 #define HAL_INTERRUPT_UNMASK( _vector_ )                   \
339     hal_interrupt_unmask( _vector_ )
340 #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )              \
341     hal_interrupt_acknowledge( _vector_ )
342 #define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) \
343     hal_interrupt_configure( _vector_, _level_, _up_ )
344 #define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )       \
345     hal_interrupt_set_level( _vector_, _level_ )
346
347 //--------------------------------------------------------------------------
348 // Clock control
349
350 externC void hal_clock_initialize(cyg_uint32);
351 externC void hal_clock_read(cyg_uint32 *);
352 externC void hal_clock_reset(cyg_uint32, cyg_uint32);
353
354 #define HAL_CLOCK_INITIALIZE( _period_ )   hal_clock_initialize( _period_ )
355 #define HAL_CLOCK_RESET( _vec_, _period_ ) hal_clock_reset( _vec_, _period_ )
356 #define HAL_CLOCK_READ( _pvalue_ )         hal_clock_read( _pvalue_ )
357 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY
358 # ifndef HAL_CLOCK_LATENCY
359 #  define HAL_CLOCK_LATENCY( _pvalue_ )    HAL_CLOCK_READ( (cyg_uint32 *)_pvalue_ )
360 # endif
361 #endif
362
363 //--------------------------------------------------------------------------
364 #endif // ifndef CYGONCE_HAL_INTR_H
365 // End of hal_intr.h