Skip to contentSkip to conversation

ARM: zImage: add support for ARMv7-M

PATCH New Joachim Eastwood 4 participants 16 messages Sep 18, 2014 – Sep 28, 2014 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ARM: zImage: add support for ARMv7-M

This patch makes it possible to enter zImage in Thumb mode for ARMv7M (Cortex-M) CPUs that does not support ARM mode. The kernel entry is also made in Thumb mode.

---
Hi,

This patch is loosely based on the Cortex-M old support patch by Catalin Marinas. A lot has happend to compressed/head.S since 2010 but the general placement of some of ifdefs are the same.

Successfully tested on NXP LPC4357 (Cortex-M4).

I just noticed that there is CONFIG_CPU_THUMBONLY config symbol. Would it be better to use that in this file?

regards
Joachim Eastwood

 arch/arm/boot/compressed/head.S | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)
arch/arm/boot/compressed/head.S +19 -2
index 413fd94b5301..6ffccb5283e6 100644
@@ -11,7 +11,12 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
+#ifdef CONFIG_CPU_V7M
+	.arch	armv7-m
+#else
 	.arch	armv7-a
+#endif
+
 /*
  * Debugging stuff
  *
@@ -114,7 +119,9 @@
  * sort out different calling conventions
  */
 		.align
-		.arm				@ Always enter in ARM state
+#ifndef CONFIG_CPU_V7M
+		.arm			@ Always enter in ARM state for non ARMv7M CPUs
+#endif
 start:
 		.type	start,#function
 		.rept	7
@@ -133,6 +140,7 @@ start:
  THUMB(		.thumb			)
 1:
  ARM_BE8(	setend	be )			@ go BE8 if compiled for BE8
+#ifndef CONFIG_CPU_V7M
 		mrs	r9, cpsr
 #ifdef CONFIG_ARM_VIRT_EXT
 		bl	__hyp_stub_install	@ get into SVC mode, reversibly
@@ -155,6 +163,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?
@@ -790,6 +799,9 @@ __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)
+		ldr	r9, =0xe000ed00		@ CPUID register address
+		ldr	r9, [r9]
 #else
 		ldr	r9, =CONFIG_PROCESSOR_ID
 #endif
@@ -945,11 +957,13 @@ proc_types:
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv6_mmu_cache_flush
 
+#ifndef CONFIG_CPU_V7M
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
 		W(b)	__armv7_mmu_cache_on
 		W(b)	__armv7_mmu_cache_off
 		W(b)	__armv7_mmu_cache_flush
+#endif
 
 		.word	0			@ unrecognised type
 		.word	0
@@ -1278,7 +1292,10 @@ __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
+#ifdef CONFIG_CPU_V7M
+		add	r4, r4, #1		@ enter in Thumb mode for ARMv7M
+#endif
+ THUMB(		bx	r4	)		@ entry point is always ARM for non ARMv7M CPUs
 
 reloc_code_end:
 
Signature · 1 line
1.8.0
#1 lore raw

PATCH 1/1 arm: kbuild: make uImage entry an odd number on ARMv7-M

This allows U-Boot to branch to the kernel in Thumb mode on ARMv7M CPUs that doesn't support ARM mode.

---
Hi,

Based on old "Make the uImage entry an odd number" e2ed3be7319f2734 patch by Catalin Marinas.

regards
Joachim Eastwood

 arch/arm/boot/Makefile | 5 +++++
 1 file changed, 5 insertions(+)
arch/arm/boot/Makefile +5 -0
index ec2f8065f955..bb68035e42f2 100644
@@ -75,6 +75,11 @@ if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \
 	false; \
 fi
 
+ifeq ($(CONFIG_CPU_V7M),y)
+  # Set bit 0 to 1 so that Thumb mode is used
+  UIMAGE_ENTRYADDR=$(shell echo $(UIMAGE_LOADADDR) | sed -e "s/.$$/1/")
+endif
+
 $(obj)/uImage:	$(obj)/zImage FORCE
 	@$(check_for_multiple_loadaddr)
 	$(call if_changed,uimage)
Signature · 1 line
1.8.0
#2 lore raw

PATCH 1/1 ARM: zImage: add support for ARMv7-M

In reply to Joachim Eastwood

arch/arm/boot/compressed/head.S __hyp_reentry_vectors: · line 1298

Quoted 7 lines · Joachim Eastwood
  ARM(          mov     pc, r4  )               @ call kernel
- THUMB(                bx      r4      )               @ entry point is always ARM
arch/arm/boot/compressed/head.S +4 -0
+#ifdef CONFIG_CPU_V7M
+               add     r4, r4, #1              @ enter in Thumb mode for ARMv7M
+#endif
+ THUMB(                bx      r4      )               @ entry point is always ARM for non ARMv7M CPUs

I think it would be much nicer to avoid sprinkling #ifdefs here. We already have the ARM() and THUMB() macros to deal with the two cases we support, which are booting in ARM mode vs ARMv7-A with THUMB2 mode. We can probably add another macro like this to deal with the ARMv7-M case that does not have ARM mode.

Arnd

#3 lore raw

PATCH 1/1 ARM: zImage: add support for ARMv7-M

Quoted 14 lines · Arnd Bergmann

arch/arm/boot/compressed/head.S __hyp_reentry_vectors: · line 1298

Quoted 7 lines · Joachim Eastwood
  ARM(          mov     pc, r4  )               @ call kernel
- THUMB(                bx      r4      )               @ entry point is always ARM
arch/arm/boot/compressed/head.S +4 -0
+#ifdef CONFIG_CPU_V7M
+               add     r4, r4, #1              @ enter in Thumb mode for ARMv7M
+#endif
+ THUMB(                bx      r4      )               @ entry point is always ARM for non ARMv7M CPUs

I think it would be much nicer to avoid sprinkling #ifdefs here. We already have the ARM() and THUMB() macros to deal with the two cases we support, which are booting in ARM mode vs ARMv7-A with THUMB2 mode. We can probably add another macro like this to deal with the ARMv7-M case that does not have ARM mode.

Well, I guess I could make a THUMBONLY macro or something like that. But I think that the macro would only be useful in the case you quoted above. The other ifdefs in the patch are either for large blocks or removing code. So I don't think it would improve the patch a great deal.

btw, do you have better name suggestion than THUMBONLY?

regards
Joachim Eastwood

#4 lore raw

PATCH 1/1 ARM: zImage: add support for ARMv7-M

Quoted 16 lines · Joachim Eastwood
Quoted 14 lines · Arnd Bergmann

arch/arm/boot/compressed/head.S __hyp_reentry_vectors: · line 1298

Quoted 7 lines · Joachim Eastwood
  ARM(          mov     pc, r4  )               @ call kernel
- THUMB(                bx      r4      )               @ entry point is always ARM
arch/arm/boot/compressed/head.S +4 -0
+#ifdef CONFIG_CPU_V7M
+               add     r4, r4, #1              @ enter in Thumb mode for ARMv7M
+#endif
+ THUMB(                bx      r4      )               @ entry point is always ARM for non ARMv7M CPUs

I think it would be much nicer to avoid sprinkling #ifdefs here. We already have the ARM() and THUMB() macros to deal with the two cases we support, which are booting in ARM mode vs ARMv7-A with THUMB2 mode. We can probably add another macro like this to deal with the ARMv7-M case that does not have ARM mode.

Quoted 7 lines

Well, I guess I could make a THUMBONLY macro or something like that. But I think that the macro would only be useful in the case you quoted above. The other ifdefs in the patch are either for large blocks or removing code. So I don't think it would improve the patch a great deal.

btw, do you have better name suggestion than THUMBONLY?

It looks like you would need the reverse as well, !THUMBONLY. What about M_CLASS and A_CLASS (with or without underscore and maybe AR_CLASS if we ever need to differentiate between A and R)?

Signature · 1 line
Catalin
#5 lore raw

PATCH 1/1 ARM: zImage: add support for ARMv7-M

Quoted 23 lines · Catalin Marinas
Quoted 22 lines · Joachim Eastwood
Quoted 14 lines · Arnd Bergmann

