diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2009-02-11 07:12:56 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-02-12 05:59:43 -0500 |
commit | 3d1228ead618b88e8606015cbabc49019981805d (patch) | |
tree | 5d44c936c12ff2e99732f535dd393af201e7fe67 /arch/arm/vfp/vfpmodule.c | |
parent | f373e8c0639f1720d2d0fe414990f504e113c2ba (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.c | 49 |
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) | |||
377 | static inline void vfp_pm_init(void) { } | 377 | static 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 | ||
385 | void 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 | ||
396 | void 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 | |||
424 | out: | ||
425 | put_cpu(); | ||
426 | } | ||
427 | #endif | ||
428 | |||
380 | #include <linux/smp.h> | 429 | #include <linux/smp.h> |
381 | 430 | ||
382 | /* | 431 | /* |