Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 279747
b: refs/heads/master
c: 0a2796d
h: refs/heads/master
i:
  279745: 2b8f5da
  279743: 2333ede
v: v3
  • Loading branch information
Greg Ungerer committed Dec 30, 2011
1 parent b45eb97 commit 7836251
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 67 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e9fcffa49376b37518baf71a47adc15e74b2434c
refs/heads/master: 0a2796da1182a7dcfba41f796f45986237bc1688
2 changes: 2 additions & 0 deletions trunk/arch/m68k/include/asm/fpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#define FPSTATESIZE (96)
#elif defined(CONFIG_M68KFPU_EMU)
#define FPSTATESIZE (28)
#elif defined(CONFIG_COLDFIRE) && defined(CONFIG_MMU)
#define FPSTATESIZE (16)
#elif defined(CONFIG_M68060)
#define FPSTATESIZE (12)
#else
Expand Down
59 changes: 45 additions & 14 deletions trunk/arch/m68k/kernel/process_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}

/*
Expand Down Expand Up @@ -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]));
}
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/m68k/kernel/setup_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ void __init setup_arch(char **cmdline_p)
* with them, we should add a test to check_bugs() below] */
#ifndef CONFIG_M68KFPU_EMU_ONLY
/* clear the fpu if we have one */
if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) {
if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|FPU_COLDFIRE)) {
volatile int zero = 0;
asm volatile ("frestore %0" : : "m" (zero));
}
Expand Down
187 changes: 136 additions & 51 deletions trunk/arch/m68k/kernel/signal_mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ static inline int restore_fpu_state(struct sigcontext *sc)

if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
/* Verify the frame format. */
if (!CPU_IS_060 && (sc->sc_fpstate[0] != fpu_version))
if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
(sc->sc_fpstate[0] != fpu_version))
goto out;
if (CPU_IS_020_OR_030) {
if (m68k_fputype & FPU_68881 &&
Expand All @@ -222,19 +223,43 @@ static inline int restore_fpu_state(struct sigcontext *sc)
sc->sc_fpstate[3] == 0x60 ||
sc->sc_fpstate[3] == 0xe0))
goto out;
} else if (CPU_IS_COLDFIRE) {
if (!(sc->sc_fpstate[0] == 0x00 ||
sc->sc_fpstate[0] == 0x05 ||
sc->sc_fpstate[0] == 0xe5))
goto out;
} else
goto out;

__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %0,%%fp0-%%fp1\n\t"
"fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
".chip 68k"
: /* no outputs */
: "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl));
if (CPU_IS_COLDFIRE) {
__asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t"
"fmovel %1,%%fpcr\n\t"
"fmovel %2,%%fpsr\n\t"
"fmovel %3,%%fpiar"
: /* no outputs */
: "m" (sc->sc_fpregs[0]),
"m" (sc->sc_fpcntl[0]),
"m" (sc->sc_fpcntl[1]),
"m" (sc->sc_fpcntl[2]));
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %0,%%fp0-%%fp1\n\t"
"fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
".chip 68k"
: /* no outputs */
: "m" (*sc->sc_fpregs),
"m" (*sc->sc_fpcntl));
}
}

if (CPU_IS_COLDFIRE) {
__asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate));
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"frestore %0\n\t"
".chip 68k"
: : "m" (*sc->sc_fpstate));
}
__asm__ volatile (".chip 68k/68881\n\t"
"frestore %0\n\t"
".chip 68k" : : "m" (*sc->sc_fpstate));
err = 0;

out:
Expand All @@ -249,7 +274,7 @@ static inline int restore_fpu_state(struct sigcontext *sc)
static inline int rt_restore_fpu_state(struct ucontext __user *uc)
{
unsigned char fpstate[FPCONTEXT_SIZE];
int context_size = CPU_IS_060 ? 8 : 0;
int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
fpregset_t fpregs;
int err = 1;

Expand All @@ -268,10 +293,11 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc)
if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
goto out;
if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
if (!CPU_IS_060)
if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
context_size = fpstate[1];
/* Verify the frame format. */
if (!CPU_IS_060 && (fpstate[0] != fpu_version))
if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
(fpstate[0] != fpu_version))
goto out;
if (CPU_IS_020_OR_030) {
if (m68k_fputype & FPU_68881 &&
Expand All @@ -290,26 +316,50 @@ static inline int rt_restore_fpu_state(struct ucontext __user *uc)
fpstate[3] == 0x60 ||
fpstate[3] == 0xe0))
goto out;
} else if (CPU_IS_COLDFIRE) {
if (!(fpstate[3] == 0x00 ||
fpstate[3] == 0x05 ||
fpstate[3] == 0xe5))
goto out;
} else
goto out;
if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
sizeof(fpregs)))
goto out;
__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %0,%%fp0-%%fp7\n\t"
"fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
".chip 68k"
: /* no outputs */
: "m" (*fpregs.f_fpregs),
"m" (*fpregs.f_fpcntl));

if (CPU_IS_COLDFIRE) {
__asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t"
"fmovel %1,%%fpcr\n\t"
"fmovel %2,%%fpsr\n\t"
"fmovel %3,%%fpiar"
: /* no outputs */
: "m" (fpregs.f_fpregs[0]),
"m" (fpregs.f_fpcntl[0]),
"m" (fpregs.f_fpcntl[1]),
"m" (fpregs.f_fpcntl[2]));
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %0,%%fp0-%%fp7\n\t"
"fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
".chip 68k"
: /* no outputs */
: "m" (*fpregs.f_fpregs),
"m" (*fpregs.f_fpcntl));
}
}
if (context_size &&
__copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
context_size))
goto out;
__asm__ volatile (".chip 68k/68881\n\t"
"frestore %0\n\t"
".chip 68k" : : "m" (*fpstate));

if (CPU_IS_COLDFIRE) {
__asm__ volatile ("frestore %0" : : "m" (*fpstate));
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"frestore %0\n\t"
".chip 68k"
: : "m" (*fpstate));
}
err = 0;

out:
Expand Down Expand Up @@ -529,10 +579,15 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
return;
}

__asm__ volatile (".chip 68k/68881\n\t"
"fsave %0\n\t"
".chip 68k"
: : "m" (*sc->sc_fpstate) : "memory");
if (CPU_IS_COLDFIRE) {
__asm__ volatile ("fsave %0"
: : "m" (*sc->sc_fpstate) : "memory");
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"fsave %0\n\t"
".chip 68k"
: : "m" (*sc->sc_fpstate) : "memory");
}

if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
fpu_version = sc->sc_fpstate[0];
Expand All @@ -543,21 +598,35 @@ static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
sc->sc_fpstate[0x38] |= 1 << 3;
}
__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %%fp0-%%fp1,%0\n\t"
"fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
".chip 68k"
: "=m" (*sc->sc_fpregs),
"=m" (*sc->sc_fpcntl)
: /* no inputs */
: "memory");

if (CPU_IS_COLDFIRE) {
__asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t"
"fmovel %%fpcr,%1\n\t"
"fmovel %%fpsr,%2\n\t"
"fmovel %%fpiar,%3"
: "=m" (sc->sc_fpregs[0]),
"=m" (sc->sc_fpcntl[0]),
"=m" (sc->sc_fpcntl[1]),
"=m" (sc->sc_fpcntl[2])
: /* no inputs */
: "memory");
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %%fp0-%%fp1,%0\n\t"
"fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
".chip 68k"
: "=m" (*sc->sc_fpregs),
"=m" (*sc->sc_fpcntl)
: /* no inputs */
: "memory");
}
}
}

static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
{
unsigned char fpstate[FPCONTEXT_SIZE];
int context_size = CPU_IS_060 ? 8 : 0;
int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
int err = 0;

if (FPU_IS_EMU) {
Expand All @@ -570,15 +639,19 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *
return err;
}

__asm__ volatile (".chip 68k/68881\n\t"
"fsave %0\n\t"
".chip 68k"
: : "m" (*fpstate) : "memory");
if (CPU_IS_COLDFIRE) {
__asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory");
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"fsave %0\n\t"
".chip 68k"
: : "m" (*fpstate) : "memory");
}

err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
fpregset_t fpregs;
if (!CPU_IS_060)
if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
context_size = fpstate[1];
fpu_version = fpstate[0];
if (CPU_IS_020_OR_030 &&
Expand All @@ -588,14 +661,27 @@ static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *
if (*(unsigned short *) fpstate == 0x1f38)
fpstate[0x38] |= 1 << 3;
}
__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %%fp0-%%fp7,%0\n\t"
"fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
".chip 68k"
: "=m" (*fpregs.f_fpregs),
"=m" (*fpregs.f_fpcntl)
: /* no inputs */
: "memory");
if (CPU_IS_COLDFIRE) {
__asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t"
"fmovel %%fpcr,%1\n\t"
"fmovel %%fpsr,%2\n\t"
"fmovel %%fpiar,%3"
: "=m" (fpregs.f_fpregs[0]),
"=m" (fpregs.f_fpcntl[0]),
"=m" (fpregs.f_fpcntl[1]),
"=m" (fpregs.f_fpcntl[2])
: /* no inputs */
: "memory");
} else {
__asm__ volatile (".chip 68k/68881\n\t"
"fmovemx %%fp0-%%fp7,%0\n\t"
"fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
".chip 68k"
: "=m" (*fpregs.f_fpregs),
"=m" (*fpregs.f_fpcntl)
: /* no inputs */
: "memory");
}
err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
sizeof(fpregs));
}
Expand Down Expand Up @@ -692,8 +778,7 @@ static inline void push_cache (unsigned long vaddr)
"cpushl %%bc,(%0)\n\t"
".chip 68k"
: : "a" (temp));
}
else {
} else if (!CPU_IS_COLDFIRE) {
/*
* 68030/68020 have no writeback cache;
* still need to clear icache.
Expand Down

0 comments on commit 7836251

Please sign in to comment.