[PATCH 3/8] ARM: make xscale iwmmxt code multiplatform aware
Rob Herring
robh at kernel.org
Fri Feb 27 09:53:47 PST 2015
On Fri, Feb 27, 2015 at 7:29 AM, Arnd Bergmann <arnd at arndb.de> wrote:
> 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)
You could use IS_ENABLED here.
> #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)
And here.
> +#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) &&
Do you really need this condition?
> + !(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