ARM7TDMI: get rid of gcc's __attribute__((interrupt)).
authorarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 19 May 2010 12:23:23 +0000 (12:23 +0000)
committerarighi <arighi@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 19 May 2010 12:23:23 +0000 (12:23 +0000)
GCC is too buggy when generating __attribute__((interrupt)) functions on
ARM (see previous stack corruption issues).

Get rid of this definition and use __attribute__((naked)) instead,
implementing all the required instructions in assembly to properly save
and restore context from an ISR.

git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3716 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/cpu/irq.h

index bda8b49729a60cf2c2807dc74edadc1187705fbb..6eac70fdea50424752119224ac1165fc794f3a50 100644 (file)
                                        __isr_##func();                         \
                                        IRQ_EXIT();                             \
                                }                                               \
-                               static void __isr_##func(void)
+                               static NOINLINE void __isr_##func(void)
                        /**
                         * Interrupt service routine prototype: can be used for
                         * forward declarations.
                #endif /* CONFIG_KERN_PREEMPT */
 
                #ifndef ISR_FUNC
-                       #define ISR_FUNC  __attribute__((interrupt))
+                       #define ISR_FUNC __attribute__((naked))
                #endif
                #ifndef DECLARE_ISR
                        #define DECLARE_ISR(func) \
                                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 void __isr_##func(void)
+                               static NOINLINE void __isr_##func(void)
                #endif
                #ifndef DECLARE_ISR_CONTEXT_SWITCH
                        #define DECLARE_ISR_CONTEXT_SWITCH(func) DECLARE_ISR(func)