arch/arm/boot/compressed/head.S __hyp_reentry_vectors: · line 1298

Quoted 7 lines · Joachim Eastwood
  ARM(          mov     pc, r4  )               @ call kernel
- THUMB(                bx      r4      )               @ entry point is always ARM
arch/arm/boot/compressed/head.S +4 -0
+#ifdef CONFIG_CPU_V7M
+               add     r4, r4, #1              @ enter in Thumb mode for ARMv7M
+#endif
+ THUMB(                bx      r4      )               @ entry point is always ARM for non ARMv7M CPUs

I think it would be much nicer to avoid sprinkling #ifdefs here. We already have the ARM() and THUMB() macros to deal with the two cases we support, which are booting in ARM mode vs ARMv7-A with THUMB2 mode. We can probably add another macro like this to deal with the ARMv7-M case that does not have ARM mode.

Well, I guess I could make a THUMBONLY macro or something like that. But I think that the macro would only be useful in the case you quoted above. The other ifdefs in the patch are either for large blocks or removing code. So I don't think it would improve the patch a great deal.

Quoted 5 lines
Quoted 1 line

btw, do you have better name suggestion than THUMBONLY?

It looks like you would need the reverse as well, !THUMBONLY. What about M_CLASS and A_CLASS (with or without underscore and maybe AR_CLASS if we ever need to differentiate between A and R)?

Yes, that would remove more of the ifdefs.
With M_CLASS/A_CLASS macros I could also wrap ".arch armv7-m" and ".arm" directives. But A_CLASS might look a bit strange when used for ARM CPUs that are not called Cortex.

I'll cook up a new patch and see how it turns out.

regards,
Joachim Eastwood

#6 lore raw

PATCH 1/1 ARM: zImage: add support for ARMv7-M

Quoted 26 lines · Joachim Eastwood
Quoted 25 lines · Catalin Marinas
Quoted 23 lines · Joachim Eastwood
Quoted 14 lines · Arnd Bergmann

arch/arm/boot/compressed/head.S __hyp_reentry_vectors: · line 1298

Quoted 7 lines · Joachim Eastwood
  ARM(          mov     pc, r4  )               @ call kernel
- THUMB(                bx      r4      )               @ entry point is always ARM
arch/arm/boot/compressed/head.S +4 -0
+#ifdef CONFIG_CPU_V7M
+               add     r4, r4, #1              @ enter in Thumb mode for ARMv7M
+#endif
+ THUMB(                bx      r4      )               @ entry point is always ARM for non ARMv7M CPUs

I think it would be much nicer to avoid sprinkling #ifdefs here. We already have the ARM() and THUMB() macros to deal with the two cases we support, which are booting in ARM mode vs ARMv7-A with THUMB2 mode. We can probably add another macro like this to deal with the ARMv7-M case that does not have ARM mode.

Well, I guess I could make a THUMBONLY macro or something like that. But I think that the macro would only be useful in the case you quoted above. The other ifdefs in the patch are either for large blocks or removing code. So I don't think it would improve the patch a great deal.

btw, do you have better name suggestion than THUMBONLY?

Quoted 8 lines
Quoted 3 lines

It looks like you would need the reverse as well, !THUMBONLY. What about M_CLASS and A_CLASS (with or without underscore and maybe AR_CLASS if we ever need to differentiate between A and R)?

Yes, that would remove more of the ifdefs.
With M_CLASS/A_CLASS macros I could also wrap ".arch armv7-m" and ".arm" directives. But A_CLASS might look a bit strange when used for ARM CPUs that are not called Cortex.

'A' in this context does not refer to Cortex CPUs. The ARM Architecture Reference Class defines three classes:

A - Application class (MMU)
R - Real-time class (no MMU, usually with an MPU, more deterministic) M - Microcontroller class (no MMU, simpler exception model aimed at bare
metal applications)

The A and R class are covered by the same ARM ARM book while the M class has a separate reference manual. That's why for some macros were we target both A and R classes I suggested AR_CLASS.

