*/
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/v7m.h>
+
+ AR_CLASS(     .arch   armv7-a )
+ M_CLASS(      .arch   armv7-m )
 
-       .arch   armv7-a
 /*
  * Debugging stuff
  *
  * sort out different calling conventions
  */
                .align
-               .arm                            @ Always enter in ARM state
+               /*
+                * Always enter in ARM state for CPUs that support the ARM ISA.
+                * As of today (2014) that's exactly the members of the A and R
+                * classes.
+                */
+ AR_CLASS(     .arm    )
 start:
                .type   start,#function
                .rept   7
 
  THUMB(                .thumb                  )
 1:
- ARM_BE8(      setend  be )                    @ go BE8 if compiled for BE8
-               mrs     r9, cpsr
+ ARM_BE8(      setend  be              )       @ go BE8 if compiled for BE8
+ AR_CLASS(     mrs     r9, cpsr        )
 #ifdef CONFIG_ARM_VIRT_EXT
                bl      __hyp_stub_install      @ get into SVC mode, reversibly
 #endif
                mov     r7, r1                  @ save architecture ID
                mov     r8, r2                  @ save atags pointer
 
+#ifndef CONFIG_CPU_V7M
                /*
                 * Booting from Angel - need to enter SVC mode and disable
                 * FIQs/IRQs (numeric definitions from angel arm.h source).
                safe_svcmode_maskall r0
                msr     spsr_cxsf, r9           @ Save the CPU boot mode in
                                                @ SPSR
+#endif
                /*
                 * Note that some cache flushing and other stuff may
                 * be needed here - is there an Angel SWI call for this?
 call_cache_fn: adr     r12, proc_types
 #ifdef CONFIG_CPU_CP15
                mrc     p15, 0, r9, c0, c0      @ get processor ID
+#elif defined(CONFIG_CPU_V7M)
+               /*
+                * On v7-M the processor id is located in the V7M_SCB_CPUID
+                * register, but as cache handling is IMPLEMENTATION DEFINED on
+                * v7-M (if existant at all) we just return early here.
+                * If V7M_SCB_CPUID were used the cpu ID functions (i.e.
+                * __armv7_mmu_cache_{on,off,flush}) would be selected which
+                * use cp15 registers that are not implemented on v7-M.
+                */
+               bx      lr
 #else
                ldr     r9, =CONFIG_PROCESSOR_ID
 #endif
 
 __enter_kernel:
                mov     r0, #0                  @ must be 0
- ARM(          mov     pc, r4  )               @ call kernel
- THUMB(                bx      r4      )               @ entry point is always ARM
+ ARM(          mov     pc, r4          )       @ call kernel
+ M_CLASS(      add     r4, r4, #1      )       @ enter in Thumb mode for M class
+ THUMB(                bx      r4              )       @ entry point is always ARM for A/R classes
 
 reloc_code_end: