summaryrefslogtreecommitdiff
path: root/arch/m68k/kernel/process_mm.c
diff options
context:
space:
mode:
authorGreg Ungerer <gerg@uclinux.org>2011-10-19 14:10:03 +1000
committerGreg Ungerer <gerg@uclinux.org>2011-12-30 10:20:47 +1000
commit0a2796da1182a7dcfba41f796f45986237bc1688 (patch)
treef3a09049fd2f554241ede9e2c2d8a979ffe1e730 /arch/m68k/kernel/process_mm.c
parente9fcffa49376b37518baf71a47adc15e74b2434c (diff)
m68k: add ColdFire FPU support for the V4e ColdFire CPUs
The V4e ColdFire CPU family also has an integrated FPU (as well as the MMU). So add code to support this hardware along side the existing m68k FPU code. The ColdFire FPU is of course different to all previous 68k FP units. It is close in operation to the 68060, but not completely compatible. The biggest issue to deal with is that the ColdFire FPU multi-move instructions are different. It does not support multi-moving the FP control registers, and the multi-move of the FP data registers uses a different instruction mnemonic. Signed-off-by: Greg Ungerer <gerg@uclinux.org> Acked-by: Matt Waddel <mwaddel@yahoo.com> Acked-by: Kurt Mahan <kmahan@xmission.com>
Diffstat (limited to 'arch/m68k/kernel/process_mm.c')
-rw-r--r--arch/m68k/kernel/process_mm.c59
1 files changed, 45 insertions, 14 deletions
diff --git a/arch/m68k/kernel/process_mm.c b/arch/m68k/kernel/process_mm.c
index 58a3253f3eb9..125f34e00bf0 100644
--- a/arch/m68k/kernel/process_mm.c
+++ b/arch/m68k/kernel/process_mm.c
@@ -172,9 +172,7 @@ void flush_thread(void)
current->thread.fs = __USER_DS;
if (!FPU_IS_EMU)
- asm volatile (".chip 68k/68881\n\t"
- "frestore %0@\n\t"
- ".chip 68k" : : "a" (&zero));
+ asm volatile ("frestore %0@" : : "a" (&zero) : "memory");
}
/*
@@ -248,11 +246,28 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
/* Copy the current fpu state */
asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory");
- if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2])
- asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
- "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
- : : "m" (p->thread.fp[0]), "m" (p->thread.fpcntl[0])
- : "memory");
+ if (!CPU_IS_060 ? p->thread.fpstate[0] : p->thread.fpstate[2]) {
+ if (CPU_IS_COLDFIRE) {
+ asm volatile ("fmovemd %/fp0-%/fp7,%0\n\t"
+ "fmovel %/fpiar,%1\n\t"
+ "fmovel %/fpcr,%2\n\t"
+ "fmovel %/fpsr,%3"
+ :
+ : "m" (p->thread.fp[0]),
+ "m" (p->thread.fpcntl[0]),
+ "m" (p->thread.fpcntl[1]),
+ "m" (p->thread.fpcntl[2])
+ : "memory");
+ } else {
+ asm volatile ("fmovemx %/fp0-%/fp7,%0\n\t"
+ "fmoveml %/fpiar/%/fpcr/%/fpsr,%1"
+ :
+ : "m" (p->thread.fp[0]),
+ "m" (p->thread.fpcntl[0])
+ : "memory");
+ }
+ }
+
/* Restore the state in case the fpu was busy */
asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0]));
}
@@ -285,12 +300,28 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu)
if (!CPU_IS_060 ? !fpustate[0] : !fpustate[2])
return 0;
- asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
- :: "m" (fpu->fpcntl[0])
- : "memory");
- asm volatile ("fmovemx %/fp0-%/fp7,%0"
- :: "m" (fpu->fpregs[0])
- : "memory");
+ if (CPU_IS_COLDFIRE) {
+ asm volatile ("fmovel %/fpiar,%0\n\t"
+ "fmovel %/fpcr,%1\n\t"
+ "fmovel %/fpsr,%2\n\t"
+ "fmovemd %/fp0-%/fp7,%3"
+ :
+ : "m" (fpu->fpcntl[0]),
+ "m" (fpu->fpcntl[1]),
+ "m" (fpu->fpcntl[2]),
+ "m" (fpu->fpregs[0])
+ : "memory");
+ } else {
+ asm volatile ("fmovem %/fpiar/%/fpcr/%/fpsr,%0"
+ :
+ : "m" (fpu->fpcntl[0])
+ : "memory");
+ asm volatile ("fmovemx %/fp0-%/fp7,%0"
+ :
+ : "m" (fpu->fpregs[0])
+ : "memory");
+ }
+
return 1;
}
EXPORT_SYMBOL(dump_fpu);