[PATCH v6] ARM: zImage: add support for ARMv7-M

Uwe Kleine-König u.kleine-koenig at pengutronix.de
Wed Dec 17 00:56:13 PST 2014


From: Joachim Eastwood <manabian at gmail.com>

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.

Signed-off-by: Joachim Eastwood <manabian at gmail.com>
[ukl: fix spelling in commit log, return early in call_cache_fn]
Signed-off-by: Uwe Kleine-König <u.kleine-koenig at pengutronix.de>
---
Hello,

I just picked up Joachim's patch and fixed the small concerns I had in
the last round.

I thought about adding a wrapper for accessing the CPUID registers that
are located in cp15 on v7-A/R and memory mapped on v7-M. The
corresponding registers and their address are as follows:

name		cp15 reg [1] on -A/R	address on -M
MIDR/CPUID  	CRm=c0, opc2=0  	0xe000ed00              
PFR0   		CRm=c1, opc2=0  	0xe000ed40
PFR1   		CRm=c1, opc2=1  	0xe000ed44
DFR0   		CRm=c1, opc2=2  	0xe000ed48
AFR0   		CRm=c1, opc2=3  	0xe000ed4c
MMFR0  		CRm=c1, opc2=4  	0xe000ed50
MMFR1  		CRm=c1, opc2=5  	0xe000ed54
MMFR2  		CRm=c1, opc2=6  	0xe000ed58
MMFR3  		CRm=c1, opc2=7  	0xe000ed5c
ISAR0  		CRm=c2, opc2=0  	0xe000ed60
ISAR1  		CRm=c2, opc2=1  	0xe000ed64
ISAR2  		CRm=c2, opc2=2  	0xe000ed68
ISAR3  		CRm=c2, opc2=3  	0xe000ed6c
ISAR4  		CRm=c2, opc2=4  	0xe000ed70
ISAR5  		CRm=c2, opc2=5  	0xe000ed74

But there is no nice translation and as cache handling is implementation
defined on v7-M anyhow there is not much use and I decided to just
return early in the cache function.

This patch is only compile tested as I don't have a machine with enough
RAM to run a non-XIP kernel, so Tested-by tags are welcome.

Best regards
Uwe

[1] all have in common: CRn=c0, opc1=0, so only CRm and opc2 are listed

 arch/arm/boot/compressed/head.S | 33 +++++++++++++++++++++++++++------
 arch/arm/include/asm/unified.h  |  8 ++++++++
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 68be9017593d..3788eedabb15 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -10,8 +10,11 @@
  */
 #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
  *
@@ -114,7 +117,12 @@
  * 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?
@@ -789,6 +799,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
@@ -1289,8 +1309,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:
 
diff --git a/arch/arm/include/asm/unified.h b/arch/arm/include/asm/unified.h
index b88beaba6b4a..200f9a7cd623 100644
--- a/arch/arm/include/asm/unified.h
+++ b/arch/arm/include/asm/unified.h
@@ -24,6 +24,14 @@
 	.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
-- 
2.1.3




More information about the linux-arm-kernel mailing list