Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit afe4b25e authored by Lennert Buytenhek's avatar Lennert Buytenhek Committed by Russell King
Browse files

[ARM] 3881/4: xscale: clean up cp0/cp1 handling



XScale cores either have a DSP coprocessor (which contains a single
40 bit accumulator register), or an iWMMXt coprocessor (which contains
eight 64 bit registers.)

Because of the small amount of state in the DSP coprocessor, access to
the DSP coprocessor (CP0) is always enabled, and DSP context switching
is done unconditionally on every task switch.  Access to the iWMMXt
coprocessor (CP0/CP1) is enabled only when an iWMMXt instruction is
first issued, and iWMMXt context switching is done lazily.

CONFIG_IWMMXT is supposed to mean 'the cpu we will be running on will
have iWMMXt support', but boards are supposed to select this config
symbol by hand, and at least one pxa27x board doesn't get this right,
so on that board, proc-xscale.S will incorrectly assume that we have a
DSP coprocessor, enable CP0 on boot, and we will then only save the
first iWMMXt register (wR0) on context switches, which is Bad.

This patch redefines CONFIG_IWMMXT as 'the cpu we will be running on
might have iWMMXt support, and we will enable iWMMXt context switching
if it does.'  This means that with this patch, running a CONFIG_IWMMXT=n
kernel on an iWMMXt-capable CPU will no longer potentially corrupt iWMMXt
state over context switches, and running a CONFIG_IWMMXT=y kernel on a
non-iWMMXt capable CPU will still do DSP context save/restore.

These changes should make iWMMXt work on PXA3xx, and as a side effect,
enable proper acc0 save/restore on non-iWMMXt capable xsc3 cores such
as IOP13xx and IXP23xx (which will not have CONFIG_CPU_XSCALE defined),
as well as setting and using HWCAP_IWMMXT properly.

Signed-off-by: default avatarLennert Buytenhek <buytenh@wantstofly.org>
Acked-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent f5236225
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -374,6 +374,14 @@ config PLAT_IOP

source arch/arm/mm/Kconfig

config IWMMXT
	bool "Enable iWMMXt support"
	depends CPU_XSCALE || CPU_XSC3
	default y if PXA27x
	help
	  Enable support for iWMMXt context switching at run time if
	  running on a CPU that supports it.

#  bool 'Use XScale PMU as timer source' CONFIG_XSCALE_PMU_TIMER
config XSCALE_PMU
	bool
+3 −1
Original line number Diff line number Diff line
@@ -24,7 +24,9 @@ obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_CRUNCH)		+= crunch.o crunch-bits.o
AFLAGS_crunch-bits.o		:= -Wa,-mcpu=ep9312

obj-$(CONFIG_IWMMXT)		+= iwmmxt.o iwmmxt-notifier.o
obj-$(CONFIG_CPU_XSCALE)	+= xscale-cp0.o
obj-$(CONFIG_CPU_XSC3)		+= xscale-cp0.o
obj-$(CONFIG_IWMMXT)		+= iwmmxt.o
AFLAGS_iwmmxt.o			:= -Wa,-mcpu=iwmmxt

ifneq ($(CONFIG_ARCH_EBSA110),y)
+0 −9
Original line number Diff line number Diff line
@@ -589,10 +589,6 @@ ENTRY(__switch_to)
	strex	r5, r4, [ip]			@ Clear exclusive monitor
#endif
#endif
#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
	mra	r4, r5, acc0
	stmia   ip, {r4, r5}
#endif
#if defined(CONFIG_HAS_TLS_REG)
	mcr	p15, 0, r3, c13, c0, 3		@ set TLS register
#elif !defined(CONFIG_TLS_REG_EMUL)
@@ -601,11 +597,6 @@ ENTRY(__switch_to)
#endif
#ifdef CONFIG_MMU
	mcr	p15, 0, r6, c3, c0, 0		@ Set domain register
#endif
#if defined(CONFIG_CPU_XSCALE) && !defined(CONFIG_IWMMXT)
	add	r4, r2, #TI_CPU_DOMAIN + 40	@ cpu_context_save->extra
	ldmib	r4, {r4, r5}
	mar	acc0, r4, r5
#endif
	mov	r5, r0
	add	r4, r2, #TI_CPU_SAVE

arch/arm/kernel/iwmmxt-notifier.c

deleted100644 → 0
+0 −63
Original line number Diff line number Diff line
/*
 *  linux/arch/arm/kernel/iwmmxt-notifier.c
 *
 *  XScale iWMMXt (Concan) context switching and handling
 *
 *  Initial code:
 *  Copyright (c) 2003, Intel Corporation
 *
 *  Full lazy switching support, optimizations and more, by Nicolas Pitre
 *  Copyright (c) 2003-2004, MontaVista Software, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <asm/thread_notify.h>
#include <asm/io.h>

static int iwmmxt_do(struct notifier_block *self, unsigned long cmd, void *t)
{
	struct thread_info *thread = t;

	switch (cmd) {
	case THREAD_NOTIFY_FLUSH:
		/*
		 * flush_thread() zeroes thread->fpstate, so no need
		 * to do anything here.
		 *
		 * FALLTHROUGH: Ensure we don't try to overwrite our newly
		 * initialised state information on the first fault.
		 */

	case THREAD_NOTIFY_RELEASE:
		iwmmxt_task_release(thread);
		break;

	case THREAD_NOTIFY_SWITCH:
		iwmmxt_task_switch(thread);
		break;
	}

	return NOTIFY_DONE;
}

static struct notifier_block iwmmxt_notifier_block = {
	.notifier_call	= iwmmxt_do,
};

static int __init iwmmxt_init(void)
{
	thread_register_notifier(&iwmmxt_notifier_block);

	return 0;
}

late_initcall(iwmmxt_init);
+0 −3
Original line number Diff line number Diff line
@@ -357,9 +357,6 @@ static void __init setup_processor(void)
#ifndef CONFIG_VFP
	elf_hwcap &= ~HWCAP_VFP;
#endif
#ifndef CONFIG_IWMMXT
	elf_hwcap &= ~HWCAP_IWMMXT;
#endif

	cpu_proc_init();
}
Loading