Skip to contentSkip to conversation

ARM: Initial support for Cortex-M3

PATCH Superseded Uwe Kleine-König 2 participants 7 messages Apr 4, 2012 – Apr 23, 2012

Subsystems (2)

v4 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v4 cover ARM: Initial support for Cortex-M3

Hello,

I rebased the series to 3.4-rc1. Apart from the asm/system.h disintegration this was trivial and git did it just right for me.

I dropped patch 3 (ARM: force branch instructions to use long distance encoding) as I don't need that anymore for reasons I didn't try to find out. With the rework of patch 1 (ARM: protect usage of cr_alignment by #ifdef CONFIG_CPU_CP15 -> ARM: make cr_alignment read-only #ifndef CONFIG_CPU_CP15) patch 2 isn't needed anymore, too.

The patches are available via git at

git://git.pengutronix.de/git/ukl/linux.git cortexm3

I also updated the efm32 branch in the same repository that additionally contains support for Energymicro's efm32 processor. The patches in this series were tested on such a machine.

As before interrupt support and Makefile/Kconfig glue are missing. The former needs some more love as I think it should be possible to support the Cortex M3's nvic using common/gic.c. I plan to address this when this series made it into Linus' tree.

See the mails with the respective patches for some more details about what changed compared to v3.

Best regards
Uwe

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

PATCH v4 1/3 ARM: make cr_alignment read-only #ifndef CONFIG_CPU_CP15

This makes cr_alignment a constant 0 to break code that tries to modify the value as it's likely that it's built on wrong assumption when CONFIG_CPU_CP15 isn't defined. For code that is only reading the value 0 is more or less a fine value to report.

---
Hello,

in the v3 series this patch was titled "ARM: protect usage of cr_alignment by #ifdef CONFIG_CPU_CP15". In response to Nicolas' review cr_alignment was made a #define and only the code modifying it was patched.

Moreover I patched the cachepolicy and noalign kernel parameter handling to just print a warning that these are unimplemented without cp15.

Best regards
Uwe

 arch/arm/include/asm/cp15.h   |   11 ++++++++++-
 arch/arm/kernel/head-common.S |    9 +++++++--
 arch/arm/mm/alignment.c       |    2 ++
 arch/arm/mm/mmu.c             |   17 +++++++++++++++++
 4 files changed, 36 insertions(+), 3 deletions(-)
arch/arm/include/asm/cp15.h +10 -1
index 5ef4d80..d814435 100644
@@ -42,6 +42,8 @@
 #define vectors_high()	(0)
 #endif
 
+#ifdef CONFIG_CPU_CP15
+
 extern unsigned long cr_no_alignment;	/* defined in entry-armv.S */
 extern unsigned long cr_alignment;	/* defined in entry-armv.S */
 
@@ -82,6 +84,13 @@ static inline void set_copro_access(unsigned int val)
 	isb();
 }
 
-#endif
+#else /* ifdef CONFIG_CPU_CP15 */
+
+#define cr_no_alignment	UL(0)
+#define cr_alignment	UL(0)
+
+#endif /* ifdef CONFIG_CPU_CP15 / else */
+
+#endif /* ifndef __ASSEMBLY__ */
 
 #endif
arch/arm/kernel/head-common.S +7 -2
index 854bd22..2f560c5 100644
@@ -98,8 +98,9 @@ __mmap_switched:
 	str	r9, [r4]			@ Save processor ID
 	str	r1, [r5]			@ Save machine type
 	str	r2, [r6]			@ Save atags pointer
-	bic	r4, r0, #CR_A			@ Clear 'A' bit
-	stmia	r7, {r0, r4}			@ Save control register values
+	cmp	r7, #0
+	bicne	r4, r0, #CR_A			@ Clear 'A' bit
+	stmneia	r7, {r0, r4}			@ Save control register values
 	b	start_kernel
 ENDPROC(__mmap_switched)
 
@@ -113,7 +114,11 @@ __mmap_switched_data:
 	.long	processor_id			@ r4
 	.long	__machine_arch_type		@ r5
 	.long	__atags_pointer			@ r6
+#ifdef CONFIG_CPU_CP15
 	.long	cr_alignment			@ r7
+#else
+	.long	0
+#endif
 	.long	init_thread_union + THREAD_START_SP @ sp
 	.size	__mmap_switched_data, . - __mmap_switched_data
 
