diff mbox

[v3] ARM: zImage: add support for ARMv7-M

Message ID 1411494565-29534-1-git-send-email-manabian@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Joachim Eastwood Sept. 23, 2014, 5:49 p.m. UTC
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 <manabian@gmail.com>
---
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(-)

Comments

Uwe Kleine-König Sept. 23, 2014, 7:32 p.m. UTC | #1
Hello Joachim,

On Tue, Sep 23, 2014 at 07:49:25PM +0200, Joachim Eastwood wrote:
> 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 <manabian@gmail.com>
> ---
> 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(-)
> 
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index 413fd94b5301..cd27090625fe 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,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?

>  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:
> @@ -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
Joachim Eastwood Sept. 23, 2014, 8:42 p.m. UTC | #2
On 23 September 2014 21:32, Uwe Kleine-König
<u.kleine-koenig@pengutronix.de> wrote:
> Hello Joachim,
>
> On Tue, Sep 23, 2014 at 07:49:25PM +0200, Joachim Eastwood wrote:
>> 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 <manabian@gmail.com>
>> ---
>> 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(-)
>>
>> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
>> index 413fd94b5301..cd27090625fe 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,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?


>>  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:
>> @@ -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
Uwe Kleine-König Sept. 23, 2014, 9:22 p.m. UTC | #3
Hello Joachim,

On Tue, Sep 23, 2014 at 10:42:57PM +0200, Joachim Eastwood wrote:
> On 23 September 2014 21:32, Uwe Kleine-König
> <u.kleine-koenig@pengutronix.de> wrote:
> >> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> >> index 413fd94b5301..cd27090625fe 100644
> >> --- a/arch/arm/boot/compressed/head.S
> >> +++ b/arch/arm/boot/compressed/head.S
> >> [...]
> >> @@ -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?
I don't know what ARM (the company) will invent in the future.
Today it's equivalent, yes.

> 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
diff mbox

Patch

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 413fd94b5301..cd27090625fe 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,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:
 
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