Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / arch / arm / kernel / fiq.c
index 894de5a..1ec3f7f 100644 (file)
@@ -85,46 +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, tmp2;
-       __asm__ volatile (
-       "mrs    %0, cpsr\n\
-       mov     %1, %3\n\
-       msr     cpsr_c, %1      @ select FIQ mode\n\
+       register unsigned long tmp;
+       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   %2, {r8 - r14}\n\
+       ldmia   %1, {r8 - r14}\n\
        msr     cpsr_c, %0      @ return to SVC mode\n\
-       mov     r0, r0"
-       : "=&r" (tmp), "=&r" (tmp2)
-       : "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");
+       mov     r0, r0\n\
+       ldmfd   sp, {fp, sp, pc}"
+       : "=&r" (tmp)
+       : "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, tmp2;
-       __asm__ volatile (
-       "mrs    %0, cpsr\n\
-       mov     %1, %3\n\
-       msr     cpsr_c, %1      @ select FIQ mode\n\
+       register unsigned long tmp;
+       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   %2, {r8 - r14}\n\
+       stmia   %1, {r8 - r14}\n\
        msr     cpsr_c, %0      @ return to SVC mode\n\
-       mov     r0, r0"
-       : "=&r" (tmp), "=&r" (tmp2)
-       : "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");
+       mov     r0, r0\n\
+       ldmfd   sp, {fp, sp, pc}"
+       : "=&r" (tmp)
+       : "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
 }
 
 int claim_fiq(struct fiq_handler *f)