Signature · 1 line
Catalin
#7 lore raw

PATCH v2 1/1 ARM: zImage: add support for ARMv7-M

In reply to Joachim Eastwood

This patch makes it possible to enter zImage in Thumb mode for ARMv7M (Cortex-M) CPUs that does not support ARM mode. The kernel entry is also made in Thumb mode.

---
Hi,

Updated version of the patch which introduce AR_CLASS/M_CLASS macros as suggested by Catalin. This reduces the amount of ifdefs needed in compressed/head.S.

Successfully tested on NXP LPC4357 (Cortex-M4).

regards,
Joachim Eastwood

 arch/arm/boot/compressed/head.S | 18 ++++++++++++++----
 arch/arm/include/asm/unified.h  |  8 ++++++++
 2 files changed, 22 insertions(+), 4 deletions(-)
arch/arm/boot/compressed/head.S +14 -4
index 413fd94b5301..75edba37bc04 100644
@@ -11,7 +11,9 @@
 #include <linux/linkage.h>
 #include <asm/assembler.h>
 
-	.arch	armv7-a
+ AR_CLASS(	.arch	armv7-a)
+ M_CLASS(	.arch	armv7-m)
+
 /*
  * Debugging stuff
  *
@@ -114,7 +116,7 @@
  * sort out different calling conventions
  */
 		.align
-		.arm				@ Always enter in ARM state
+ AR_CLASS(	.arm	)		@ Always enter in ARM state for AR class
 start:
 		.type	start,#function
 		.rept	7
@@ -133,6 +135,7 @@ start:
  THUMB(		.thumb			)
 1:
  ARM_BE8(	setend	be )			@ go BE8 if compiled for BE8
+#ifndef CONFIG_CPU_V7M
 		mrs	r9, cpsr
 #ifdef CONFIG_ARM_VIRT_EXT
 		bl	__hyp_stub_install	@ get into SVC mode, reversibly
@@ -155,6 +158,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?
@@ -790,6 +794,9 @@ __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)
+		ldr	r9, =0xe000ed00		@ CPUID register address
+		ldr	r9, [r9]
 #else
 		ldr	r9, =CONFIG_PROCESSOR_ID
 #endif
@@ -945,11 +952,13 @@ proc_types:
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv6_mmu_cache_flush
 
+#ifndef CONFIG_CPU_V7M
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
 		W(b)	__armv7_mmu_cache_on
 		W(b)	__armv7_mmu_cache_off
 		W(b)	__armv7_mmu_cache_flush
+#endif
 
 		.word	0			@ unrecognised type
 		.word	0
@@ -1277,8 +1286,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 AR class
 
 reloc_code_end:
 
arch/arm/include/asm/unified.h +8 -0
index b88beaba6b4a..200f9a7cd623 100644
@@ -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
Signature · 1 line
1.8.0
#8 lore raw

PATCH v2 1/1 ARM: zImage: add support for ARMv7-M

arch/arm/boot/compressed/head.S line 119

Quoted 3 lines · Joachim Eastwood
arch/arm/boot/compressed/head.S +1 -1
 		.align
-		.arm				@ Always enter in ARM state
+ AR_CLASS(	.arm	)		@ Always enter in ARM state for AR class

Nitpick: A/R class (or classes).

arch/arm/boot/compressed/head.S __common_mmu_cache_on: · line 798

Quoted 2 lines
arch/arm/boot/compressed/head.S +2 -0
+#elif defined(CONFIG_CPU_V7M)
+		ldr	r9, =0xe000ed00		@ CPUID register address

Another nitpick: can you use some macro? We define them in arch/arm/include/asm/v7m.h, so you could write the above as (untested):

		ldr	r9, =BASEADDR_V7M_SCB + V7M_SCB_CPUID
Signature · 1 line
Catalin
#9 lore raw

PATCH v2 1/1 ARM: zImage: add support for ARMv7-M

Quoted 6 lines · Catalin Marinas
Quoted 3 lines · Joachim Eastwood

.align
- .arm @ Always enter in ARM state
+ AR_CLASS( .arm ) @ Always enter in ARM state for AR class

