summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell King <rmk@flint.arm.linux.org.uk>2005-03-02 15:32:02 +0000
committerRussell King <rmk@flint.arm.linux.org.uk>2005-03-02 15:32:02 +0000
commit2e1946e6d49417978af3f84f20573ae21566bb2b (patch)
tree463ad636db850c6da0a395646ee1e4bfb0762a10
parenta98faa0cfb14567db871088699adde16c81957eb (diff)
[ARM] Fix set_fiq_regs()/get_fiq_regs()
Make these "naked" functions. This allows us to eliminate the clobbers which later gcc versions complain about. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--arch/arm/kernel/fiq.c47
1 files changed, 20 insertions, 27 deletions
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index a45c7874a467..9299dfc25698 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -46,12 +46,6 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
-#warning This file requires GCC 3.3.x or older to build. Alternatively,
-#warning please talk to GCC people to resolve the issues with the
-#warning assembly clobber list.
-#endif
-
static unsigned long no_fiq_insn;
/* Default reacquire function
@@ -91,44 +85,43 @@ void set_fiq_handler(void *start, unsigned int length)
/*
* Taking an interrupt in FIQ mode is death, so both these functions
- * disable irqs for the duration.
+ * disable irqs for the duration. Note - these functions are almost
+ * entirely coded in assembly.
*/
-void set_fiq_regs(struct pt_regs *regs)
+void __attribute__((naked)) set_fiq_regs(struct pt_regs *regs)
{
register unsigned long tmp;
- __asm__ volatile (
- "mrs %0, cpsr\n\
+ asm volatile (
+ "mov ip, sp\n\
+ stmfd sp!, {fp, ip, lr, pc}\n\
+ sub fp, ip, #4\n\
+ mrs %0, cpsr\n\
msr cpsr_c, %2 @ select FIQ mode\n\
mov r0, r0\n\
ldmia %1, {r8 - r14}\n\
msr cpsr_c, %0 @ return to SVC mode\n\
- mov r0, r0"
+ mov r0, r0\n\
+ ldmea fp, {fp, sp, pc}"
: "=&r" (tmp)
- : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)
- /* These registers aren't modified by the above code in a way
- visible to the compiler, but we mark them as clobbers anyway
- so that GCC won't put any of the input or output operands in
- them. */
- : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
+ : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
}
-void get_fiq_regs(struct pt_regs *regs)
+void __attribute__((naked)) get_fiq_regs(struct pt_regs *regs)
{
register unsigned long tmp;
- __asm__ volatile (
- "mrs %0, cpsr\n\
+ asm volatile (
+ "mov ip, sp\n\
+ stmfd sp!, {fp, ip, lr, pc}\n\
+ sub fp, ip, #4\n\
+ mrs %0, cpsr\n\
msr cpsr_c, %2 @ select FIQ mode\n\
mov r0, r0\n\
stmia %1, {r8 - r14}\n\
msr cpsr_c, %0 @ return to SVC mode\n\
- mov r0, r0"
+ mov r0, r0\n\
+ ldmea fp, {fp, sp, pc}"
: "=&r" (tmp)
- : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)
- /* These registers aren't modified by the above code in a way
- visible to the compiler, but we mark them as clobbers anyway
- so that GCC won't put any of the input or output operands in
- them. */
- : "r8", "r9", "r10", "r11", "r12", "r13", "r14");
+ : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
}
int claim_fiq(struct fiq_handler *f)