cpu/irq.h

Go to the documentation of this file.
00001 
00041 #ifndef CPU_IRQ_H
00042 #define CPU_IRQ_H
00043 
00044 #include "detect.h"
00045 #include "types.h"
00046 
00047 #include <cfg/compiler.h> /* for uintXX_t */
00048 
00049 #if CPU_I196
00050     #define IRQ_DISABLE             disable_interrupt()
00051     #define IRQ_ENABLE              enable_interrupt()
00052 #elif CPU_X86
00053 
00054     /* Get IRQ_* definitions from the hosting environment. */
00055     #include <cfg/os.h>
00056     #if OS_EMBEDDED
00057         #define IRQ_DISABLE             FIXME
00058         #define IRQ_ENABLE              FIXME
00059         #define IRQ_SAVE_DISABLE(x)     FIXME
00060         #define IRQ_RESTORE(x)          FIXME
00061     #endif /* OS_EMBEDDED */
00062 
00063 
00064 #elif CPU_ARM
00065 
00066     #ifdef __IAR_SYSTEMS_ICC__
00067 
00068         #include <inarm.h>
00069 
00070         #if __CPU_MODE__ == 1 /* Thumb */
00071             /* Use stubs */
00072             extern cpu_flags_t get_CPSR(void);
00073             extern void set_CPSR(cpu_flags_t flags);
00074         #else
00075             #define get_CPSR __get_CPSR
00076             #define set_CPSR __set_CPSR
00077         #endif
00078 
00079         #define IRQ_DISABLE __disable_interrupt()
00080         #define IRQ_ENABLE  __enable_interrupt()
00081 
00082         #define IRQ_SAVE_DISABLE(x) \
00083         do { \
00084             (x) = get_CPSR(); \
00085             __disable_interrupt(); \
00086         } while (0)
00087 
00088         #define IRQ_RESTORE(x) \
00089         do { \
00090             set_CPSR(x); \
00091         } while (0)
00092 
00093         #define IRQ_ENABLED() \
00094             ((bool)(get_CPSR() & 0xb0))
00095 
00096     #else /* !__IAR_SYSTEMS_ICC__ */
00097 
00098         #define IRQ_DISABLE \
00099         do { \
00100             asm volatile ( \
00101                 "mrs r0, cpsr\n\t" \
00102                 "orr r0, r0, #0xc0\n\t" \
00103                 "msr cpsr_c, r0" \
00104                 ::: "r0" \
00105             ); \
00106         } while (0)
00107 
00108         #define IRQ_ENABLE \
00109         do { \
00110             asm volatile ( \
00111                 "mrs r0, cpsr\n\t" \
00112                 "bic r0, r0, #0xc0\n\t" \
00113                 "msr cpsr_c, r0" \
00114                 ::: "r0" \
00115             ); \
00116         } while (0)
00117 
00118         #define IRQ_SAVE_DISABLE(x) \
00119         do { \
00120             asm volatile ( \
00121                 "mrs %0, cpsr\n\t" \
00122                 "orr r0, %0, #0xc0\n\t" \
00123                 "msr cpsr_c, r0" \
00124                 : "=r" (x) \
00125                 : /* no inputs */ \
00126                 : "r0" \
00127             ); \
00128         } while (0)
00129 
00130         #define IRQ_RESTORE(x) \
00131         do { \
00132             asm volatile ( \
00133                 "msr cpsr_c, %0" \
00134                 : /* no outputs */ \
00135                 : "r" (x) \
00136             ); \
00137         } while (0)
00138 
00139         #define CPU_READ_FLAGS() \
00140         ({ \
00141             cpu_flags_t sreg; \
00142             asm volatile ( \
00143                 "mrs %0, cpsr\n\t" \
00144                 : "=r" (sreg) \
00145                 : /* no inputs */ \
00146             ); \
00147             sreg; \
00148         })
00149 
00150         #define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0)
00151 
00152     #endif /* !__IAR_SYSTEMS_ICC_ */
00153 
00154 #elif CPU_PPC
00155 
00156     /* Get IRQ_* definitions from the hosting environment. */
00157     #include <cfg/os.h>
00158     #if OS_EMBEDDED
00159         #define IRQ_DISABLE         FIXME
00160         #define IRQ_ENABLE          FIXME
00161         #define IRQ_SAVE_DISABLE(x) FIXME
00162         #define IRQ_RESTORE(x)      FIXME
00163         #define IRQ_ENABLED()       FIXME
00164     #endif /* OS_EMBEDDED */
00165 
00166 #elif CPU_DSP56K
00167 
00168     #define IRQ_DISABLE             do { asm(bfset #0x0200,SR); asm(nop); } while (0)
00169     #define IRQ_ENABLE              do { asm(bfclr #0x0200,SR); asm(nop); } while (0)
00170 
00171     #define IRQ_SAVE_DISABLE(x)  \
00172         do { (void)x; asm(move SR,x); asm(bfset #0x0200,SR); } while (0)
00173     #define IRQ_RESTORE(x)  \
00174         do { (void)x; asm(move x,SR); } while (0)
00175 
00176     static inline bool irq_running(void)
00177     {
00178         extern void *user_sp;
00179         return !!user_sp;
00180     }
00181     #define IRQ_RUNNING() irq_running()
00182 
00183     static inline bool irq_enabled(void)
00184     {
00185         uint16_t x;
00186         asm(move SR,x);
00187         return !(x & 0x0200);
00188     }
00189     #define IRQ_ENABLED() irq_enabled()
00190 
00191 #elif CPU_AVR
00192 
00193     #define IRQ_DISABLE   asm volatile ("cli" ::)
00194     #define IRQ_ENABLE    asm volatile ("sei" ::)
00195 
00196     #define IRQ_SAVE_DISABLE(x) \
00197     do { \
00198         __asm__ __volatile__( \
00199             "in %0,__SREG__\n\t" \
00200             "cli" \
00201             : "=r" (x) : /* no inputs */ : "cc" \
00202         ); \
00203     } while (0)
00204 
00205     #define IRQ_RESTORE(x) \
00206     do { \
00207         __asm__ __volatile__( \
00208             "out __SREG__,%0" : /* no outputs */ : "r" (x) : "cc" \
00209         ); \
00210     } while (0)
00211 
00212     #define IRQ_ENABLED() \
00213     ({ \
00214         uint8_t sreg; \
00215         __asm__ __volatile__( \
00216             "in %0,__SREG__\n\t" \
00217             : "=r" (sreg)  /* no inputs & no clobbers */ \
00218         ); \
00219         (bool)(sreg & 0x80); \
00220     })
00221 #else
00222     #error No CPU_... defined.
00223 #endif
00224 
00225 #ifndef IRQ_ENTRY
00226     #define IRQ_ENTRY() /* NOP */
00227 #endif
00228 
00229 #ifndef IRQ_EXIT
00230     #define IRQ_EXIT() /* NOP */
00231 #endif
00232 
00233 #ifdef IRQ_RUNNING
00235     #define ASSERT_IRQ_CONTEXT()  ASSERT(IRQ_RUNNING())
00236 
00238     #define ASSERT_USER_CONTEXT() ASSERT(!IRQ_RUNNING())
00239 #else
00240     #define ASSERT_USER_CONTEXT()  do {} while(0)
00241     #define ASSERT_IRQ_CONTEXT()   do {} while(0)
00242 #endif
00243 
00244 #ifdef IRQ_ENABLED
00246     #define IRQ_ASSERT_ENABLED()  ASSERT(IRQ_ENABLED())
00247 
00249     #define IRQ_ASSERT_DISABLED() ASSERT(!IRQ_ENABLED())
00250 #else
00251     #define IRQ_ASSERT_ENABLED() do {} while(0)
00252     #define IRQ_ASSERT_DISABLED() do {} while(0)
00253 #endif
00254 
00260 #define ATOMIC(CODE) \
00261     do { \
00262         cpu_flags_t __flags; \
00263         IRQ_SAVE_DISABLE(__flags); \
00264         CODE; \
00265         IRQ_RESTORE(__flags); \
00266     } while (0)
00267 
00268 #endif /* CPU_IRQ_H */