diff mbox

ARM: zImage: add support for ARMv7-M

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

Commit Message

Joachim Eastwood Sept. 18, 2014, 4:22 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,

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(-)

Comments

Arnd Bergmann Sept. 18, 2014, 5:38 p.m. UTC | #1
On Thursday 18 September 2014, Joachim Eastwood wrote:
>   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
>  

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
Joachim Eastwood Sept. 18, 2014, 6:34 p.m. UTC | #2
On 18 September 2014 19:38, Arnd Bergmann <arnd@arndb.de> wrote:
> On Thursday 18 September 2014, Joachim Eastwood wrote:
>>   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
>>
>
> 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
Catalin Marinas Sept. 19, 2014, 10:33 a.m. UTC | #3
On Thu, Sep 18, 2014 at 07:34:47PM +0100, Joachim Eastwood wrote:
> On 18 September 2014 19:38, Arnd Bergmann <arnd@arndb.de> wrote:
> > On Thursday 18 September 2014, Joachim Eastwood wrote:
> >>   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
> >>
> >
> > 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?

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)?
Joachim Eastwood Sept. 19, 2014, 12:40 p.m. UTC | #4
On 19 September 2014 12:33, Catalin Marinas <catalin.marinas@arm.com> wrote:
> On Thu, Sep 18, 2014 at 07:34:47PM +0100, Joachim Eastwood wrote:
>> On 18 September 2014 19:38, Arnd Bergmann <arnd@arndb.de> wrote:
>> > On Thursday 18 September 2014, Joachim Eastwood wrote:
>> >>   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
>> >>
>> >
>> > 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?
>
> 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
Catalin Marinas Sept. 19, 2014, 1:35 p.m. UTC | #5
On Fri, Sep 19, 2014 at 01:40:41PM +0100, Joachim Eastwood wrote:
> On 19 September 2014 12:33, Catalin Marinas <catalin.marinas@arm.com> wrote:
> > On Thu, Sep 18, 2014 at 07:34:47PM +0100, Joachim Eastwood wrote:
> >> On 18 September 2014 19:38, Arnd Bergmann <arnd@arndb.de> wrote:
> >> > On Thursday 18 September 2014, Joachim Eastwood wrote:
> >> >>   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
> >> >>
> >> >
> >> > 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?
> >
> > 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.
diff mbox

Patch

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 413fd94b5301..6ffccb5283e6 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -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: