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 <kern/proc.h>
00048
00049 #include <cfg/compiler.h>
00050 #include "cfg/cfg_proc.h"
00051
00052 #if CPU_I196
00053 #define IRQ_DISABLE disable_interrupt()
00054 #define IRQ_ENABLE enable_interrupt()
00055 #elif CPU_X86
00056
00057
00058 #include <cfg/os.h>
00059 #if OS_EMBEDDED
00060 #define IRQ_DISABLE FIXME
00061 #define IRQ_ENABLE FIXME
00062 #define IRQ_SAVE_DISABLE(x) FIXME
00063 #define IRQ_RESTORE(x) FIXME
00064 #endif
00065
00066
00067 #elif CPU_ARM
00068
00069 #ifdef __IAR_SYSTEMS_ICC__
00070
00071 #include <inarm.h>
00072
00073 #if __CPU_MODE__ == 1
00074
00075 extern cpu_flags_t get_CPSR(void);
00076 extern void set_CPSR(cpu_flags_t flags);
00077 #else
00078 #define get_CPSR __get_CPSR
00079 #define set_CPSR __set_CPSR
00080 #endif
00081
00082 #define IRQ_DISABLE __disable_interrupt()
00083 #define IRQ_ENABLE __enable_interrupt()
00084
00085 #define IRQ_SAVE_DISABLE(x) \
00086 do { \
00087 (x) = get_CPSR(); \
00088 __disable_interrupt(); \
00089 } while (0)
00090
00091 #define IRQ_RESTORE(x) \
00092 do { \
00093 set_CPSR(x); \
00094 } while (0)
00095
00096 #define IRQ_ENABLED() \
00097 ((bool)(get_CPSR() & 0xb0))
00098
00099 #else
00100
00101 #define IRQ_DISABLE \
00102 do { \
00103 asm volatile ( \
00104 "mrs r0, cpsr\n\t" \
00105 "orr r0, r0, #0xc0\n\t" \
00106 "msr cpsr_c, r0" \
00107 ::: "r0" \
00108 ); \
00109 } while (0)
00110
00111 #define IRQ_ENABLE \
00112 do { \
00113 asm volatile ( \
00114 "mrs r0, cpsr\n\t" \
00115 "bic r0, r0, #0xc0\n\t" \
00116 "msr cpsr_c, r0" \
00117 ::: "r0" \
00118 ); \
00119 } while (0)
00120
00121 #define IRQ_SAVE_DISABLE(x) \
00122 do { \
00123 asm volatile ( \
00124 "mrs %0, cpsr\n\t" \
00125 "orr r0, %0, #0xc0\n\t" \
00126 "msr cpsr_c, r0" \
00127 : "=r" (x) \
00128 : \
00129 : "r0" \
00130 ); \
00131 } while (0)
00132
00133 #define IRQ_RESTORE(x) \
00134 do { \
00135 asm volatile ( \
00136 "msr cpsr_c, %0" \
00137 : \
00138 : "r" (x) \
00139 ); \
00140 } while (0)
00141
00142 #define CPU_READ_FLAGS() \
00143 ({ \
00144 cpu_flags_t sreg; \
00145 asm volatile ( \
00146 "mrs %0, cpsr\n\t" \
00147 : "=r" (sreg) \
00148 : \
00149 ); \
00150 sreg; \
00151 })
00152
00153 #define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0)
00154
00155 #if CONFIG_KERN_PREEMPT
00156 EXTERN_C void asm_irq_switch_context(void);
00157
00164 #define IRQ_ENTRY() asm volatile ( \
00165 "sub lr, lr, #4\n\t" \
00166 "stmfd sp!, {r0-r3, ip, lr}\n\t")
00167 #define IRQ_EXIT() asm volatile ( \
00168 "b asm_irq_switch_context\n\t")
00169
00179 #define ISR_FUNC __attribute__((naked))
00180
00207 #define DECLARE_ISR_CONTEXT_SWITCH(func) \
00208 void ISR_FUNC func(void); \
00209 static void __isr_##func(void); \
00210 void ISR_FUNC func(void) \
00211 { \
00212 IRQ_ENTRY(); \
00213 IRQ_DISABLE; \
00214 __isr_##func(); \
00215 IRQ_EXIT(); \
00216 } \
00217 static void __isr_##func(void)
00218
00222 #define ISR_PROTO_CONTEXT_SWITCH(func) \
00223 void ISR_FUNC func(void)
00224
00234 #if CONFIG_KERN_PRI
00235 #define DECLARE_ISR(func) \
00236 DECLARE_ISR_CONTEXT_SWITCH(func)
00237
00238 #define ISR_PROTO(func) \
00239 ISR_PROTO_CONTEXT_SWITCH(func)
00240 #endif
00241 #endif
00242
00243 #ifndef DECLARE_ISR
00244 #define DECLARE_ISR(func) \
00245 void __attribute__((interrupt)) func(void)
00246 #endif
00247 #ifndef DECLARE_ISR_CONTEXT_SWITCH
00248 #define DECLARE_ISR_CONTEXT_SWITCH(func) \
00249 void __attribute__((interrupt)) func(void)
00250 #endif
00251 #ifndef ISR_PROTO
00252 #define ISR_PROTO(func) \
00253 void __attribute__((interrupt)) func(void)
00254 #endif
00255 #ifndef ISR_PROTO_CONTEXT_SWITCH
00256 #define ISR_PROTO_CONTEXT_SWITCH(func) \
00257 void __attribute__((interrupt)) func(void)
00258 #endif
00259
00260 #endif
00261
00262 #elif CPU_PPC
00263
00264
00265 #include <cfg/os.h>
00266 #if OS_EMBEDDED
00267 #define IRQ_DISABLE FIXME
00268 #define IRQ_ENABLE FIXME
00269 #define IRQ_SAVE_DISABLE(x) FIXME
00270 #define IRQ_RESTORE(x) FIXME
00271 #define IRQ_ENABLED() FIXME
00272 #endif
00273
00274 #elif CPU_DSP56K
00275
00276 #define IRQ_DISABLE do { asm(bfset #0x0200,SR); asm(nop); } while (0)
00277 #define IRQ_ENABLE do { asm(bfclr #0x0200,SR); asm(nop); } while (0)
00278
00279 #define IRQ_SAVE_DISABLE(x) \
00280 do { (void)x; asm(move SR,x); asm(bfset #0x0200,SR); } while (0)
00281 #define IRQ_RESTORE(x) \
00282 do { (void)x; asm(move x,SR); } while (0)
00283
00284 static inline bool irq_running(void)
00285 {
00286 extern void *user_sp;
00287 return !!user_sp;
00288 }
00289 #define IRQ_RUNNING() irq_running()
00290
00291 static inline bool irq_enabled(void)
00292 {
00293 uint16_t x;
00294 asm(move SR,x);
00295 return !(x & 0x0200);
00296 }
00297 #define IRQ_ENABLED() irq_enabled()
00298
00299 #elif CPU_AVR
00300
00301 #define IRQ_DISABLE asm volatile ("cli" ::)
00302 #define IRQ_ENABLE asm volatile ("sei" ::)
00303
00304 #define IRQ_SAVE_DISABLE(x) \
00305 do { \
00306 __asm__ __volatile__( \
00307 "in %0,__SREG__\n\t" \
00308 "cli" \
00309 : "=r" (x) : : "cc" \
00310 ); \
00311 } while (0)
00312
00313 #define IRQ_RESTORE(x) \
00314 do { \
00315 __asm__ __volatile__( \
00316 "out __SREG__,%0" : : "r" (x) : "cc" \
00317 ); \
00318 } while (0)
00319
00320 #define IRQ_ENABLED() \
00321 ({ \
00322 uint8_t sreg; \
00323 __asm__ __volatile__( \
00324 "in %0,__SREG__\n\t" \
00325 : "=r" (sreg) \
00326 ); \
00327 (bool)(sreg & 0x80); \
00328 })
00329 #if CONFIG_KERN_PREEMPT
00330 #define DECLARE_ISR_CONTEXT_SWITCH(vect) \
00331 INLINE void __isr_##vect(void); \
00332 ISR(vect) \
00333 { \
00334 __isr_##vect(); \
00335 IRQ_PREEMPT_HANDLER(); \
00336 } \
00337 INLINE void __isr_##vect(void)
00338
00349 #if CONFIG_KERN_PRI
00350 #define DECLARE_ISR(func) \
00351 DECLARE_ISR_CONTEXT_SWITCH(func)
00352
00356 #define ISR_PROTO(func) \
00357 ISR_PROTO_CONTEXT_SWITCH(func)
00358 #endif
00359 #endif
00360
00361 #ifndef ISR_PROTO
00362 #define ISR_PROTO(vect) ISR(vect)
00363 #endif
00364 #ifndef DECLARE_ISR
00365 #define DECLARE_ISR(vect) ISR(vect)
00366 #endif
00367 #ifndef DECLARE_ISR_CONTEXT_SWITCH
00368 #define DECLARE_ISR_CONTEXT_SWITCH(vect) ISR(vect)
00369 #endif
00370 #ifndef ISR_PROTO_CONTEXT_SWITCH
00371 #define ISR_PROTO_CONTEXT_SWITCH(func) ISR(vect)
00372 #endif
00373
00374 #else
00375 #error No CPU_... defined.
00376 #endif
00377
00378 #ifdef IRQ_RUNNING
00380 #define ASSERT_IRQ_CONTEXT() ASSERT(IRQ_RUNNING())
00381
00383 #define ASSERT_USER_CONTEXT() ASSERT(!IRQ_RUNNING())
00384 #else
00385 #define ASSERT_USER_CONTEXT() do {} while(0)
00386 #define ASSERT_IRQ_CONTEXT() do {} while(0)
00387 #endif
00388
00389 #ifdef IRQ_ENABLED
00391 #define IRQ_ASSERT_ENABLED() ASSERT(IRQ_ENABLED())
00392
00394 #define IRQ_ASSERT_DISABLED() ASSERT(!IRQ_ENABLED())
00395 #else
00396 #define IRQ_ASSERT_ENABLED() do {} while(0)
00397 #define IRQ_ASSERT_DISABLED() do {} while(0)
00398 #endif
00399
00400
00401 #ifndef IRQ_PREEMPT_HANDLER
00402 #if CONFIG_KERN_PREEMPT
00403
00406 INLINE void IRQ_PREEMPT_HANDLER(void)
00407 {
00408 if (proc_needPreempt())
00409 proc_preempt();
00410 }
00411 #else
00412 #define IRQ_PREEMPT_HANDLER()
00413 #endif
00414 #endif
00415
00421 #define ATOMIC(CODE) \
00422 do { \
00423 cpu_flags_t __flags; \
00424 IRQ_SAVE_DISABLE(__flags); \
00425 CODE; \
00426 IRQ_RESTORE(__flags); \
00427 } while (0)
00428
00429 #endif