From: u.kleine-koenig@pengutronix.de (Uwe Kleine-König)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 10/11] Cortex-M3: Add VFP support
Date: Sun, 22 Jan 2012 12:13:36 +0100 [thread overview]
Message-ID: <1327230817-12855-10-git-send-email-u.kleine-koenig@pengutronix.de> (raw)
In-Reply-To: <20120122111230.GB14835@pengutronix.de>
From: Catalin Marinas <catalin.marinas@arm.com>
This patch adds support for the ARMv7-M VFP extension. It uses the lazy
state preservation mechanism available in hardware for the S0-S15
registers. The S16-S32 registers are saved at a context switch if the
thread being scheduled out ever used the VFP. Similarly, the S16-S31
registers are restored if the thread being scheduled in ever used the
VFP.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
---
arch/arm/Kconfig | 7 +++
arch/arm/include/asm/fpstate.h | 3 +
arch/arm/kernel/Makefile | 2 +
arch/arm/kernel/asm-offsets.c | 3 +
| 14 ++++++
arch/arm/kernel/vfp-m.c | 102 ++++++++++++++++++++++++++++++++++++++++
6 files changed, 131 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/kernel/vfp-m.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ca9b48c..c5caeee 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2227,6 +2227,13 @@ config NEON
Say Y to include support code for NEON, the ARMv7 Advanced SIMD
Extension.
+config VFPM
+ bool "ARMv7-M VFP Extension support"
+ depends on CPU_V7M
+ help
+ Say Y to include support for the ARMv7-M VFP Extension
+ (single-precision floating point hardware).
+
endmenu
menu "Userspace binary formats"
diff --git a/arch/arm/include/asm/fpstate.h b/arch/arm/include/asm/fpstate.h
index 3ad4c10..e18c3d9 100644
--- a/arch/arm/include/asm/fpstate.h
+++ b/arch/arm/include/asm/fpstate.h
@@ -43,6 +43,9 @@ struct vfp_hard_struct {
#ifdef CONFIG_SMP
__u32 cpu;
#endif
+#ifdef CONFIG_VFPM
+ __u32 clean;
+#endif
};
union vfp_state {
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 32e96e6..66d6c92 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -81,6 +81,8 @@ obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
obj-$(CONFIG_ARM_CPU_TOPOLOGY) += topology.o
+obj-$(CONFIG_VFPM) += vfp-m.o
+
ifneq ($(CONFIG_ARCH_EBSA110),y)
obj-y += io.o
endif
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index e861849..10ec416 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -60,6 +60,9 @@ int main(void)
DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value));
DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate));
DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate));
+#ifdef CONFIG_VFPM
+ DEFINE(TI_VFPSTATE_CLEAN, offsetof(struct thread_info, vfpstate.hard.clean));
+#endif
#ifdef CONFIG_SMP
DEFINE(VFP_CPU, offsetof(union vfp_state, hard.cpu));
#endif
--git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 8050d9b..cb38aff 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -72,7 +72,15 @@
*/
.macro v7m_exception_entry
cpsid i
+#ifdef CONFIG_VFPM
+ get_thread_info r0
+ and r1, lr, #1 << 4 @ VFP clean state
+ str r1, [r0, #TI_VFPSTATE_CLEAN]
+#endif
cmp lr, #0xfffffffd @ check the return stack
+#ifdef CONFIG_VFPM
+ cmpne lr, #0xffffffed
+#endif
beq 1f @ exception on process stack
add r12, sp, #32 @ MSP before exception
stmdb sp!, {r4-r12, lr} @ push unsaved registers
@@ -90,6 +98,9 @@
.macro v7m_exception_fast_exit
ldmia sp!, {r4-r12, lr} @ restore previously saved state
cmp lr, #0xfffffffd @ check the return stack
+#ifdef CONFIG_VFPM
+ cmpne lr, #0xffffffed
+#endif
addeq sp, #32 @ returning to PSP, just restore MSP
cpsie i
bx lr
@@ -99,6 +110,9 @@
cpsid i
ldr lr, [sp, #S_EXC_LR] @ read exception LR
cmp lr, #0xfffffffd @ check the return stack
+#ifdef CONFIG_VFPM
+ cmpne lr, #0xffffffed
+#endif
beq 1f @ returning to PSP
@ Prepare the MSP stack
ldmia sp, {r4-r11} @ restore previously saved state
diff --git a/arch/arm/kernel/vfp-m.c b/arch/arm/kernel/vfp-m.c
new file mode 100644
index 0000000..0528189
--- /dev/null
+++ b/arch/arm/kernel/vfp-m.c
@@ -0,0 +1,102 @@
+/*
+ * arch/arm/kernel/vfp-m.c
+ *
+ * Copyright (C) 2010 ARM Limited
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/thread_notify.h>
+
+static union vfp_state *last_vfp_context;
+
+static void save_vfp_context(union vfp_state *vfp)
+{
+ /* vstmia %0!, {d8-d15} */
+ asm(" stc p11, cr8, [%0], #16*4\n" : : "r" (vfp) : "cc");
+}
+
+static void load_vfp_context(union vfp_state *vfp)
+{
+ /* vldmia %0!, {d8-d15} */
+ asm(" ldc p11, cr8, [%0], #16*4\n" : : "r" (vfp) : "cc");
+}
+
+static int vfpm_notifier(struct notifier_block *self, unsigned long cmd,
+ void *t)
+{
+ struct thread_info *thread = t;
+ union vfp_state *vfp = &thread->vfpstate;
+ union vfp_state *old_vfp = ¤t_thread_info()->vfpstate;
+ u32 *fpccr = (u32 *)0xe000ef34;
+
+ switch (cmd) {
+ case THREAD_NOTIFY_FLUSH:
+ memset(vfp, 0, sizeof(*vfp));
+ vfp->hard.clean = 1;
+ /* fall through */
+
+ case THREAD_NOTIFY_EXIT:
+ if (last_vfp_context == vfp) {
+ /* disable lazy state saving */
+ *fpccr &= ~1;
+ last_vfp_context = NULL;
+ }
+ break;
+
+ case THREAD_NOTIFY_SWITCH:
+ if (!old_vfp->hard.clean) {
+ save_vfp_context(last_vfp_context);
+ last_vfp_context = old_vfp;
+ }
+ if (!vfp->hard.clean && last_vfp_context != vfp) {
+ load_vfp_context(vfp);
+ last_vfp_context = vfp;
+ }
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block vfpm_notifier_block = {
+ .notifier_call = vfpm_notifier,
+};
+
+static int __init vfpm_init(void)
+{
+ u32 *cpacr = (u32 *)0xe000ed88;
+ u32 *mvfr0 = (u32 *)0xe000ef40;
+ u32 *fpccr = (u32 *)0xe000ef34;
+
+ /* check for single-precision VFP operations */
+ if ((*mvfr0 & 0xf0) != 0x20)
+ return 0;
+
+ printk(KERN_INFO "ARMv7-M VFP Extension supported\n");
+
+ *cpacr |= 0xf << 20; /* coprocessor access */
+ *fpccr |= 3 << 30; /* automatic lazy state preservation */
+
+ elf_hwcap |= HWCAP_VFP;
+ thread_register_notifier(&vfpm_notifier_block);
+
+ return 0;
+}
+
+late_initcall(vfpm_init);
--
1.7.8.3
next prev parent reply other threads:[~2012-01-22 11:13 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-22 11:12 [RFC PATCH 00/11] Cortex-M3 support Uwe Kleine-König
2012-01-22 11:13 ` [RFC PATCH 01/11] ARM: only show modules in the memory layout for MODULES=y Uwe Kleine-König
2012-01-26 6:16 ` Linus Walleij
2012-01-22 11:13 ` [RFC PATCH 02/11] ARM: add device tree blobs to .gitignore Uwe Kleine-König
2012-01-22 11:13 ` [RFC PATCH 03/11] ARM: protect usage of cr_alignment by #ifdef CONFIG_CPU_CP15 Uwe Kleine-König
2012-01-23 5:43 ` Jean-Christophe PLAGNIOL-VILLARD
2012-01-23 8:14 ` Uwe Kleine-König
2012-01-22 11:13 ` [RFC PATCH 04/11] ARM: Add a printk loglevel modifier Uwe Kleine-König
2012-01-23 5:50 ` Jean-Christophe PLAGNIOL-VILLARD
2012-01-22 11:13 ` [RFC PATCH 05/11] ARM: provide XIP_VIRT_ADDR for no-MMU builds Uwe Kleine-König
2012-01-22 11:13 ` [RFC PATCH 06/11] Cortex-M3: Add base support for Cortex-M3 Uwe Kleine-König
2012-01-22 19:45 ` Michał Mirosław
2012-01-22 20:42 ` Uwe Kleine-König
2012-01-22 11:13 ` [RFC PATCH 07/11] Cortex-M3: Add support for exception handling Uwe Kleine-König
2012-01-22 11:13 ` [RFC PATCH 08/11] Cortex-M3: Add NVIC support Uwe Kleine-König
2012-01-31 19:39 ` Uwe Kleine-König
2012-01-22 11:13 ` [RFC PATCH 09/11] Cortex-M3: Allow the building of Cortex-M3 kernel port Uwe Kleine-König
2012-01-22 20:05 ` Michał Mirosław
2012-02-07 19:43 ` Uwe Kleine-König
2012-01-22 11:13 ` Uwe Kleine-König [this message]
2012-01-22 11:13 ` [RFC PATCH 11/11] HACK! ARM: no, we don't enter in ARM Uwe Kleine-König
2012-02-07 20:18 ` [RFC PATCH 00/11] Cortex-M3 support Uwe Kleine-König
2012-02-16 20:01 ` Uwe Kleine-König
2012-02-16 20:18 ` [PATCH 1/5] ARM: protect usage of cr_alignment by #ifdef CONFIG_CPU_CP15 Uwe Kleine-König
2012-02-16 20:18 ` [PATCH 2/5] ARM: Add a printk loglevel modifier Uwe Kleine-König
2012-02-16 20:18 ` [PATCH 3/5] ARM: force branch instructions to use long distance encoding Uwe Kleine-König
2012-02-16 20:18 ` [PATCH 4/5] ARM: Cortex-M3: Add base support for Cortex-M3 Uwe Kleine-König
2012-02-16 20:18 ` [PATCH 5/5] ARM: Cortex-M3: Add support for exception handling Uwe Kleine-König
2012-02-16 22:20 ` Russell King - ARM Linux
2012-02-24 22:01 ` Uwe Kleine-König
2012-02-24 22:12 ` Catalin Marinas
2012-02-24 22:43 ` Russell King - ARM Linux
2012-02-25 8:49 ` Catalin Marinas
2012-02-25 14:07 ` Uwe Kleine-König
2012-03-05 17:04 ` [PATCH v2 4/5] Cortex-M3: Add base support for Cortex-M3 Uwe Kleine-König
2012-03-05 17:04 ` [PATCH v2 5/5] Cortex-M3: Add support for exception handling Uwe Kleine-König
2012-03-09 17:10 ` Catalin Marinas
2012-03-13 20:39 ` Uwe Kleine-König
2012-03-08 10:52 ` [PATCH v2 4/5] Cortex-M3: Add base support for Cortex-M3 Catalin Marinas
2012-02-17 0:28 ` [PATCH 1/5] ARM: protect usage of cr_alignment by #ifdef CONFIG_CPU_CP15 Ryan Mallon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1327230817-12855-10-git-send-email-u.kleine-koenig@pengutronix.de \
--to=u.kleine-koenig@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.