aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/vfp/vfpmodule.c
diff options
context:
space:
mode:
authorCatalin Marinas <catalin.marinas@arm.com>2009-02-11 07:12:56 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-02-12 05:59:43 -0500
commit3d1228ead618b88e8606015cbabc49019981805d (patch)
tree5d44c936c12ff2e99732f535dd393af201e7fe67 /arch/arm/vfp/vfpmodule.c
parentf373e8c0639f1720d2d0fe414990f504e113c2ba (diff)
[ARM] 5387/1: Add ptrace VFP support on ARM
This patch adds ptrace support for setting and getting the VFP registers using PTRACE_SETVFPREGS and PTRACE_GETVFPREGS. The user_vfp structure defined in asm/user.h contains 32 double registers (to cover VFPv3 and Neon hardware) and the FPSCR register. Cc: Paul Brook <paul@codesourcery.com> Cc: Daniel Jacobowitz <dan@codesourcery.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/vfp/vfpmodule.c')
-rw-r--r--arch/arm/vfp/vfpmodule.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 9f476a1be2ca..7e1239041b39 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -377,6 +377,55 @@ static void vfp_pm_init(void)
377static inline void vfp_pm_init(void) { } 377static inline void vfp_pm_init(void) { }
378#endif /* CONFIG_PM */ 378#endif /* CONFIG_PM */
379 379
380/*
381 * Synchronise the hardware VFP state of a thread other than current with the
382 * saved one. This function is used by the ptrace mechanism.
383 */
384#ifdef CONFIG_SMP
385void vfp_sync_state(struct thread_info *thread)
386{
387 /*
388 * On SMP systems, the VFP state is automatically saved at every
389 * context switch. We mark the thread VFP state as belonging to a
390 * non-existent CPU so that the saved one will be reloaded when
391 * needed.
392 */
393 thread->vfpstate.hard.cpu = NR_CPUS;
394}
395#else
396void vfp_sync_state(struct thread_info *thread)
397{
398 unsigned int cpu = get_cpu();
399 u32 fpexc = fmrx(FPEXC);
400
401 /*
402 * If VFP is enabled, the previous state was already saved and
403 * last_VFP_context updated.
404 */
405 if (fpexc & FPEXC_EN)
406 goto out;
407
408 if (!last_VFP_context[cpu])
409 goto out;
410
411 /*
412 * Save the last VFP state on this CPU.
413 */
414 fmxr(FPEXC, fpexc | FPEXC_EN);
415 vfp_save_state(last_VFP_context[cpu], fpexc);
416 fmxr(FPEXC, fpexc);
417
418 /*
419 * Set the context to NULL to force a reload the next time the thread
420 * uses the VFP.
421 */
422 last_VFP_context[cpu] = NULL;
423
424out:
425 put_cpu();
426}
427#endif
428
380#include <linux/smp.h> 429#include <linux/smp.h>
381 430
382/* 431/*