X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Farm%2Fkernel%2Ffiq.c;h=1ec3f7faa259eedba5ccf3973ca827fb869cdfcd;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=a45c7874a467f7e01b7822b1672a1db0d5e18f36;hpb=6a77f38946aaee1cd85eeec6cf4229b204c15071;p=linux-2.6.git diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c index a45c7874a..1ec3f7faa 100644 --- a/arch/arm/kernel/fiq.c +++ b/arch/arm/kernel/fiq.c @@ -46,12 +46,6 @@ #include #include -#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\ + ldmfd sp, {fp, sp, pc}" : "=&r" (tmp) - : "r" (®s->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" (®s->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\ + ldmfd sp, {fp, sp, pc}" : "=&r" (tmp) - : "r" (®s->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" (®s->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE)); } int claim_fiq(struct fiq_handler *f)