Nitpick: A/R class (or classes).

Sure.

Quoted 7 lines

arch/arm/boot/compressed/head.S __common_mmu_cache_on: · line 798

Quoted 2 lines
arch/arm/boot/compressed/head.S +2 -0
+#elif defined(CONFIG_CPU_V7M)
+             ldr     r9, =0xe000ed00         @ CPUID register address

Another nitpick: can you use some macro? We define them in arch/arm/include/asm/v7m.h, so you could write the above as (untested):

ldr r9, =BASEADDR_V7M_SCB + V7M_SCB_CPUID

I'll use the version from head-nommu.S, which does this:
ldr r9, =BASEADDR_V7M_SCB
ldr r9, [r9, V7M_SCB_CPUID]

I'll send out an updated patch soon.

regards
Joachim Eastwood

#10 lore raw

PATCH v3 1/1 ARM: zImage: add support for ARMv7-M

In reply to Joachim Eastwood

This patch makes it possible to enter zImage in Thumb mode for ARMv7M (Cortex-M) CPUs that does not support ARM mode. The kernel entry is also made in Thumb mode.

---
Hi,

Updated patch per comments from Catalin Marinas.

Changes
v3: Use defines for ARMv7M CPU registers.
v2: Introduce AR_CLASS/M_CLASS macros. This reduces the amount
of ifdefs needed in compressed/head.S.

Successfully tested on NXP LPC4357 (Cortex-M4).

regards,
Joachim Eastwood

 arch/arm/boot/compressed/head.S | 19 +++++++++++++++----
 arch/arm/include/asm/unified.h  |  8 ++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)
arch/arm/boot/compressed/head.S +15 -4
index 413fd94b5301..cd27090625fe 100644
@@ -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,7 @@
  * sort out different calling conventions
  */
 		.align
-		.arm				@ Always enter in ARM state
+ AR_CLASS(	.arm	)		@ Always enter in ARM state for A/R classes
 start:
 		.type	start,#function
 		.rept	7
@@ -133,6 +136,7 @@ start:
  THUMB(		.thumb			)
 1:
  ARM_BE8(	setend	be )			@ go BE8 if compiled for BE8
+#ifndef CONFIG_CPU_V7M
 		mrs	r9, cpsr
 #ifdef CONFIG_ARM_VIRT_EXT
 		bl	__hyp_stub_install	@ get into SVC mode, reversibly
@@ -155,6 +159,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?
@@ -790,6 +795,9 @@ __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)
+		ldr	r9, =BASEADDR_V7M_SCB
+		ldr	r9, [r9, V7M_SCB_CPUID]
 #else
 		ldr	r9, =CONFIG_PROCESSOR_ID
 #endif
@@ -945,11 +953,13 @@ proc_types:
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv6_mmu_cache_flush
 
+#ifndef CONFIG_CPU_V7M
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
 		W(b)	__armv7_mmu_cache_on
 		W(b)	__armv7_mmu_cache_off
 		W(b)	__armv7_mmu_cache_flush
+#endif
 
 		.word	0			@ unrecognised type
 		.word	0
@@ -1277,8 +1287,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 AR class
 
 reloc_code_end:
 
arch/arm/include/asm/unified.h +8 -0
index b88beaba6b4a..200f9a7cd623 100644
@@ -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
Signature · 1 line
1.8.0
#11 lore raw

PATCH v3 1/1 ARM: zImage: add support for ARMv7-M

Hello Joachim,

Quoted 39 lines · Joachim Eastwood

This patch makes it possible to enter zImage in Thumb mode for ARMv7M (Cortex-M) CPUs that does not support ARM mode. The kernel entry is also made in Thumb mode.

---
Hi,

Updated patch per comments from Catalin Marinas.

Changes
v3: Use defines for ARMv7M CPU registers.
v2: Introduce AR_CLASS/M_CLASS macros. This reduces the amount
of ifdefs needed in compressed/head.S.

Successfully tested on NXP LPC4357 (Cortex-M4).

 arch/arm/boot/compressed/head.S | 19 +++++++++++++++----
 arch/arm/include/asm/unified.h  |  8 ++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)
