00001 #ifndef CYGONCE_HAL_HAL_INTR_H 00002 #define CYGONCE_HAL_HAL_INTR_H 00003 //========================================================================== 00004 // 00005 // hal_intr.h 00006 // 00007 // HAL Interrupt and clock support 00008 // 00009 //========================================================================== 00010 //####ECOSGPLCOPYRIGHTBEGIN#### 00011 // ------------------------------------------- 00012 // This file is part of eCos, the Embedded Configurable Operating System. 00013 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. 00014 // 00015 // eCos is free software; you can redistribute it and/or modify it under 00016 // the terms of the GNU General Public License as published by the Free 00017 // Software Foundation; either version 2 or (at your option) any later version. 00018 // 00019 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY 00020 // WARRANTY; without even the implied warranty of MERCHANTABILITY or 00021 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 00022 // for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License along 00025 // with eCos; if not, write to the Free Software Foundation, Inc., 00026 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00027 // 00028 // As a special exception, if other files instantiate templates or use macros 00029 // or inline functions from this file, or you compile this file and link it 00030 // with other works to produce a work based on this file, this file does not 00031 // by itself cause the resulting work to be covered by the GNU General Public 00032 // License. However the source code for this file must still be made available 00033 // in accordance with section (3) of the GNU General Public License. 00034 // 00035 // This exception does not invalidate any other reasons why a work based on 00036 // this file might be covered by the GNU General Public License. 00037 // 00038 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. 00039 // at http://sources.redhat.com/ecos/ecos-license/ 00040 // ------------------------------------------- 00041 //####ECOSGPLCOPYRIGHTEND#### 00042 //========================================================================== 00043 //#####DESCRIPTIONBEGIN#### 00044 // 00045 // Author(s): yoshinori sato 00046 // Contributors: yoshinori sato, Uwe Kindler 00047 // Date: 2003-12-06 00048 // Purpose: Define Interrupt support 00049 // Description: The macros defined here provide the HAL APIs for handling 00050 // interrupts and the clock. 00051 // Usage: 00052 // #include <cyg/hal/hal_intr.h> 00053 // ... 00054 // 00055 // 00056 //####DESCRIPTIONEND#### 00057 // 00058 //========================================================================== 00059 00060 00061 //========================================================================== 00062 // DOXYGEN FILE HEADER 00072 //========================================================================== 00073 00074 00075 //========================================================================== 00076 // INCLUDES 00077 //========================================================================== 00078 #include <pkgconf/hal.h> 00079 00080 #if defined(CYGPKG_KERNEL) 00081 #include <pkgconf/kernel.h> 00082 #endif 00083 00084 #include <cyg/infra/cyg_type.h> 00085 #include <cyg/hal/hal_io.h> 00086 00087 #include <cyg/hal/var_intr.h> 00088 00089 00090 //========================================================================== 00091 // H8S VSR 00092 // DESCRIPTION: 00093 // The H8S architecture supports a number of 128 exception/interrupt 00094 // vectors. The vector name are defined within the variant HAL. 00095 //========================================================================== 00096 #define CYGNUM_HAL_VSR_MIN 0 00097 #define CYGNUM_HAL_VSR_MAX 127 00098 #define CYGNUM_HAL_VSR_COUNT 128 00099 00100 00101 //========================================================================== 00102 // H8S INTERRUPT PRIORITY LEVELS 00103 //========================================================================== 00104 #define CYGNUM_HAL_INT_PRIO_0 0x00 00105 #define CYGNUM_HAL_INT_PRIO_1 0x01 00106 #define CYGNUM_HAL_INT_PRIO_2 0x02 00107 #define CYGNUM_HAL_INT_PRIO_3 0x03 00108 #define CYGNUM_HAL_INT_PRIO_4 0x04 00109 #define CYGNUM_HAL_INT_PRIO_5 0x05 00110 #define CYGNUM_HAL_INT_PRIO_6 0x06 00111 #define CYGNUM_HAL_INT_PRIO_7 0x07 00112 00113 #define CYGNUM_HAL_INT_PRIO_LOWEST CYGNUM_HAL_INT_PRIO_0 00114 #define CYGNUM_HAL_INT_PRIO_HIGHEST CYGNUM_HAL_INT_PRIO_7 00115 // 00116 // When H8S is reseted then the initial values for all priorities 00117 // is CYGNUM_HAL_INT_PRIO_7 00118 // 00119 #define CYGNUM_HAL_INT_PRIO_DEFAULT CYGNUM_HAL_INT_PRIO_7 00120 00121 00122 //========================================================================== 00123 // SET VSR TO ECOS HANDLER 00124 // DESCRIPTION: 00125 // If kernel is present but no kernal api then we have to declare 00126 // this enum in order to compile the source 00127 //========================================================================== 00128 #if defined(CYGPKG_KERNEL) && !defined(CYGFUN_KERNEL_API_C) 00129 enum cyg_ISR_results 00130 { 00131 CYG_ISR_HANDLED = 1, // Interrupt was handled 00132 CYG_ISR_CALL_DSR = 2 // Schedule DSR 00133 }; 00134 #endif 00135 00136 00137 //========================================================================== 00138 // STATIC DATA USED BY HAL 00139 //========================================================================== 00140 // 00141 // ISR tables 00144 externC volatile CYG_ADDRESS hal_interrupt_handlers[CYGNUM_HAL_ISR_COUNT]; 00147 externC volatile CYG_ADDRWORD hal_interrupt_data[CYGNUM_HAL_ISR_COUNT]; 00150 externC volatile CYG_ADDRESS hal_interrupt_objects[CYGNUM_HAL_ISR_COUNT]; 00151 // 00152 // VSR table 00156 externC volatile CYG_ADDRESS hal_vsr_table[CYGNUM_HAL_VSR_COUNT]; 00157 00158 00159 //========================================================================== 00160 // DEFAULT ISR 00163 //========================================================================== 00164 externC cyg_uint32 hal_default_isr(CYG_ADDRWORD vector, CYG_ADDRWORD data); 00165 #define HAL_DEFAULT_ISR hal_default_isr 00166 00167 00168 //========================================================================== 00169 // EXECUTE DSR ON INTERRUPT STACK 00170 // DESCRIPTION: 00171 // A feature that many HALs support is the ability to execute DSRs on 00172 // the interrupt stack. This is not an essential feature, and is better 00173 // left unimplemented in the initial porting effort. If this is 00174 // required, then the macro HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() 00175 // should be defined to call a function in vectors.S. 00176 //========================================================================== 00177 #ifdef CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK 00182 externC void hal_interrupt_stack_call_pending_DSRs(void); 00183 #define HAL_INTERRUPT_STACK_CALL_PENDING_DSRS() \ 00184 hal_interrupt_stack_call_pending_DSRs() 00185 // 00186 // these are offered solely for stack usage testing 00187 // if they are not defined, then there is no interrupt stack. 00188 // use them to declare these extern however you want: 00189 // extern char HAL_INTERRUPT_STACK_BASE[]; 00190 // extern char HAL_INTERRUPT_STACK_TOP[]; 00191 // is recommended 00192 // 00193 #define HAL_INTERRUPT_STACK_BASE cyg_interrupt_stack_base 00194 #define HAL_INTERRUPT_STACK_TOP cyg_interrupt_stack 00195 #endif // CYGIMP_HAL_COMMON_INTERRUPTS_USE_INTERRUPT_STACK 00196 00197 00198 //========================================================================== 00199 // INTERRUPT STATE CONTROL 00200 //========================================================================== 00204 typedef cyg_uint32 CYG_INTERRUPT_STATE; 00205 00206 00207 //========================================================================== 00208 // DISABLE INTERRUPTS 00209 // DESCRIPTION: 00210 // Disables the delivery of interrupts and stores the original state 00211 // of the interrupt mask in the variable passed in the old argument. 00212 // 00213 // PARAMETERS: 00214 // '_old_' Stores the current interrupt mask before setting the new one 00215 // 00216 // NOTES: 00217 // If we ware working in interrupt control mode 2 then we have to mask 00218 // the 3 interrupt mask bits ind EXR register 00219 //========================================================================== 00220 #define HAL_DISABLE_INTERRUPTS(_old_) \ 00221 asm volatile ( \ 00222 "sub.l er0,er0\n\t" \ 00223 "stc exr,r0l\n\t" \ 00224 "orc #0x7,exr\n\t" \ 00225 "and.b #0x07,r0l\n\t" \ 00226 "mov.l er0,%0" \ 00227 : "=r"(_old_) \ 00228 : \ 00229 : "er0" \ 00230 ); 00231 00232 00233 //========================================================================== 00234 // ENABLE INTERRUPTS 00235 // DESCRIPTION: 00236 // Simply enables interrupts regardless of the current state of the 00237 // mask. 00238 // 00239 // NOTES: 00240 // If we ware working in interrupt control mode 2 then we have to 00241 // then we have to set Bit 0 - Bit 2 of EXR to zero in order to 00242 // unmask all interrupts. 00243 //========================================================================== 00244 #define HAL_ENABLE_INTERRUPTS() \ 00245 asm volatile ( \ 00246 "andc #0xf8,exr" \ 00247 ); 00248 00249 00250 //========================================================================== 00251 // RESTORE INTERRUPTS 00252 // DESCRIPTION: 00253 // Restores the state of the interrupt mask to that recorded in old. 00254 // 00255 // PARAMETERS: 00256 // '_old_' Interrupt mask to be restored 00257 // 00258 // NOTES: 00259 // We are working in interrupt control mode 2 so we are going to modify 00260 // the interrupt mask bits in EXR register (Bit 0 - 2) 00261 //========================================================================== 00262 #define HAL_RESTORE_INTERRUPTS(_old_) \ 00263 asm volatile ( \ 00264 "mov.l %0,er0\n\t" \ 00265 "and.b #0x07,r0l\n\t" \ 00266 "stc exr,r0h\n\t" \ 00267 "and.b #0xf8,r0h\n\t" \ 00268 "or.b r0h,r0l\n\t" \ 00269 "ldc r0l,exr" \ 00270 : \ 00271 : "r"(_old_) \ 00272 : "er0" \ 00273 ); 00274 00275 00276 //========================================================================== 00277 // QUERY INTERRUPTS 00278 // DESCRIPTION: 00279 // stores the state of the interrupt mask in the variable passed in 00280 // the state argument. The state stored here should also be capable of 00281 // being passed to HAL_RESTORE_INTERRUPTS() at a later point. 00282 // 00283 // PARAMETERS: 00284 // '_state_' Stores interrupt state 00285 // 00286 // NOTES: 00287 // We are working in interrupt control mode 2 so we are going to 00288 // query the EXR register 00289 //========================================================================== 00290 #define HAL_QUERY_INTERRUPTS(_state_) \ 00291 asm volatile ( \ 00292 "sub.l er0,er0\n\t" \ 00293 "stc exr,r0l\n\t" \ 00294 "and.b #0x07,r0l\n\t" \ 00295 "mov.l er0,%0" \ 00296 : "=r"(_state_) \ 00297 ); 00298 00299 00300 //========================================================================== 00301 // TEST VECTOR STATE 00302 // DESCRIPTION: 00303 // Tests the state of the supplied interrupt vector and sets the value 00304 // of the state parameter to either 1 or 0 depending on whether there 00305 // is already an ISR attached to the vector. The HAL will only allow one 00306 // ISR to be attached to each vector, so it is a good idea to use this 00307 // function before using HAL_INTERRUPT_ATTACH(). 00308 // 00309 // PARAMETERS: 00310 // '_vector_' Vector number to be tested 00311 // '_state_' State of the vector in _vector_ 00312 // 0 - Vector not in use, 1 - Vector in use 00313 //========================================================================== 00314 #define HAL_INTERRUPT_IN_USE(_vector_, _state_) \ 00315 CYG_MACRO_START \ 00316 cyg_uint32 _index_; \ 00317 HAL_TRANSLATE_VECTOR ((_vector_), _index_); \ 00318 \ 00319 if (hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR) \ 00320 { \ 00321 (_state_) = 0; \ 00322 } \ 00323 else \ 00324 { \ 00325 (_state_) = 1; \ 00326 } \ 00327 CYG_MACRO_END 00328 00329 00330 //========================================================================== 00331 // ATTACH ISR TO VECTOR 00332 // DESCRIPTION: 00333 // Attaches the ISR, data pointer and object pointer to the given 00334 // vector. When an interrupt occurs on this vector the ISR is called 00335 // using the C calling convention and the vector number and data pointer 00336 // are passed to it as the first and second arguments respectively. 00337 // 00338 // PARAMETERS: 00339 // '_vector_' Vector number of vector where VSR should be attached 00340 // '_isr_' Points to interrupt service routine 00341 // '_data_' Pointer to data 00342 // '_object_' Pointer to interrupt object 00343 //========================================================================== 00344 #if !defined(HAL_INTERRUPT_ATTACH) 00345 #define HAL_INTERRUPT_ATTACH(_vector_, _isr_, _data_, _object_) \ 00346 CYG_MACRO_START \ 00347 cyg_uint32 _index_; \ 00348 HAL_TRANSLATE_VECTOR(_vector_, _index_); \ 00349 \ 00350 if (hal_interrupt_handlers[_index_] == (CYG_ADDRESS)HAL_DEFAULT_ISR) \ 00351 { \ 00352 hal_interrupt_handlers[_index_] = (CYG_ADDRESS)_isr_; \ 00353 hal_interrupt_data[_index_] = (CYG_ADDRWORD)_data_; \ 00354 hal_interrupt_objects[_index_] = (CYG_ADDRESS)_object_; \ 00355 } \ 00356 CYG_MACRO_END 00357 #endif // #if !defined(HAL_INTERRUPT_ATTACH) 00358 00359 //========================================================================== 00360 // DETACH ISR FROM VECTOR 00361 // DESCRIPTION: 00362 // Detaches the ISR from the vector. 00363 // 00364 // PARAMETERS: 00365 // '_vector_' Vector number 00366 // '_isr_' Points to interrupt service routine 00367 //========================================================================== 00368 #define HAL_INTERRUPT_DETACH( _vector_, _isr_ ) \ 00369 CYG_MACRO_START \ 00370 cyg_uint32 _index_; \ 00371 HAL_TRANSLATE_VECTOR(_vector_, _index_); \ 00372 \ 00373 if (hal_interrupt_handlers[_index_] == (CYG_ADDRESS)_isr_ ) \ 00374 { \ 00375 hal_interrupt_handlers[_index_] = (CYG_ADDRESS)HAL_DEFAULT_ISR; \ 00376 hal_interrupt_data[_index_] = 0; \ 00377 hal_interrupt_objects[_index_] = 0; \ 00378 } \ 00379 CYG_MACRO_END 00380 00381 00382 //========================================================================== 00383 // GET COPY OF VSR 00384 // DESCRIPTION: 00385 // Assigns a copy of the VSR to the location pointed to by pvsr. 00386 // 00387 // PARAMETERS: 00388 // '_vector_' Vector number 00389 // '_pvsr_' Points to location of VSR 00390 //========================================================================== 00391 #define HAL_VSR_GET(_vector_, _pvsr_) \ 00392 *((CYG_ADDRESS *)_pvsr_) = hal_vsr_table[_vector_]; 00393 00394 00395 //========================================================================== 00396 // REPLACE VSR 00397 // DESCRIPTION: 00398 // Replaces the VSR attached to the vector with the replacement supplied 00399 // in vsr. The old VSR is returned in the location pointed to by pvsr. 00400 // 00401 // PARAMETERS: 00402 // '_vector_' Vector number of VSR to be replaced 00403 // '_vsr_' New VSR routine fro vector 00404 // '_poldvsr_' Points to old VSR 00405 //========================================================================== 00406 #define HAL_VSR_SET( _vector_, _vsr_, _poldvsr_ ) \ 00407 CYG_MACRO_START \ 00408 if( (void*)_poldvsr_ != (void*)NULL ) \ 00409 { \ 00410 *(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \ 00411 } \ 00412 hal_vsr_table[_vector_] = (CYG_ADDRESS)_vsr_; \ 00413 CYG_MACRO_END 00414 00415 00416 //========================================================================== 00417 // SET VSR TO ECOS HANDLER 00418 // DESCRIPTION: 00419 // Ensures that the VSR for a specific exception is pointing to the eCos 00420 // exception VSR and not one for RedBoot or some other ROM monitor. The 00421 // default when running under RedBoot is for exceptions to be handled by 00422 // RedBoot and passed to GDB. This macro diverts the exception to eCos so 00423 // that it may be handled by application code. The arguments are the VSR 00424 // vector to be replaced, and a location in which to store the old VSR 00425 // pointer, so that it may be replaced at a later point. 00426 // 00427 // NOTES: 00428 // This is an ugly name, but what it means is: grab the VSR back to eCos 00429 // internal handling, or if you like, the default handler. But if 00430 // cooperating with GDB and RedBoot, the default behaviour is to pass most 00431 // exceptions to RedBoot. This macro undoes that so that eCos handles the 00432 // exception. So use it with care. 00433 //========================================================================== 00437 externC void __default_interrupt_vsr( void ); 00441 externC void __default_exception_vsr( void ); 00442 #define HAL_VSR_SET_TO_ECOS_HANDLER( _vector_, _poldvsr_ ) \ 00443 CYG_MACRO_START \ 00444 if( (void*)_poldvsr_ != (void*)NULL ) \ 00445 *(CYG_ADDRESS *)_poldvsr_ = hal_vsr_table[_vector_]; \ 00446 hal_vsr_table[_vector_] = ( CYG_VECTOR_IS_INTERRUPT( _vector_ ) \ 00447 ? (CYG_ADDRESS)__default_interrupt_vsr \ 00448 : (CYG_ADDRESS)__default_exception_vsr ); \ 00449 CYG_MACRO_END 00450 00451 00452 //-------------------------------------------------------------------------- 00453 #endif // ifndef CYGONCE_HAL_HAL_INTR_H 00454 // EOF hal_intr.h
1.3.5