arch/arm/mm/alignment.c +2 -0
index 9107231..7df07d1 100644
@@ -962,12 +962,14 @@ static int __init alignment_init(void)
 		return -ENOMEM;
 #endif
 
+#ifdef CONFIG_CPU_CP15
 	if (cpu_is_v6_unaligned()) {
 		cr_alignment &= ~CR_A;
 		cr_no_alignment &= ~CR_A;
 		set_cr(cr_alignment);
 		ai_usermode = safe_usermode(ai_usermode, false);
 	}
+#endif
 
 	hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
 			"alignment exception");
arch/arm/mm/mmu.c +17 -0
index b86f893..b78d47a 100644
@@ -96,6 +96,7 @@ static struct cachepolicy cache_policies[] __initdata = {
 	}
 };
 
+#ifdef CONFIG_CPU_CP15
 /*
  * These are useful for identifying cache coherency
  * problems by allowing the cache or the cache and
@@ -194,6 +195,22 @@ void adjust_cr(unsigned long mask, unsigned long set)
 }
 #endif
 
+#else
+
+static int __init early_cachepolicy(char *p)
+{
+	pr_warning("cachepolicy kernel parameter not supported without cp15\n");
+}
+early_param("cachepolicy", early_cachepolicy);
+
+static int __init noalign_setup(char *__unused)
+{
+	pr_warning("noalign kernel parameter not supported without cp15\n");
+}
+__setup("noalign", noalign_setup);
+
+#endif
+
 #define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
 #define PROT_SECT_DEVICE	PMD_TYPE_SECT|PMD_SECT_AP_WRITE
 
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH v4 2/3 Cortex-M3: Add base support for Cortex-M3

In reply to Uwe Kleine-König

From: Catalin Marinas <[email protected]>

This patch adds the base support for the Cortex-M3 processor (ARMv7-M architecture). It consists of the corresponding arch/arm/mm/ files and various #ifdef's around the kernel. Exception handling is implemented by a subsequent patch.

[ukleinek: squash in some changes originating from commit

b5717ba (Cortex-M3: Add support for the Microcontroller Prototyping System)

from the v2.6.33-arm1 patch stack, port to post 3.2, drop zImage support, drop reorganisation of pt_regs, and a few cosmetic changes]

---
Hello,

this patch was only rebased onto v3.4-rc1 and so needed some minor adaptions, e.g. for the asm/system.h disintegration.

Best regards
Uwe

 arch/arm/include/asm/assembler.h   |   13 ++-
 arch/arm/include/asm/cputype.h     |    3 +
 arch/arm/include/asm/glue-cache.h  |   24 ++++++
 arch/arm/include/asm/glue-df.h     |    8 ++
 arch/arm/include/asm/glue-proc.h   |    9 ++
 arch/arm/include/asm/irqflags.h    |   51 +++++++++++-
 arch/arm/include/asm/processor.h   |    7 ++
 arch/arm/include/asm/ptrace.h      |   20 ++++-
 arch/arm/include/asm/system_info.h |    1 +
 arch/arm/kernel/asm-offsets.c      |    3 +
 arch/arm/kernel/head-nommu.S       |    9 +-
 arch/arm/kernel/setup.c            |   13 ++-
 arch/arm/kernel/traps.c            |    2 +
 arch/arm/mm/nommu.c                |    2 +
 arch/arm/mm/proc-v7m.S             |  161 ++++++++++++++++++++++++++++++++++++
 15 files changed, 318 insertions(+), 8 deletions(-)
 create mode 100644 arch/arm/mm/proc-v7m.S
arch/arm/include/asm/assembler.h +12 -1
index 03fb936..705d108 100644
@@ -135,7 +135,11 @@
  * assumes FIQs are enabled, and that the processor is in SVC mode.
  */
 	.macro	save_and_disable_irqs, oldcpsr
+#ifdef CONFIG_CPU_V7M
+	mrs	\oldcpsr, primask
+#else
 	mrs	\oldcpsr, cpsr
+#endif
 	disable_irq
 	.endm
 
@@ -149,7 +153,11 @@
  * guarantee that this will preserve the flags.
  */
 	.macro	restore_irqs_notrace, oldcpsr
+#ifdef CONFIG_CPU_V7M
+	msr	primask, \oldcpsr
+#else
 	msr	cpsr_c, \oldcpsr
+#endif
 	.endm
 
 	.macro restore_irqs, oldcpsr
@@ -228,7 +236,10 @@
 #endif
 	.endm
 
-#ifdef CONFIG_THUMB2_KERNEL
+#if defined(CONFIG_CPU_V7M)
+	.macro	setmode, mode, reg
+	.endm
+#elif defined(CONFIG_THUMB2_KERNEL)
 	.macro	setmode, mode, reg
 	mov	\reg, #\mode
 	msr	cpsr_c, \reg
arch/arm/include/asm/cputype.h +3 -0
index cb47d28..5bd8cb6 100644
@@ -46,6 +46,9 @@ extern unsigned int processor_id;
 		    : "cc");						\
 		__val;							\
 	})
+#elif defined(CONFIG_CPU_V7M)
+#define read_cpuid(reg) (*(unsigned int *)0xe000ed00)
+#define read_cpuid_ext(reg) 0
 #else
 #define read_cpuid(reg) (processor_id)
 #define read_cpuid_ext(reg) 0
arch/arm/include/asm/glue-cache.h +24 -0
index 7e30874..6a5fd0b 100644
@@ -125,10 +125,34 @@
 //# endif
 #endif
 
+#if defined(CONFIG_CPU_V7M)
+# ifdef _CACHE
+#  error "Multi-cache not supported on ARMv7-M"
+# else
+#  define _CACHE nop
+# endif
+#endif
+
 #if !defined(_CACHE) && !defined(MULTI_CACHE)
 #error Unknown cache maintenance model
 #endif
 
+#ifndef __ASSEMBLER__
+static inline void nop_flush_icache_all(void) { }
+static inline void nop_flush_kern_cache_all(void) { }
+static inline void nop_flush_user_cache_all(void) { }
+static inline void nop_flush_user_cache_range(unsigned long a, unsigned long b, unsigned int c) { }
+
+static inline void nop_coherent_kern_range(unsigned long a, unsigned long b) { }
+static inline void nop_coherent_user_range(unsigned long a, unsigned long b) { }
+static inline void nop_flush_kern_dcache_area(void *a, size_t s) { }
+
+static inline void nop_dma_flush_range(const void *a, const void *b) { }
+
+static inline void nop_dma_map_area(const void *s, size_t l, int f) { }
+static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
+#endif
+
 #ifndef MULTI_CACHE
 #define __cpuc_flush_icache_all		__glue(_CACHE,_flush_icache_all)
 #define __cpuc_flush_kern_all		__glue(_CACHE,_flush_kern_cache_all)
arch/arm/include/asm/glue-df.h +8 -0
index 354d571..26be71c 100644
@@ -103,6 +103,14 @@
 # endif
 #endif
 
+#ifdef CONFIG_CPU_ABRT_NOMMU
+# ifdef CPU_DABORT_HANDLER
+#  define MULTI_DABORT 1
+# else
+#  define CPU_DABORT_HANDLER nommu_early_abort
+# endif
+#endif
+
 #ifndef CPU_DABORT_HANDLER
 #error Unknown data abort handler type
 #endif
arch/arm/include/asm/glue-proc.h +9 -0
index e2be7f1..8f9991b 100644
@@ -248,6 +248,15 @@
 # endif
 #endif
 
+#ifdef CONFIG_CPU_V7M
+# ifdef CPU_NAME
+#  undef  MULTI_CPU
+#  define MULTI_CPU
+# else
+#  define CPU_NAME cpu_v7m
+# endif
+#endif
+
 #ifndef MULTI_CPU
 #define cpu_proc_init			__glue(CPU_NAME,_proc_init)
 #define cpu_proc_fin			__glue(CPU_NAME,_proc_fin)
arch/arm/include/asm/irqflags.h +49 -2

72 lines not on this page · raw message

arch/arm/include/asm/processor.h +7 -0
index 5ac8d3d..850710e 100644
@@ -49,7 +49,14 @@ struct thread_struct {
 #ifdef CONFIG_MMU
 #define nommu_start_thread(regs) do { } while (0)
 #else
+#ifndef CONFIG_CPU_V7M
 #define nommu_start_thread(regs) regs->ARM_r10 = current->mm->start_data
+#else
+#define nommu_start_thread(regs) do {					\
+	regs->ARM_r10 = current->mm->start_data;			\
+	regs->ARM_EXC_RET = 0xfffffffdL;				\
+} while (0)
+#endif
 #endif
 
 #define start_thread(regs,pc,sp)					\
arch/arm/include/asm/ptrace.h +19 -1
index 451808b..696bbf4 100644
@@ -39,16 +39,25 @@
 #define FIQ26_MODE	0x00000001
 #define IRQ26_MODE	0x00000002
 #define SVC26_MODE	0x00000003
+#ifndef CONFIG_CPU_V7M
 #define USR_MODE	0x00000010
+#define SVC_MODE	0x00000013
+#else
+#define USR_MODE	0x00000000
+#define SVC_MODE	0x00000000
+#endif
 #define FIQ_MODE	0x00000011
 #define IRQ_MODE	0x00000012
-#define SVC_MODE	0x00000013
 #define ABT_MODE	0x00000017
 #define UND_MODE	0x0000001b
 #define SYSTEM_MODE	0x0000001f
 #define MODE32_BIT	0x00000010
 #define MODE_MASK	0x0000001f
+#ifndef CONFIG_CPU_V7M
 #define PSR_T_BIT	0x00000020
+#else
+#define PSR_T_BIT	0x01000000
+#endif
 #define PSR_F_BIT	0x00000040
 #define PSR_I_BIT	0x00000080
 #define PSR_A_BIT	0x00000100
@@ -106,7 +115,11 @@ struct pt_regs {
 };
 #else /* __KERNEL__ */
 struct pt_regs {
+#ifdef CONFIG_CPU_V7M
+	unsigned long uregs[20];
+#else
 	unsigned long uregs[18];
+#endif
 };
 #endif /* __KERNEL__ */
 
@@ -128,6 +141,7 @@ struct pt_regs {
 #define ARM_r1		uregs[1]
 #define ARM_r0		uregs[0]
 #define ARM_ORIG_r0	uregs[17]
+#define ARM_EXC_RET	uregs[18]
 
 /*
  * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
@@ -165,6 +179,7 @@ struct pt_regs {
  */
 static inline int valid_user_regs(struct pt_regs *regs)
 {
+#ifndef CONFIG_CPU_V7M
 	unsigned long mode = regs->ARM_cpsr & MODE_MASK;
 
 	/*
@@ -187,6 +202,9 @@ static inline int valid_user_regs(struct pt_regs *regs)
 		regs->ARM_cpsr |= USR_MODE;
 
 	return 0;
+#else /* ifndef CONFIG_CPU_V7M */
+	return 1;
+#endif
 }
 
 static inline long regs_return_value(struct pt_regs *regs)
arch/arm/include/asm/system_info.h +1 -0
index dfd386d..720ea03 100644
@@ -11,6 +11,7 @@
 #define CPU_ARCH_ARMv5TEJ	7
 #define CPU_ARCH_ARMv6		8
 #define CPU_ARCH_ARMv7		9
+#define CPU_ARCH_ARMv7M		10
 
 #ifndef __ASSEMBLY__
 
arch/arm/kernel/asm-offsets.c +3 -0
index 1429d89..6f6b5b6 100644
@@ -91,6 +91,9 @@ int main(void)
   DEFINE(S_PC,			offsetof(struct pt_regs, ARM_pc));
   DEFINE(S_PSR,			offsetof(struct pt_regs, ARM_cpsr));
   DEFINE(S_OLD_R0,		offsetof(struct pt_regs, ARM_ORIG_r0));
+#ifdef CONFIG_CPU_V7M
+  DEFINE(S_EXC_RET,		offsetof(struct pt_regs, ARM_EXC_RET));
+#endif
   DEFINE(S_FRAME_SIZE,		sizeof(struct pt_regs));
   BLANK();
 #ifdef CONFIG_CACHE_L2X0
arch/arm/kernel/head-nommu.S +6 -3
index 278cfc1..c391c05 100644
@@ -44,10 +44,13 @@ ENTRY(stext)
 
 	setmode	PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode
 						@ and irqs disabled
-#ifndef CONFIG_CPU_CP15
-	ldr	r9, =CONFIG_PROCESSOR_ID
-#else
+#if defined(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
 	bl	__lookup_processor_type		@ r5=procinfo r9=cpuid
 	movs	r10, r5				@ invalid processor (r5=0)?
arch/arm/kernel/setup.c +12 -1
index b914113..7eb44c9 100644
@@ -134,7 +134,9 @@ struct stack {
 	u32 und[3];
 } ____cacheline_aligned;
 
+#ifndef CONFIG_CPU_V7M
 static struct stack stacks[NR_CPUS];
+#endif
 
 char elf_platform[ELF_PLATFORM_SIZE];
 EXPORT_SYMBOL(elf_platform);
@@ -214,7 +216,7 @@ static const char *proc_arch[] = {
 	"5TEJ",
 	"6TEJ",
 	"7",
-	"?(11)",
+	"7M",
 	"?(12)",
 	"?(13)",
 	"?(14)",
@@ -223,6 +225,12 @@ static const char *proc_arch[] = {
 	"?(17)",
 };
 
+#ifdef CONFIG_CPU_V7M
+static int __get_cpu_architecture(void)
+{
+	return CPU_ARCH_ARMv7M;
+}
+#else
 static int __get_cpu_architecture(void)
 {
 	int cpu_arch;
@@ -255,6 +263,7 @@ static int __get_cpu_architecture(void)
 
 	return cpu_arch;
 }
+#endif
 
 int __pure cpu_architecture(void)
 {
@@ -382,6 +391,7 @@ static void __init feat_v6_fixup(void)
  */
 void cpu_init(void)
 {
+#ifndef CONFIG_CPU_V7M
 	unsigned int cpu = smp_processor_id();
 	struct stack *stk = &stacks[cpu];
 
@@ -426,6 +436,7 @@ void cpu_init(void)
 	      "I" (offsetof(struct stack, und[0])),
 	      PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE)
 	    : "r14");
+#endif
 }
 
 int __cpu_logical_map[NR_CPUS];
arch/arm/kernel/traps.c +2 -0
index 7784547..d66da90 100644
@@ -791,6 +791,7 @@ static void __init kuser_get_tls_init(unsigned long vectors)
 
 void __init early_trap_init(void *vectors_base)
 {
+#ifndef CONFIG_CPU_V7M
 	unsigned long vectors = (unsigned long)vectors_base;
 	extern char __stubs_start[], __stubs_end[];
 	extern char __vectors_start[], __vectors_end[];
@@ -824,4 +825,5 @@ void __init early_trap_init(void *vectors_base)
 
 	flush_icache_range(vectors, vectors + PAGE_SIZE);
 	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#endif
 }
arch/arm/mm/nommu.c +2 -0
index 6486d2f..5960a32 100644
@@ -19,12 +19,14 @@
 
 void __init arm_mm_memblock_reserve(void)
 {
+#ifndef CONFIG_CPU_V7M
 	/*
 	 * Register the exception vector page.
 	 * some architectures which the DRAM is the exception vector to trap,
 	 * alloc_page breaks with error, although it is not NULL, but "0."
 	 */
 	memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
+#endif
 }
 
 void __init sanity_check_meminfo(void)
arch/arm/mm/proc-v7m.S new file +161 -0

161 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#3 lore raw

PATCH v4 2/3 Cortex-M3: Add base support for Cortex-M3

Quoted 7 lines · Uwe Kleine-K?nig
arch/arm/include/asm/irqflags.h +0 -0
index 1e6cca5..ac4d548 100644
@@ -10,6 +10,18 @@
  */
 #if __LINUX_ARM_ARCH__ >= 6

arch/arm/include/asm/irqflags.h line 21

Quoted 10 lines
arch/arm/include/asm/irqflags.h +9 -0
 
+#ifdef CONFIG_CPU_V7M
+static inline unsigned long arch_local_irq_save(void)
+{
+	unsigned long flags;
+
+	asm volatile(
+		"	mrs	%0, primask	@ arch_local_irq_save\n"
+		"	cpsid	i"
+		: "=r" (flags) : : "memory", "cc");

Wouldn't it produce a smaller patch to define something for "primask" vs "cpsr", rather than having to re-implement the entire function ?

Quoted 5 lines
arch/arm/include/asm/ptrace.h +0 -0
index 451808b..696bbf4 100644

arch/arm/include/asm/ptrace.h line 48

Quoted 10 lines
arch/arm/include/asm/ptrace.h +6 -0
@@ -39,16 +39,25 @@
 #define FIQ26_MODE	0x00000001
 #define IRQ26_MODE	0x00000002
 #define SVC26_MODE	0x00000003
+#ifndef CONFIG_CPU_V7M
 #define USR_MODE	0x00000010
+#define SVC_MODE	0x00000013
+#else
+#define USR_MODE	0x00000000
+#define SVC_MODE	0x00000000
+#endif

Note that these definitions are exported to userspace. Do we want to expose this kind of change there?

arch/arm/include/asm/ptrace.h line 60

Quoted 13 lines
arch/arm/include/asm/ptrace.h +4 -1
 #define FIQ_MODE	0x00000011
 #define IRQ_MODE	0x00000012
-#define SVC_MODE	0x00000013
 #define ABT_MODE	0x00000017
 #define UND_MODE	0x0000001b
 #define SYSTEM_MODE	0x0000001f
 #define MODE32_BIT	0x00000010
 #define MODE_MASK	0x0000001f
+#ifndef CONFIG_CPU_V7M
 #define PSR_T_BIT	0x00000020
+#else
+#define PSR_T_BIT	0x01000000
+#endif

Ditto. Note also that these bits changing will be visible via the pt_regs to userspace too. Maybe overloading these constants like this and making them depend on the kernel configuration is not a good idea for userspace.

Maybe giving the V7M definitions a new prefix would be a better idea?

#4 lore raw

PATCH v4 3/3 Cortex-M3: Add support for exception handling

In reply to Uwe Kleine-König

This patch implements the exception handling for the ARMv7-M architecture (pretty different from the A or R profiles).

It bases on work done earlier by Catalin for 2.6.33 but was nearly completely rewritten to use a pt_regs layout compatible to the A profile.

---
Hello,

apart from rebasing on top of 3.4-rc1 this patch is unchanged compared to v3.

Best regards
Uwe

 arch/arm/kernel/entry-common.S |    4 ++
 arch/arm/kernel/entry-header.S |  148 ++++++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/entry-v7m.S    |  134 ++++++++++++++++++++++++++++++++++++
 arch/arm/kernel/process.c      |    8 +++
 arch/arm/kernel/ptrace.c       |    3 +
 arch/arm/kernel/signal.c       |   13 ++++
 arch/arm/kernel/sys_arm.c      |    1 +
 7 files changed, 311 insertions(+)
 create mode 100644 arch/arm/kernel/entry-v7m.S
arch/arm/kernel/entry-common.S +4 -0
index 54ee265..3e7c216 100644
@@ -351,6 +351,9 @@ ENDPROC(ftrace_stub)
 
 	.align	5
 ENTRY(vector_swi)
+#ifdef CONFIG_CPU_V7M
+	v7m_exception_entry
+#else
 	sub	sp, sp, #S_FRAME_SIZE
 	stmia	sp, {r0 - r12}			@ Calling r0 - r12
  ARM(	add	r8, sp, #S_PC		)
@@ -361,6 +364,7 @@ ENTRY(vector_swi)
 	str	lr, [sp, #S_PC]			@ Save calling PC
 	str	r8, [sp, #S_PSR]		@ Save CPSR
 	str	r0, [sp, #S_OLD_R0]		@ Save OLD_R0
+#endif
 	zero_fp
 
 	/*
arch/arm/kernel/entry-header.S +148 -0

166 lines not on this page · raw message

arch/arm/kernel/entry-v7m.S new file +134 -0

134 lines not on this page · raw message

arch/arm/kernel/process.c +8 -0
index 2b7b017..9f301dc 100644
@@ -454,7 +454,11 @@ asm(	".pushsection .text\n"
 #ifdef CONFIG_TRACE_IRQFLAGS
 "	bl	trace_hardirqs_on\n"
 #endif
+#ifdef CONFIG_CPU_V7M
+"	msr	primask, r7\n"
+#else
 "	msr	cpsr_c, r7\n"
+#endif
 "	mov	r0, r4\n"
 "	mov	lr, r6\n"
 "	mov	pc, r5\n"
@@ -493,6 +497,10 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 	regs.ARM_r7 = SVC_MODE | PSR_ENDSTATE | PSR_ISETSTATE;
 	regs.ARM_pc = (unsigned long)kernel_thread_helper;
 	regs.ARM_cpsr = regs.ARM_r7 | PSR_I_BIT;
+#if defined CONFIG_CPU_V7M
+	/* Return to Handler mode */
+	regs.ARM_EXC_RET = 0xfffffff1L;
+#endif
 
 	return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
 }
arch/arm/kernel/ptrace.c +3 -0
index 45956c9..49383a4 100644
@@ -82,6 +82,9 @@ static const struct pt_regs_offset regoffset_table[] = {
 	REG_OFFSET_NAME(pc),
 	REG_OFFSET_NAME(cpsr),
 	REG_OFFSET_NAME(ORIG_r0),
+#ifdef CONFIG_CPU_V7M
+	REG_OFFSET_NAME(EXC_RET),
+#endif
 	REG_OFFSET_END,
 };
 
arch/arm/kernel/signal.c +13 -0
index 7cb532f..be61a41 100644
@@ -278,6 +278,8 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf)
 	sigset_t set;
 	int err;
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
+
 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
 	if (err == 0) {
 		sigdelsetmask(&set, ~_BLOCKABLE);
@@ -325,6 +327,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
 {
 	struct sigframe __user *frame;
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
 	/* Always make any pending restarted system calls return -EINTR */
 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
@@ -355,6 +358,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
 {
 	struct rt_sigframe __user *frame;
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
 	/* Always make any pending restarted system calls return -EINTR */
 	current_thread_info()->restart_block.fn = do_no_restart_syscall;
 
@@ -439,6 +443,7 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, int framesize)
 	unsigned long sp = regs->ARM_sp;
 	void __user *frame;
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
 	/*
 	 * This is the X/Open sanctioned signal stack switching.
 	 */
@@ -468,6 +473,8 @@ setup_return(struct pt_regs *regs, struct k_sigaction *ka,
 	int thumb = 0;
 	unsigned long cpsr = regs->ARM_cpsr & ~(PSR_f | PSR_E_BIT);
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
+
 	cpsr |= PSR_ENDSTATE;
 
 	/*
@@ -540,6 +547,8 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg
 	struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame));
 	int err = 0;
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
+
 	if (!frame)
 		return 1;
 
@@ -563,6 +572,8 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
 	stack_t stack;
 	int err = 0;
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
+
 	if (!frame)
 		return 1;
 
@@ -607,6 +618,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
 	int usig = sig;
 	int ret;
 
+	pr_info("%s(regs=%p)\n", __func__, regs);
 	/*
 	 * translate the signal
 	 */
@@ -776,6 +788,7 @@ static void do_signal(struct pt_regs *regs, int syscall)
 asmlinkage void
 do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
 {
+	pr_info("%s(regs=%p)\n", __func__, regs);
 	if (thread_flags & _TIF_SIGPENDING)
 		do_signal(regs, syscall);
 
arch/arm/kernel/sys_arm.c +1 -0
index d2b1779..4d3caca4d 100644
@@ -102,6 +102,7 @@ int kernel_execve(const char *filename,
 	 * We were successful.  We won't be returning to our caller, but
 	 * instead to user space by manipulating the kernel stack.
 	 */
+	pr_info("we were successful\n");
 	asm(	"add	r0, %0, %1\n\t"
 		"mov	r1, %2\n\t"
 		"mov	r2, %3\n\t"
Signature · 1 line
1.7.9.5
#5 lore raw

v4 cover ARM: Initial support for Cortex-M3

In reply to Uwe Kleine-König

Hello,

in reply to the last post Arnd suggested to take this series early after the 3.4 merge window for next.

Now that 3.4-rc3 is out, I wonder if you (Russell) already found the time to look at the series?

Best regards
Uwe

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

v4 cover ARM: Initial support for Cortex-M3

Hello Russell,

Quoted 5 lines · Uwe Kleine-K?nig

in reply to the last post Arnd suggested to take this series early after the 3.4 merge window for next.

Now that 3.4-rc3 is out, I wonder if you (Russell) already found the time to look at the series?

would it be ok for you if I put the series into your patch system just that it doesn't become forgotten?

Best regards
Uwe

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