From: arighi Date: Wed, 19 May 2010 12:23:23 +0000 (+0000) Subject: ARM7TDMI: get rid of gcc's __attribute__((interrupt)). X-Git-Tag: 2.5.0~201 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=9792a2d2230d9e4e8bd3dec96e37e4107a6d8a37;p=bertos.git ARM7TDMI: get rid of gcc's __attribute__((interrupt)). 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 --- diff --git a/bertos/cpu/irq.h b/bertos/cpu/irq.h index bda8b497..6eac70fd 100644 --- a/bertos/cpu/irq.h +++ b/bertos/cpu/irq.h @@ -350,7 +350,7 @@ __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. @@ -377,7 +377,7 @@ #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) \ @@ -394,9 +394,14 @@ 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)