ARM: zImage: add support for ARMv7-M
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
@@ -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
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
@@ -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
PATCH 1/1 ARM: zImage: add support for ARMv7-M
In reply to Joachim Eastwoodarch/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 ARMarch/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
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 ARMarch/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 CPUsI think it would be much nicer to avoid sprinkling #ifdefs here. We already have the
ARM()andTHUMB()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
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 ARMarch/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 CPUsI think it would be much nicer to avoid sprinkling #ifdefs here. We already have the
ARM()andTHUMB()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
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 ARMarch/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 CPUsI think it would be much nicer to avoid sprinkling #ifdefs here. We already have the
ARM()andTHUMB()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_CLASSandA_CLASS(with or without underscore and maybeAR_CLASSif 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
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 ARMarch/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 CPUsI think it would be much nicer to avoid sprinkling #ifdefs here. We already have the
ARM()andTHUMB()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_CLASSandA_CLASS(with or without underscore and maybeAR_CLASSif 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. ButA_CLASSmight 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
PATCH v2 1/1 ARM: zImage: add support for ARMv7-M
In reply to Joachim EastwoodThis 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
@@ -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
@@ -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
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
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 classNitpick: 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 addressAnother 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
PATCH v3 1/1 ARM: zImage: add support for ARMv7-M
In reply to Joachim EastwoodThis 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
@@ -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
@@ -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
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.
Signed-off-by Joachim Eastwood <[email protected]>---
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 incompressed/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@@ -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
-0start: .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/ |
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.
Signed-off-by Joachim Eastwood <[email protected]>---
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 incompressed/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@@ -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 classesSemantically we don't want .arm when
CPU_THUMBONLYis 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
-0start: .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, reversiblyI think you need to be more precious here. The following is #ifdef'd out:
#endifmov 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 angelarm.hsource).
* We only do this if we were in user mode on entry. */
mrs r2, cpsr @ get current mode
tst r2, #3 @ not user?
bnenot_angel
mov r0, #0x17 @angel_SWIreason_EnterSVC
ARM( swi0x123456) @angel_SWI_ARM
THUMB( svc0xab) @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 +#endifAt 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
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@@ -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 classesSemantically we don't want .arm when
CPU_THUMBONLYis 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/ |
PATCH v4 1/1 ARM: zImage: add support for ARMv7-M
In reply to Joachim EastwoodThis 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
@@ -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
@@ -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
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.
Signed-off-by Joachim Eastwood <[email protected]>---
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 incompressed/head.S.Successfully tested on NXP LPC4357 (Cortex-M4).
regards,
Joachim Eastwoodarch/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@@ -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/ |