ARM: 8327/1: zImage: add support for ARMv7-M
authorJoachim Eastwood <manabian@gmail.com>
Wed, 25 Mar 2015 07:47:18 +0000 (08:47 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Sat, 28 Mar 2015 16:54:53 +0000 (16:54 +0000)
This patch makes it possible to enter zImage in Thumb mode for ARMv7-M
(Cortex-M) CPUs that do not support ARM mode. The kernel entry is also
made in Thumb mode.

[ukl: fix spelling in commit log, return early in call_cache_fn]

Signed-off-by: Joachim Eastwood <manabian@gmail.com>
Tested-by: Stefan Agner <stefan@agner.ch>
Tested-by: Ezequiel Garcia <ezequiel@vanguardiasur.com.ar>
Tested-by: Chanwoo Choi <cw00.choi@samsung.com>
Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/boot/compressed/head.S
arch/arm/include/asm/unified.h

index 55a3532..2c45b57 100644 (file)
  */
 #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
@@ -132,14 +140,15 @@ start:
 
  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).
@@ -155,6 +164,7 @@ not_angel:
                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?
@@ -827,6 +837,16 @@ __common_mmu_cache_on:
 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
@@ -1327,8 +1347,9 @@ __hyp_reentry_vectors:
 
 __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:
 
index b88beab..200f9a7 100644 (file)
        .syntax unified
 #endif
 
+#ifdef CONFIG_CPU_V7M
+#define AR_CLASS(x...)
+#define M_CLASS(x...)  x
+#else
+#define AR_CLASS(x...) x
+#define M_CLASS(x...)
+#endif
+
 #ifdef CONFIG_THUMB2_KERNEL
 
 #if __GNUC__ < 4