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 #elif CPU_ARM
00064 
00065 
00066     #ifdef __IAR_SYSTEMS_ICC__
00067 
00068         #include <inarm.h>
00069 
00070         #if __CPU_MODE__ == 1 /* Thumb */
00071             /* Use stubs */
00072             extern cpuflags_t get_CPSR(void);
00073             extern void set_CPSR(cpuflags_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         #define BREAKPOINT  /* asm("bkpt 0") DOES NOT WORK */
00097 
00098     #else /* !__IAR_SYSTEMS_ICC__ */
00099 
00100         #define IRQ_DISABLE \
00101         do { \
00102             asm volatile ( \
00103                 "mrs r0, cpsr\n\t" \
00104                 "orr r0, r0, #0xc0\n\t" \
00105                 "msr cpsr_c, r0" \
00106                 ::: "r0" \
00107             ); \
00108         } while (0)
00109 
00110         #define IRQ_ENABLE \
00111         do { \
00112             asm volatile ( \
00113                 "mrs r0, cpsr\n\t" \
00114                 "bic r0, r0, #0xc0\n\t" \
00115                 "msr cpsr_c, r0" \
00116                 ::: "r0" \
00117             ); \
00118         } while (0)
00119 
00120         #define IRQ_SAVE_DISABLE(x) \
00121         do { \
00122             asm volatile ( \
00123                 "mrs %0, cpsr\n\t" \
00124                 "orr r0, %0, #0xc0\n\t" \
00125                 "msr cpsr_c, r0" \
00126                 : "=r" (x) \
00127                 : /* no inputs */ \
00128                 : "r0" \
00129             ); \
00130         } while (0)
00131 
00132         #define IRQ_RESTORE(x) \
00133         do { \
00134             asm volatile ( \
00135                 "msr cpsr_c, %0" \
00136                 : /* no outputs */ \
00137                 : "r" (x) \
00138             ); \
00139         } while (0)
00140 
00141         #define CPU_READ_FLAGS() \
00142         ({ \
00143             cpuflags_t sreg; \
00144             asm volatile ( \
00145                 "mrs %0, cpsr\n\t" \
00146                 : "=r" (sreg) \
00147                 : /* no inputs */ \
00148             ); \
00149             sreg; \
00150         })
00151 
00152         #define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0)
00153 
00154     #endif /* !__IAR_SYSTEMS_ICC_ */
00155 
00156 #elif CPU_PPC
00157     #define IRQ_DISABLE         FIXME
00158     #define IRQ_ENABLE          FIXME
00159     #define IRQ_SAVE_DISABLE(x) FIXME
00160     #define IRQ_RESTORE(x)      FIXME
00161     #define IRQ_ENABLED()       FIXME
00162 
00163 #elif CPU_DSP56K
00164 
00165     #define BREAKPOINT              asm(debug)
00166     #define IRQ_DISABLE             do { asm(bfset #0x0200,SR); asm(nop); } while (0)
00167     #define IRQ_ENABLE              do { asm(bfclr #0x0200,SR); asm(nop); } while (0)
00168 
00169     #define IRQ_SAVE_DISABLE(x)  \
00170         do { (void)x; asm(move SR,x); asm(bfset #0x0200,SR); } while (0)
00171     #define IRQ_RESTORE(x)  \
00172         do { (void)x; asm(move x,SR); } while (0)
00173 
00174     static inline bool irq_running(void)
00175     {
00176         extern void *user_sp;
00177         return !!user_sp;
00178     }
00179     #define IRQ_RUNNING() irq_running()
00180 
00181     static inline bool irq_enabled(void)
00182     {
00183         uint16_t x;
00184         asm(move SR,x);
00185         return !(x & 0x0200);
00186     }
00187     #define IRQ_ENABLED() irq_enabled()
00188 
00189 #elif CPU_AVR
00190 
00191     #define IRQ_DISABLE   asm volatile ("cli" ::)
00192     #define IRQ_ENABLE    asm volatile ("sei" ::)
00193 
00194     #define IRQ_SAVE_DISABLE(x) \
00195     do { \
00196         __asm__ __volatile__( \
00197             "in %0,__SREG__\n\t" \
00198             "cli" \
00199             : "=r" (x) : /* no inputs */ : "cc" \
00200         ); \
00201     } while (0)
00202 
00203     #define IRQ_RESTORE(x) \
00204     do { \
00205         __asm__ __volatile__( \
00206             "out __SREG__,%0" : /* no outputs */ : "r" (x) : "cc" \
00207         ); \
00208     } while (0)
00209 
00210     #define IRQ_ENABLED() \
00211     ({ \
00212         uint8_t sreg; \
00213         __asm__ __volatile__( \
00214             "in %0,__SREG__\n\t" \
00215             : "=r" (sreg)  /* no inputs & no clobbers */ \
00216         ); \
00217         (bool)(sreg & 0x80); \
00218     })
00219 #else
00220     #error No CPU_... defined.
00221 #endif
00222 
00223 #ifndef IRQ_ENTRY
00224     #define IRQ_ENTRY() /* NOP */
00225 #endif
00226 
00227 #ifndef IRQ_EXIT
00228     #define IRQ_EXIT() /* NOP */
00229 #endif
00230 
00231 
00237 #define ATOMIC(CODE) \
00238     do { \
00239         cpuflags_t __flags; \
00240         IRQ_SAVE_DISABLE(__flags); \
00241         CODE; \
00242         IRQ_RESTORE(__flags); \
00243     } while (0)
00244 
00245 
00246 #ifndef BREAKPOINT
00247 #define BREAKPOINT /* nop */
00248 #endif
00249 
00250 
00251 #endif /* CPU_IRQ_H */