hal_intr.h

Go to the documentation of this file.
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

Generated on Tue Feb 17 09:06:12 2004 for eCos EDOSK-2674 HAL by doxygen 1.3.5