arch/arm/boot/compressed/head.S +4 -1
index 413fd94b5301..cd27090625fe 100644
@@ -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
  *

arch/arm/boot/compressed/head.S line 120

Quoted 5 lines
arch/arm/boot/compressed/head.S +1 -1
@@ -114,7 +117,7 @@
  * sort out different calling conventions
  */
 		.align
-		.arm				@ Always enter in ARM state
+ AR_CLASS(	.arm	)		@ Always enter in ARM state for A/R classes

Semantically we don't want .arm when CPU_THUMBONLY is enabled. At least currently this is equivalent with !AR_CLASS. Maybe this is worth to be pointed out in a comment?

arch/arm/boot/compressed/head.S start: · line 142

Quoted 11 lines
arch/arm/boot/compressed/head.S +1 -0
 start:
 		.type	start,#function
 		.rept	7
@@ -133,6 +136,7 @@ start:
  THUMB(		.thumb			)
 1:
  ARM_BE8(	setend	be )			@ go BE8 if compiled for BE8
+#ifndef CONFIG_CPU_V7M
 		mrs	r9, cpsr
 #ifdef CONFIG_ARM_VIRT_EXT
 		bl	__hyp_stub_install	@ get into SVC mode, reversibly

I think you need to be more precious here. The following is #ifdef'd out:
#endif
mov r7, r1 @ save architecture ID
mov r8, r2 @ save atags pointer

/*
* Booting from Angel - need to enter SVC mode and disable

		 * FIQs/IRQs (numeric definitions from angel arm.h source).
		 * We only do this if we were in user mode on entry.
		 */
		mrs	r2, cpsr		@ get current mode
		tst	r2, #3			@ not user?
		bne	not_angel
		mov	r0, #0x17		@ angel_SWIreason_EnterSVC
    ARM(	swi	0x123456	)	@ angel_SWI_ARM
    THUMB(	svc	0xab		)	@ angel_SWI_THUMB

not_angel:

arch/arm/boot/compressed/head.S not_angel: · line 162

Quoted 5 lines
arch/arm/boot/compressed/head.S +1 -0
@@ -155,6 +159,7 @@ not_angel:
 		safe_svcmode_maskall r0
 		msr	spsr_cxsf, r9		@ Save the CPU boot mode in
 						@ SPSR
+#endif

At least saving r1 and r2 should be preserved, shouldn't it? I wonder how this could result in a working kernel because r7 and r8 are passed to Image which are not initialized with your patch.

Unrelated to Joachim's patch I wonder why we have "mrs rX, cpsr" twice
here.

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
#12 lore raw

PATCH v3 1/1 ARM: zImage: add support for ARMv7-M

Quoted 37 lines · Uwe Kleine-K?nig

Hello Joachim,

Quoted 34 lines · Joachim Eastwood

This patch makes it possible to enter zImage in Thumb mode for ARMv7M (Cortex-M) CPUs that does not support ARM mode. The kernel entry is also made in Thumb mode.

---
Hi,

Updated patch per comments from Catalin Marinas.

Changes
v3: Use defines for ARMv7M CPU registers.
v2: Introduce AR_CLASS/M_CLASS macros. This reduces the amount
of ifdefs needed in compressed/head.S.

Successfully tested on NXP LPC4357 (Cortex-M4).

 arch/arm/boot/compressed/head.S | 19 +++++++++++++++----
 arch/arm/include/asm/unified.h  |  8 ++++++++
 2 files changed, 23 insertions(+), 4 deletions(-)
arch/arm/boot/compressed/head.S +4 -0
index 413fd94b5301..cd27090625fe 100644
@@ -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 )
 
Quoted 13 lines

arch/arm/boot/compressed/head.S line 120

Quoted 10 lines
arch/arm/boot/compressed/head.S +1 -2
-     .arch   armv7-a
 /*
  * Debugging stuff
  *
@@ -114,7 +117,7 @@
  * sort out different calling conventions
  */
              .align
