Thumb-2: Implementation of the unified start-up and exceptions code
[linux-3.10.git] / arch / arm / kernel / setup.c
index bc5e412..d4d4f77 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/smp.h>
 #include <linux/fs.h>
 
+#include <asm/unified.h>
 #include <asm/cpu.h>
 #include <asm/cputype.h>
 #include <asm/elf.h>
@@ -327,25 +328,38 @@ void cpu_init(void)
        }
 
        /*
+        * Define the placement constraint for the inline asm directive below.
+        * In Thumb-2, msr with an immediate value is not allowed.
+        */
+#ifdef CONFIG_THUMB2_KERNEL
+#define PLC    "r"
+#else
+#define PLC    "I"
+#endif
+
+       /*
         * setup stacks for re-entrant exception handlers
         */
        __asm__ (
        "msr    cpsr_c, %1\n\t"
-       "add    sp, %0, %2\n\t"
+       "add    r14, %0, %2\n\t"
+       "mov    sp, r14\n\t"
        "msr    cpsr_c, %3\n\t"
-       "add    sp, %0, %4\n\t"
+       "add    r14, %0, %4\n\t"
+       "mov    sp, r14\n\t"
        "msr    cpsr_c, %5\n\t"
-       "add    sp, %0, %6\n\t"
+       "add    r14, %0, %6\n\t"
+       "mov    sp, r14\n\t"
        "msr    cpsr_c, %7"
            :
            : "r" (stk),
-             "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
+             PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),
              "I" (offsetof(struct stack, irq[0])),
-             "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
+             PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE),
              "I" (offsetof(struct stack, abt[0])),
-             "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),
+             PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE),
              "I" (offsetof(struct stack, und[0])),
-             "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
+             PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
            : "r14");
 }