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
47 // Contributors: nickg, gthomas,
50 // Purpose: Define Interrupt support
51 // Description: The macros defined here provide the HAL APIs for handling
52 // interrupts and the clock.
54 // Usage: #include <cyg/hal/hal_intr.h>
58 //####DESCRIPTIONEND####
60 //==========================================================================
62 #include <pkgconf/hal.h>
64 #include <cyg/infra/cyg_type.h>
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
72 # ifdef CYGBLD_HAL_VAR_INTS_H
73 # include CYGBLD_HAL_VAR_INTS_H
75 # include <cyg/hal/plf_ints.h> // default less-complex platforms
79 // Spurious interrupt (no interrupt source could be found)
80 #define CYGNUM_HAL_INTERRUPT_NONE -1
82 //--------------------------------------------------------------------------
83 // FUJITSU exception vectors.
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.
88 // These vectors correspond to VSRs. These values are the ones to use for
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
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
134 // Exception vectors. These are the values used when passed out to an
135 // external exception handler using cyg_hal_deliver_exception()
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
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
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)
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
153 //--------------------------------------------------------------------------
154 // Static data used by HAL
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];
162 externC CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT];
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;
169 #if CYGINT_HAL_FRV_MEM_REAL_REGION_TOP
171 externC cyg_uint8 *hal_frv_mem_real_region_top( cyg_uint8 *_regionend_ );
173 # define HAL_MEM_REAL_REGION_TOP( _regionend_ ) \
174 hal_frv_mem_real_region_top( _regionend_ )
177 //--------------------------------------------------------------------------
179 // The #define is used to test whether this routine exists, and to allow
180 // code outside the HAL to call it.
182 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data);
184 #define HAL_DEFAULT_ISR hal_default_isr
186 //--------------------------------------------------------------------------
187 // Interrupt state storage
189 typedef cyg_uint32 CYG_INTERRUPT_STATE;
191 //--------------------------------------------------------------------------
192 // Interrupt control macros
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);
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_) \
204 register cyg_uint32 reg; \
207 "\tsetlos (0x0F<<3),gr5\n" \
208 "\tor %0,gr5,gr5\n" \
209 "\tmovgs gr5,psr\n" \
212 : "gr5" /* Clobber list */ \
217 #define HAL_ENABLE_INTERRUPTS() \
221 "\tsetlos (0x0F<<3),gr5\n" \
223 "\tand gr4,gr5,gr5\n" \
224 "\tmovgs gr5,psr\n" \
227 : "gr4","gr5" /* Clobber list */ \
231 // This should work, but breaks compiler
233 #define HAL_RESTORE_INTERRUPTS(_old_) \
238 "\tand %0,gr5,gr5\n" \
239 "\tor gr5,gr4,gr4\n" \
240 "\tmovgs gr4,psr\n" \
243 : "gr4","gr5" /* Clobber list */ \
247 #define HAL_RESTORE_INTERRUPTS(_old_) \
248 hal_restore_interrupts(_old_)
251 #define HAL_QUERY_INTERRUPTS(_old_) \
252 _old_ = hal_query_interrupts()
254 //--------------------------------------------------------------------------
255 // Routine to execute DSRs using separate interrupt stack
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()
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[];
274 //--------------------------------------------------------------------------
275 // Vector translation.
277 #ifndef HAL_TRANSLATE_VECTOR
278 #define HAL_TRANSLATE_VECTOR(_vector_,_index_) \
279 (_index_) = (_vector_)
282 //--------------------------------------------------------------------------
283 // Interrupt and VSR attachment macros
285 #define HAL_INTERRUPT_IN_USE( _vector_, _state_) \
287 cyg_uint32 _index_; \
288 HAL_TRANSLATE_VECTOR ((_vector_), _index_); \
290 if( hal_interrupt_handlers[_index_] == (CYG_ADDRESS)hal_default_isr ) \
296 #define HAL_INTERRUPT_ATTACH( _vector_, _isr_, _data_, _object_ ) \
298 if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)hal_default_isr ) \
300 hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)_isr_; \
301 hal_interrupt_data[_vector_] = (CYG_ADDRWORD) _data_; \
302 hal_interrupt_objects[_vector_] = (CYG_ADDRESS)_object_; \
306 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \
308 if( hal_interrupt_handlers[_vector_] == (CYG_ADDRESS)_isr_ ) \
310 hal_interrupt_handlers[_vector_] = (CYG_ADDRESS)hal_default_isr; \
311 hal_interrupt_data[_vector_] = 0; \
312 hal_interrupt_objects[_vector_] = 0; \
316 #define HAL_VSR_GET( _vector_, _pvsr_ ) \
317 *(CYG_ADDRESS *)(_pvsr_) = hal_vsr_table[_vector_];
320 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \
322 if( _poldvsr_ != NULL ) \
323 *(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \
324 hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_; \
327 //--------------------------------------------------------------------------
328 // Interrupt controller access
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);
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_ )
347 //--------------------------------------------------------------------------
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);
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_ )
363 //--------------------------------------------------------------------------
364 #endif // ifndef CYGONCE_HAL_INTR_H