-             .arm                            @ Always enter in ARM state
+ AR_CLASS(   .arm    )               @ Always enter in ARM state for A/R classes

Semantically we don't want .arm when CPU_THUMBONLY is enabled. At least currently this is equivalent with !AR_CLASS. Maybe this is worth to be pointed out in a comment?

Won't THUMBONLY always mean !AR_CLASS?

Do you have a particular comment in mind?

Quoted 29 lines

arch/arm/boot/compressed/head.S start: · line 142

Quoted 11 lines
arch/arm/boot/compressed/head.S +1 -0
 start:
              .type   start,#function
              .rept   7
@@ -133,6 +136,7 @@ start:
  THUMB(              .thumb                  )
 1:
  ARM_BE8(    setend  be )                    @ go BE8 if compiled for BE8
+#ifndef CONFIG_CPU_V7M
              mrs     r9, cpsr
 #ifdef CONFIG_ARM_VIRT_EXT
              bl      __hyp_stub_install      @ get into SVC mode, reversibly

I think you need to be more precious here. The following is #ifdef'd out:
#endif

                mov     r7, r1                  @ save architecture ID
                mov     r8, r2                  @ save atags pointer

/*
* Booting from Angel - need to enter SVC mode and disable
* FIQs/IRQs (numeric definitions from angel arm.h source).
* We only do this if we were in user mode on entry. */
mrs r2, cpsr @ get current mode
tst r2, #3 @ not user?
bne not_angel
mov r0, #0x17 @ angel_SWIreason_EnterSVC
ARM( swi 0x123456 ) @ angel_SWI_ARM
THUMB( svc 0xab ) @ angel_SWI_THUMB
not_angel:

Quoted 9 lines

arch/arm/boot/compressed/head.S not_angel: · line 162

Quoted 5 lines
arch/arm/boot/compressed/head.S +1 -0
@@ -155,6 +159,7 @@ not_angel:
              safe_svcmode_maskall r0
              msr     spsr_cxsf, r9           @ Save the CPU boot mode in
                                              @ SPSR
+#endif

At least saving r1 and r2 should be preserved, shouldn't it? I wonder how this could result in a working kernel because r7 and r8 are passed to Image which are not initialized with your patch.

Yes, r1 and r2 should be preserved. I have a workaround for the bootloader in my kernel tree which might explain why it still worked...
I'll send an updated patch tomorrow.

Thanks for looking.

regards
Joachim Eastwood

#13 lore raw

PATCH v3 1/1 ARM: zImage: add support for ARMv7-M

Hello Joachim,

Quoted 17 lines · Joachim Eastwood
Quoted 6 lines · Uwe Kleine-K?nig
Quoted 6 lines
arch/arm/boot/compressed/head.S +0 -0
index 413fd94b5301..cd27090625fe 100644
[...]
@@ -114,7 +117,7 @@
Quoted 8 lines

arch/arm/boot/compressed/head.S line 120

Quoted 5 lines
arch/arm/boot/compressed/head.S +1 -1
  * sort out different calling conventions
  */
              .align
-             .arm                            @ Always enter in ARM state
+ AR_CLASS(   .arm    )               @ Always enter in ARM state for A/R classes

Semantically we don't want .arm when CPU_THUMBONLY is enabled. At least currently this is equivalent with !AR_CLASS. Maybe this is worth to be pointed out in a comment?

Quoted 1 line

Won't THUMBONLY always mean !AR_CLASS?

I don't know what ARM (the company) will invent in the future. Today it's equivalent, yes.

Quoted 1 line

Do you have a particular comment in mind?

Something like:

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.

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
#14 lore raw

PATCH v4 1/1 ARM: zImage: add support for ARMv7-M

In reply to Joachim Eastwood

This patch makes it possible to enter zImage in Thumb mode for ARMv7M (Cortex-M) CPUs that does not support ARM mode. The kernel entry is also made in Thumb mode.

---
Hi,

Updated patch with comments from Uwe Kleine-K?nig.

Changes
v4: Preserve r1/r2. Add comment about class A/R.
v3: Use defines for ARMv7M CPU registers.
v2: Introduce AR_CLASS/M_CLASS macros. This reduces the amount
of ifdefs needed in compressed/head.S.

