X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Firq.h;h=6eac70fdea50424752119224ac1165fc794f3a50;hb=9792a2d2230d9e4e8bd3dec96e37e4107a6d8a37;hp=c3824556176b647068a5e6913b19c122b102e3a5;hpb=b78bdbe2e4aec232a7f48cb61a9b1d0dcee046b1;p=bertos.git diff --git a/bertos/cpu/irq.h b/bertos/cpu/irq.h index c3824556..6eac70fd 100644 --- a/bertos/cpu/irq.h +++ b/bertos/cpu/irq.h @@ -239,56 +239,51 @@ #else /* !__IAR_SYSTEMS_ICC__ */ - #define IRQ_DISABLE \ - do { \ - asm volatile ( \ - "mrs r0, cpsr\n\t" \ - "orr r0, r0, #0xc0\n\t" \ - "msr cpsr_c, r0" \ - ::: "r0" \ - ); \ + #define IRQ_DISABLE \ + do { \ + cpu_flags_t sreg; \ + asm volatile ( \ + "mrs %0, cpsr\n\t" \ + "orr %0, %0, #0xc0\n\t" \ + "msr cpsr_c, %0\n\t" \ + : "=r" (sreg) : : "memory", "cc"); \ } while (0) - #define IRQ_ENABLE \ - do { \ - asm volatile ( \ - "mrs r0, cpsr\n\t" \ - "bic r0, r0, #0xc0\n\t" \ - "msr cpsr_c, r0" \ - ::: "r0" \ - ); \ + #define IRQ_ENABLE \ + do { \ + cpu_flags_t sreg; \ + asm volatile ( \ + "mrs %0, cpsr\n\t" \ + "bic %0, %0, #0xc0\n\t" \ + "msr cpsr_c, %0\n\t" \ + : "=r" (sreg) : : "memory", "cc"); \ } while (0) - #define IRQ_SAVE_DISABLE(x) \ - do { \ - asm volatile ( \ - "mrs %0, cpsr\n\t" \ - "orr r0, %0, #0xc0\n\t" \ - "msr cpsr_c, r0" \ - : "=r" (x) \ - : /* no inputs */ \ - : "r0" \ - ); \ + #define IRQ_SAVE_DISABLE(x) \ + do { \ + register cpu_flags_t sreg; \ + asm volatile ( \ + "mrs %0, cpsr\n\t" \ + "orr %1, %0, #0xc0\n\t" \ + "msr cpsr_c, %1\n\t" \ + : "=r" (x), "=r" (sreg) \ + : : "memory", "cc"); \ } while (0) - #define IRQ_RESTORE(x) \ - do { \ - asm volatile ( \ - "msr cpsr_c, %0" \ - : /* no outputs */ \ - : "r" (x) \ - ); \ + #define IRQ_RESTORE(x) \ + do { \ + asm volatile ( \ + "msr cpsr_c, %0\n\t" \ + : : "r" (x) : "memory", "cc"); \ } while (0) - #define CPU_READ_FLAGS() \ - ({ \ - cpu_flags_t sreg; \ - asm volatile ( \ - "mrs %0, cpsr\n\t" \ - : "=r" (sreg) \ - : /* no inputs */ \ - ); \ - sreg; \ + #define CPU_READ_FLAGS() \ + ({ \ + cpu_flags_t sreg; \ + asm volatile ( \ + "mrs %0, cpsr\n\t" \ + : "=r" (sreg) : : "memory", "cc"); \ + sreg; \ }) #define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0) @@ -345,17 +340,17 @@ * IRQs will be automatically re-enabled when restoring * the context of the user task. */ - #define DECLARE_ISR_CONTEXT_SWITCH(func) \ - void ISR_FUNC func(void); \ - static void __isr_##func(void); \ - void ISR_FUNC func(void) \ - { \ - IRQ_ENTRY(); \ - IRQ_DISABLE; \ - __isr_##func(); \ - IRQ_EXIT(); \ - } \ - static void __isr_##func(void) + #define DECLARE_ISR_CONTEXT_SWITCH(func) \ + void ISR_FUNC func(void); \ + static NOINLINE void __isr_##func(void); \ + void ISR_FUNC func(void) \ + { \ + IRQ_ENTRY(); \ + IRQ_DISABLE; \ + __isr_##func(); \ + IRQ_EXIT(); \ + } \ + static NOINLINE void __isr_##func(void) /** * Interrupt service routine prototype: can be used for * forward declarations. @@ -381,21 +376,41 @@ #endif /* !CONFIG_KERN_PRI */ #endif /* CONFIG_KERN_PREEMPT */ + #ifndef ISR_FUNC + #define ISR_FUNC __attribute__((naked)) + #endif #ifndef DECLARE_ISR #define DECLARE_ISR(func) \ - void __attribute__((interrupt)) func(void) + void ISR_FUNC func(void); \ + /* \ + * FIXME: avoid the inlining of this function. \ + * \ + * This is terribly inefficient, but it's a \ + * reliable workaround to avoid gcc blowing \ + * away the stack (see the bug below): \ + * \ + * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41999 \ + */ \ + static NOINLINE void __isr_##func(void); \ + void ISR_FUNC func(void) \ + { \ + asm volatile ( \ + "sub lr, lr, #4\n\t" \ + "stmfd sp!, {r0-r3, ip, lr}\n\t"); \ + __isr_##func(); \ + asm volatile ( \ + "ldmfd sp!, {r0-r3, ip, pc}^\n\t"); \ + } \ + static NOINLINE void __isr_##func(void) #endif #ifndef DECLARE_ISR_CONTEXT_SWITCH - #define DECLARE_ISR_CONTEXT_SWITCH(func) \ - void __attribute__((interrupt)) func(void) + #define DECLARE_ISR_CONTEXT_SWITCH(func) DECLARE_ISR(func) #endif #ifndef ISR_PROTO - #define ISR_PROTO(func) \ - void __attribute__((interrupt)) func(void) + #define ISR_PROTO(func) void ISR_FUNC func(void) #endif #ifndef ISR_PROTO_CONTEXT_SWITCH - #define ISR_PROTO_CONTEXT_SWITCH(func) \ - void __attribute__((interrupt)) func(void) + #define ISR_PROTO_CONTEXT_SWITCH(func) ISR_PROTO(func) #endif #endif /* !__IAR_SYSTEMS_ICC_ */