[PATCH 3/8] ARM: make xscale iwmmxt code multiplatform aware

Arnd Bergmann arnd at arndb.de
Fri Feb 27 05:29:30 PST 2015


In a multiplatform configuration, we may end up building a kernel
for both Marvell PJ1 and an ARMv4 CPU implementation. In that
case, the xscale-cp0 code is built with gcc -march=armv4{,t},
which results in a build error from the coprocessor instructions.

Since we know this code will only have to run on an actual xscale
processor, we can simply build the entire file for ARMv5TE.

Related to this, we need to handle the iWMMXT initialization sequence
differently during boot, to ensure we don't try to touch xscale
specific registers on other CPUs from the xscale_cp0_init initcall.
cpu_is_xscale() used to be hardcoded to '1' in any configuration
that enables any XScale-compatible core, but this breaks once
we can have a combined kernel with MMP1 and something else.

In this patch, I introduce two new macros, cpu_is_xscale()
and cpu_is_mohawk, so we can test for all three of them in
the iwmmxt initialization. The two existing users of
cpu_is_xscale() are modified accordingly, but slightly
change behavior for kernels that enable CPU_MOHAWK in combination
with CPU_XSCALE or CPU_XSC3. Previously, these would leave
clear PMD_BIT4 in the page tables, now they leave it untouched,
just like we always do for kernels that enable only CPU_MOHAWK.
Since the previous behavior was inconsistent, I assume it was
unintentional.

Signed-off-by: Arnd Bergmann <arnd at arndb.de>
---
 arch/arm/include/asm/cputype.h | 27 +++++++++++++++++++++++++--
 arch/arm/kernel/Makefile       |  1 +
 arch/arm/kernel/xscale-cp0.c   |  6 ++++++
 arch/arm/mm/idmap.c            |  3 ++-
 4 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 819777d0e91f..7bc66e22afd7 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -228,10 +228,33 @@ static inline int cpu_is_xsc3(void)
 }
 #endif
 
-#if !defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_CPU_XSC3)
+#if !defined(CONFIG_CPU_XSCALE)
 #define	cpu_is_xscale()	0
 #else
-#define	cpu_is_xscale()	1
+static inline int cpu_is_xscale(void)
+{
+	unsigned int id;
+	id = read_cpuid_id() & 0xffffe000;
+
+	if ((id == 0x69052000) || (id == 0x69054000))
+		return 1;
+
+	return 0;
+}
+#endif
+
+#if !defined(CONFIG_CPU_MOHAWK)
+#define	cpu_is_mohawk()	0
+#else
+static inline int cpu_is_mohawk(void)
+{
+	unsigned int id;
+	id = read_cpuid_id() & 0xffffe000;
+
+	if (id == 0x56158000)
+
+	return 0;
+}
 #endif
 
 /*
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 902397dd1000..7840acff6cd3 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
 obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
 obj-$(CONFIG_CPU_MOHAWK)	+= xscale-cp0.o
+CFLAGS_xscale-cp0.o		+= -Wa,-march=armv5te
 obj-$(CONFIG_CPU_PJ4)		+= pj4-cp0.o
 obj-$(CONFIG_CPU_PJ4B)		+= pj4-cp0.o
 obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
diff --git a/arch/arm/kernel/xscale-cp0.c b/arch/arm/kernel/xscale-cp0.c
index bdbb8853a19b..a23420fab70e 100644
--- a/arch/arm/kernel/xscale-cp0.c
+++ b/arch/arm/kernel/xscale-cp0.c
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <asm/thread_notify.h>
+#include <asm/cputype.h>
 
 static inline void dsp_save_state(u32 *state)
 {
@@ -152,6 +153,11 @@ static int __init xscale_cp0_init(void)
 {
 	u32 cp_access;
 
+	/* do not attempt to probe iwmmxt on non-xscale family CPUs */
+	if (IS_ENABLED(CONFIG_ARCH_MULTIPLATFORM) &&
+	    !(cpu_is_xscale() || cpu_is_xsc3() || cpu_is_mohawk()))
+		return 0;
+
 	cp_access = xscale_cp_access_read() & ~3;
 	xscale_cp_access_write(cp_access | 1);
 
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index e7a81cebbb2e..40140984db0a 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -86,7 +86,8 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
 
 	prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
 
-	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+	if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ &&
+	    !cpu_is_xscale() && !cpu_is_xsc3())
 		prot |= PMD_BIT4;
 
 	pgd += pgd_index(addr);
-- 
2.1.0.rc2




More information about the linux-arm-kernel mailing list