Successfully tested on NXP LPC4357 (Cortex-M4).

regards,
Joachim Eastwood

 arch/arm/boot/compressed/head.S | 28 ++++++++++++++++++++++------
 arch/arm/include/asm/unified.h  |  8 ++++++++
 2 files changed, 30 insertions(+), 6 deletions(-)
arch/arm/boot/compressed/head.S +22 -6
index 413fd94b5301..0afcbb1e1d7d 100644
@@ -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?
@@ -790,6 +800,9 @@ __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)
+		ldr	r9, =BASEADDR_V7M_SCB
+		ldr	r9, [r9, V7M_SCB_CPUID]
 #else
 		ldr	r9, =CONFIG_PROCESSOR_ID
 #endif
@@ -945,11 +958,13 @@ proc_types:
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv6_mmu_cache_flush
 
+#ifndef CONFIG_CPU_V7M
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
 		W(b)	__armv7_mmu_cache_on
 		W(b)	__armv7_mmu_cache_off
 		W(b)	__armv7_mmu_cache_flush
+#endif
 
 		.word	0			@ unrecognised type
 		.word	0
@@ -1277,8 +1292,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:
 
arch/arm/include/asm/unified.h +8 -0
index b88beaba6b4a..200f9a7cd623 100644
@@ -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
Signature · 1 line
1.8.0
#15 lore raw

PATCH v4 1/1 ARM: zImage: add support for ARMv7-M

Hello Joachim,

Quoted 1 line · Joachim Eastwood

This patch makes it possible to enter zImage in Thumb mode for ARMv7M

The official spelling is ARMv7-M.

Quoted 92 lines

(Cortex-M) CPUs that does not support ARM mode. The kernel entry is also made in Thumb mode.

---
Hi,

Updated patch with comments from Uwe Kleine-K?nig.

Changes
v4: Preserve r1/r2. Add comment about class A/R.
v3: Use defines for ARMv7M CPU registers.
v2: Introduce AR_CLASS/M_CLASS macros. This reduces the amount
of ifdefs needed in compressed/head.S.

Successfully tested on NXP LPC4357 (Cortex-M4).

regards,
Joachim Eastwood

 arch/arm/boot/compressed/head.S | 28 ++++++++++++++++++++++------
 arch/arm/include/asm/unified.h  |  8 ++++++++
 2 files changed, 30 insertions(+), 6 deletions(-)
arch/arm/boot/compressed/head.S +17 -4
index 413fd94b5301..0afcbb1e1d7d 100644
@@ -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?
@@ -790,6 +800,9 @@ __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)
+		ldr	r9, =BASEADDR_V7M_SCB
+		ldr	r9, [r9, V7M_SCB_CPUID]
 #else
 		ldr	r9, =CONFIG_PROCESSOR_ID
 #endif

arch/arm/boot/compressed/head.S proc_types: · line 967

Quoted 10 lines
arch/arm/boot/compressed/head.S +2 -0
@@ -945,11 +958,13 @@ proc_types:
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv6_mmu_cache_flush
 
+#ifndef CONFIG_CPU_V7M
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
 		W(b)	__armv7_mmu_cache_on
 		W(b)	__armv7_mmu_cache_off
 		W(b)	__armv7_mmu_cache_flush
+#endif

this #ifndef is needed because it is matched for V7-M CPU, but __armv7_mmu_cache_\* is wrong for these, right?

So I suggest adding a comment here, something like:

/*
* v7-M CPUs match this entry, but the cache handling is
* different to v7-A and v7-R. So this entry has to be
* skipped for v7-M builds.
*/

Alternatives are:
- Find a way to differentiate the AR and M classes.
I think you cannot by just looking at the CPU ID value, so the selection of the right functions would need to become more (compl|sophist)icated.
- As there is no v7-M cache architecurally defined, return early in the #elif branch above (line 803).

I think the first option isn't practicable. The second is IMHO a nice alternative.

Best regards
Uwe

Signature · 2 lines
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |