]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/arch/v2_0/include/hal_intr.h
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / 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/hal_platform_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 // ARM exception vectors.
84
85 // These vectors correspond to VSRs. These values are the ones to use for
86 // HAL_VSR_GET/SET
87
88 #define CYGNUM_HAL_VECTOR_RESET                0
89 #define CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION    1
90 #define CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT   2
91 #define CYGNUM_HAL_VECTOR_ABORT_PREFETCH       3
92 #define CYGNUM_HAL_VECTOR_ABORT_DATA           4
93 #define CYGNUM_HAL_VECTOR_reserved             5
94 #define CYGNUM_HAL_VECTOR_IRQ                  6
95 #define CYGNUM_HAL_VECTOR_FIQ                  7
96
97 #define CYGNUM_HAL_VSR_MIN                     0
98 #define CYGNUM_HAL_VSR_MAX                     7
99 #define CYGNUM_HAL_VSR_COUNT                   8
100
101 // Exception vectors. These are the values used when passed out to an
102 // external exception handler using cyg_hal_deliver_exception()
103
104 #define CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION \
105           CYGNUM_HAL_VECTOR_UNDEF_INSTRUCTION
106 #define CYGNUM_HAL_EXCEPTION_INTERRUPT \
107           CYGNUM_HAL_VECTOR_SOFTWARE_INTERRUPT
108 #define CYGNUM_HAL_EXCEPTION_CODE_ACCESS    CYGNUM_HAL_VECTOR_ABORT_PREFETCH
109 #define CYGNUM_HAL_EXCEPTION_DATA_ACCESS    CYGNUM_HAL_VECTOR_ABORT_DATA
110
111 #define CYGNUM_HAL_EXCEPTION_MIN     CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION
112 #define CYGNUM_HAL_EXCEPTION_MAX     CYGNUM_HAL_EXCEPTION_DATA_ACCESS
113 #define CYGNUM_HAL_EXCEPTION_COUNT   (CYGNUM_HAL_EXCEPTION_MAX - \
114                                       CYGNUM_HAL_EXCEPTION_MIN + 1)
115
116 //--------------------------------------------------------------------------
117 // Static data used by HAL
118
119 // ISR tables
120 externC CYG_ADDRESS    hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT];
121 externC CYG_ADDRWORD   hal_interrupt_data[CYGNUM_HAL_ISR_COUNT];
122 externC CYG_ADDRESS    hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT];
123
124 // VSR table
125 externC CYG_ADDRESS    hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
126
127 // Platform setup memory size (0 if unknown by hardware)
128 externC CYG_ADDRWORD   hal_dram_size;
129 // what, if anything, this means, is platform dependent:
130 externC CYG_ADDRWORD   hal_dram_type; 
131
132 #if CYGINT_HAL_ARM_MEM_REAL_REGION_TOP
133
134 externC cyg_uint8 *hal_arm_mem_real_region_top( cyg_uint8 *_regionend_ );
135                                                 
136 # define HAL_MEM_REAL_REGION_TOP( _regionend_ ) \
137     hal_arm_mem_real_region_top( _regionend_ )
138 #endif
139
140 //--------------------------------------------------------------------------
141 // Default ISR
142 // The #define is used to test whether this routine exists, and to allow
143 // code outside the HAL to call it.
144  
145 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
146
147 #define HAL_DEFAULT_ISR hal_default_isr
148
149 //--------------------------------------------------------------------------
150 // Interrupt state storage
151
152 typedef cyg_uint32 CYG_INTERRUPT_STATE;
153
154 //--------------------------------------------------------------------------
155 // Interrupt control macros
156
157 #ifndef __thumb__
158 // Note: This disables both FIQ and IRQ interrupts!
159 #define HAL_DISABLE_INTERRUPTS(_old_)           \
160     asm volatile (                              \
161         "mrs %0,cpsr;"                          \
162         "mrs r4,cpsr;"                          \
163         "orr r4,r4,#0xC0;"                      \
164         "msr cpsr,r4"                           \
165         : "=r"(_old_)                           \
166         :                                       \
167         : "r4"                                  \
168         );
169
170 #define HAL_ENABLE_INTERRUPTS()                 \
171     asm volatile (                              \
172         "mrs r3,cpsr;"                          \
173         "bic r3,r3,#0xC0;"                      \
174         "msr cpsr,r3"                           \
175         :                                       \
176         :                                       \
177         : "r3"                                  \
178         );
179
180 #define HAL_RESTORE_INTERRUPTS(_old_)           \
181     asm volatile (                              \
182         "mrs r3,cpsr;"                          \
183         "and r4,%0,#0xC0;"                      \
184         "bic r3,r3,#0xC0;"                      \
185         "orr r3,r3,r4;"                         \
186         "msr cpsr,r3"                           \
187         :                                       \
188         : "r"(_old_)                            \
189         : "r3", "r4"                            \
190         );
191
192 #define HAL_QUERY_INTERRUPTS(_old_)             \
193     asm volatile (                              \
194         "mrs r4,cpsr;"                          \
195         "and r4,r4,#0xC0;"                      \
196         "eor %0,r4,#0xC0;"                      \
197         : "=r"(_old_)                           \
198         :                                       \
199         : "r4"                                  \
200         );
201 #else // __thumb__
202
203 // Thumb mode does not have access to the PSR registers;  
204
205 #if 0 // These don't seem to always work
206 #define HAL_DISABLE_INTERRUPTS(_old_)                   \
207     asm volatile (                                      \
208         "ldr r4,=10f;"                                  \
209         "bx r4;"                                        \
210         ".code 32;"                                     \
211         "10:;"                                          \
212         "mrs %0,cpsr;"                                  \
213         "mrs r4,cpsr;"                                  \
214         "orr r4,r4,#0xC0;"                              \
215         "msr cpsr,r4;"                                  \
216         "ldr r4,=10f+1;"                                \
217         "bx  r4;"                                       \
218         ".code 16;"                                     \
219         "10:;"                                          \
220         : "=r"(_old_)                                   \
221         :                                               \
222         : "r4"                                          \
223         );
224
225 #define HAL_ENABLE_INTERRUPTS()                         \
226     asm volatile (                                      \
227         "ldr r3,=10f;"                                  \
228         "bx r3;"                                        \
229         ".code 32;"                                     \
230         "10:;"                                          \
231         "mrs r3,cpsr;"                                  \
232         "bic r3,r3,#0xC0;"                              \
233         "msr cpsr,r3;"                                  \
234         "ldr r3,=10f+1;"                                \
235         "bx  r3;"                                       \
236         ".code 16;"                                     \
237         "10:;"                                          \
238         :                                               \
239         :                                               \
240         : "r3"                                          \
241         );
242
243 #define HAL_RESTORE_INTERRUPTS(_old_)                   \
244     asm volatile (                                      \
245         "ldr r3,=10f;"                                  \
246         "bx r3;"                                        \
247         ".code 32;"                                     \
248         "10:;"                                          \
249         "mrs r3,cpsr;"                                  \
250         "and r4,%0,#0xC0;"                              \
251         "bic r3,r3,#0xC0;"                              \
252         "orr r3,r3,r4;"                                 \
253         "msr cpsr,r3;"                                  \
254         "ldr r3,=10f+1;"                                \
255         "bx  r3;"                                       \
256         ".code 16;"                                     \
257         "10:;"                                          \
258         :                                               \
259         : "r"(_old_)                                    \
260         : "r3", "r4"                                    \
261         );
262
263 #define HAL_QUERY_INTERRUPTS(_old_)                     \
264     asm volatile (                                      \
265         "ldr r4,=10f;"                                  \
266         "bx r4;"                                        \
267         ".code 32;"                                     \
268         "10:;"                                          \
269         "mrs r4,cpsr;"                                  \
270         "and r4,r4,#0xC0;"                              \
271         "eor %0,r4,#0xC0;"                              \
272         "ldr r4,=10f+1;"                                \
273         "bx  r4;"                                       \
274         ".code 16;"                                     \
275         "10:;"                                          \
276         : "=r"(_old_)                                   \
277         :                                               \
278         : "r4"                                          \
279         );
280 #else
281
282 externC cyg_uint32 hal_disable_interrupts(void);
283 externC void       hal_enable_interrupts(void);
284 externC void       hal_restore_interrupts(cyg_uint32);
285 externC cyg_uint32 hal_query_interrupts(void);
286
287 #define HAL_DISABLE_INTERRUPTS(_old_)                   \
288     _old_ = hal_disable_interrupts();
289
290 #define HAL_ENABLE_INTERRUPTS()                         \
291     hal_enable_interrupts();
292
293 #define HAL_RESTORE_INTERRUPTS(_old_)                   \
294     hal_restore_interrupts(_old_);
295
296 #define HAL_QUERY_INTERRUPTS(_old_)                     \
297     _old_ = hal_query_interrupts();
298 #endif
299
300 #endif // __thumb__
301
302 //--------------------------------------------------------------------------
303 // Routine to execute DSRs using separate interrupt stack
304
305 #ifdef  CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK
306 externC void hal_interrupt_stack_call_pending_DSRs(void);
307 #define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \
308     hal_interrupt_stack_call_pending_DSRs()
309
310 // these are offered solely for stack usage testing
311 // if they are not defined, then there is no interrupt stack.
312 #define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base
313 #define HAL_INTERRUPT_STACK_TOP  cyg_interrupt_stack
314 // use them to declare these extern however you want:
315 //       extern char HAL_INTERRUPT_STACK_BASE[];
316 //       extern char HAL_INTERRUPT_STACK_TOP[];
317 // is recommended
318 #endif
319
320 //--------------------------------------------------------------------------
321 // Vector translation.
322
323 #ifndef HAL_TRANSLATE_VECTOR
324 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) \
325     (_index_) = (_vector_)
326 #endif
327
328 //--------------------------------------------------------------------------
329 // Interrupt and VSR attachment macros
330
331 #define HAL_INTERRUPT_IN_USE( _vector_, _state_)                          \
332     CYG_MACRO_START                                                       \
333     cyg_uint32 _index_;                                                   \
334     HAL_TRANSLATE_VECTOR ((_vector_), _index_);                           \
335                                                                           \
336     if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)hal_default_isr ) \
337         (_state_) = 0;                                                    \
338     else                                                                  \
339         (_state_) = 1;                                                    \
340     CYG_MACRO_END
341
342 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ )          \
343     CYG_MACRO_START                                                        \
344     if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)hal_default_isr ) \
345     {                                                                      \
346         hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)_isr_;             \
347         hal_interrupt_data[_vector_] = (CYG_ADDRWORD) _data_;              \
348         hal_interrupt_objects[_vector_] = (CYG_ADDRESS)_object_;           \
349     }                                                                      \
350     CYG_MACRO_END
351
352 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ )                            \
353     CYG_MACRO_START                                                        \
354     if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)_isr_ )           \
355     {                                                                      \
356         hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)hal_default_isr;   \
357         hal_interrupt_data[_vector_] = 0;                                  \
358         hal_interrupt_objects[_vector_] = 0;                               \
359     }                                                                      \
360     CYG_MACRO_END
361
362 #define HAL_VSR_GET( _vector_, _pvsr_ )                         \
363     *(CYG_ADDRESS *)(_pvsr_) = hal_vsr_table[_vector_];
364     
365
366 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ )               \
367     CYG_MACRO_START                                             \
368     if( _poldvsr_ != NULL )                                     \
369         *(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_];    \
370     hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_;               \
371     CYG_MACRO_END
372
373 //--------------------------------------------------------------------------
374 // Interrupt controller access
375
376 externC void hal_interrupt_mask(int);
377 externC void hal_interrupt_unmask(int);
378 externC void hal_interrupt_acknowledge(int);
379 externC void hal_interrupt_configure(int, int, int);
380 externC void hal_interrupt_set_level(int, int);
381
382 #define HAL_INTERRUPT_MASK( _vector_ )                     \
383     hal_interrupt_mask( _vector_ ) 
384 #define HAL_INTERRUPT_UNMASK( _vector_ )                   \
385     hal_interrupt_unmask( _vector_ )
386 #define HAL_INTERRUPT_ACKNOWLEDGE( _vector_ )              \
387     hal_interrupt_acknowledge( _vector_ )
388 #define HAL_INTERRUPT_CONFIGURE( _vector_, _level_, _up_ ) \
389     hal_interrupt_configure( _vector_, _level_, _up_ )
390 #define HAL_INTERRUPT_SET_LEVEL( _vector_, _level_ )       \
391     hal_interrupt_set_level( _vector_, _level_ )
392
393 //--------------------------------------------------------------------------
394 // Clock control
395
396 externC void hal_clock_initialize(cyg_uint32);
397 externC void hal_clock_read(cyg_uint32 *);
398 externC void hal_clock_reset(cyg_uint32, cyg_uint32);
399
400 #define HAL_CLOCK_INITIALIZE( _period_ )   hal_clock_initialize( _period_ )
401 #define HAL_CLOCK_RESET( _vec_, _period_ ) hal_clock_reset( _vec_, _period_ )
402 #define HAL_CLOCK_READ( _pvalue_ )         hal_clock_read( _pvalue_ )
403 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK_LATENCY
404 # ifndef HAL_CLOCK_LATENCY
405 #  define HAL_CLOCK_LATENCY( _pvalue_ )    HAL_CLOCK_READ( (cyg_uint32 *)_pvalue_ )
406 # endif
407 #endif
408
409 //--------------------------------------------------------------------------
410 #endif // ifndef CYGONCE_HAL_INTR_H
411 // End of hal_intr.h