--- arch/m68k/kernel/asm-offsets.c | 3 arch/m68k/kernel/entry.S | 4 arch/m68k/kernel/process.c | 6 + arch/m68k/kernel/ptrace.c | 6 + arch/m68k/kernel/setup.c | 6 - arch/m68k/kernel/signal.c | 195 +++++++++++++++++++++-------------------- include/asm-m68k/processor.h | 2 7 files changed, 125 insertions(+), 97 deletions(-) --- linux-m68k-2.6.8.1+uc0/arch/m68k/kernel/asm-offsets.c 2004-04-30 17:54:35.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/kernel/asm-offsets.c 2004-05-04 22:42:37.000000000 +0200 @@ -8,6 +8,7 @@ * #defines from the assembly-language output. */ +#include #include #include #include @@ -42,9 +43,11 @@ int main(void) DEFINE(THREAD_FS, offsetof(struct thread_struct, fs)); DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp)); DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0)); +#ifdef CONFIG_FPU DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp)); DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl)); DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate)); +#endif /* offsets into the thread_info struct */ DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count)); --- linux-m68k-2.6.8.1+uc0/arch/m68k/kernel/entry.S 2004-05-24 11:13:22.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/kernel/entry.S 2004-06-26 17:19:20.000000000 +0200 @@ -343,7 +458,7 @@ resume: movel %sp,%a0@(TASK_THREAD+THREAD_KSP) /* save floating point context */ -#ifndef CONFIG_M68KFPU_EMU_ONLY +#if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU_ONLY) #ifdef CONFIG_M68KFPU_EMU tstl m68k_fputype jeq 3f @@ -377,7 +492,7 @@ resume: movel %a1,%curptr /* restore floating point context */ -#ifndef CONFIG_M68KFPU_EMU_ONLY +#if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU_ONLY) #ifdef CONFIG_M68KFPU_EMU tstl m68k_fputype jeq 4f --- linux-m68k-2.6.8.1+uc0/arch/m68k/kernel/process.c 2004-06-21 20:20:00.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/kernel/process.c 2004-06-26 17:17:36.000000000 +0200 @@ -264,6 +264,7 @@ int copy_thread(int nr, unsigned long cl */ p->thread.fs = get_fs().seg; +#ifdef CONFIG_FPU if (!FPU_IS_EMU) { /* Copy the current fpu state */ asm volatile ("fsave %0" : : "m" (p->thread.fpstate[0]) : "memory"); @@ -276,6 +277,7 @@ int copy_thread(int nr, unsigned long cl /* Restore the state in case the fpu was busy */ asm volatile ("frestore %0" : : "m" (p->thread.fpstate[0])); } +#endif /* CONFIG_FPU */ return 0; } @@ -284,6 +286,7 @@ int copy_thread(int nr, unsigned long cl int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) { +#ifdef CONFIG_FPU char fpustate[216]; if (FPU_IS_EMU) { @@ -311,7 +314,8 @@ int dump_fpu (struct pt_regs *regs, stru asm volatile ("fmovemx %/fp0-%/fp7,%0" :: "m" (fpu->fpregs[0]) : "memory"); - return 1; +#endif /* CONFIG_FPU */ + return 0; } /* --- linux-m68k-2.6.8.1+uc0/arch/m68k/kernel/ptrace.c 2004-05-24 11:13:22.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/kernel/ptrace.c 2004-06-26 17:17:36.000000000 +0200 @@ -185,6 +185,7 @@ asmlinkage int sys_ptrace(long request, tmp = get_reg(child, addr); if (addr == PT_SR) tmp >>= 16; +#ifdef CONFIG_FPU } else if (addr >= 21 && addr < 49) { tmp = child->thread.fp[addr - 21]; #ifdef CONFIG_M68KFPU_EMU @@ -195,6 +196,7 @@ asmlinkage int sys_ptrace(long request, tmp = ((tmp & 0xffff0000) << 15) | ((tmp & 0x0000ffff) << 16); #endif +#endif /* CONFIG_FPU */ } else break; ret = put_user(tmp,(unsigned long *) data); @@ -229,6 +231,7 @@ asmlinkage int sys_ptrace(long request, ret = 0; break; } +#ifdef CONFIG_FPU if (addr >= 21 && addr < 48) { #ifdef CONFIG_M68KFPU_EMU @@ -244,6 +247,7 @@ asmlinkage int sys_ptrace(long request, child->thread.fp[addr - 21] = data; ret = 0; } +#endif /* CONFIG_FPU */ break; case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ @@ -347,6 +351,7 @@ asmlinkage int sys_ptrace(long request, break; } +#ifdef CONFIG_FPU case PTRACE_GETFPREGS: { /* Get the child FPU state. */ ret = 0; if (copy_to_user((void *)data, &child->thread.fp, @@ -362,6 +367,7 @@ asmlinkage int sys_ptrace(long request, ret = -EFAULT; break; } +#endif /* CONFIG_FPU */ default: ret = ptrace_request(child, request, addr, data); --- linux-m68k-2.6.8.1+uc0/arch/m68k/kernel/setup.c 2004-08-14 15:35:13.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/kernel/setup.c 2004-10-08 21:01:07.000000000 +0200 @@ -221,7 +237,7 @@ void __init setup_arch(char **cmdline_p) * We should really do our own FPU check at startup. * [what do we do with buggy 68LC040s? if we have problems * with them, we should add a test to check_bugs() below] */ -#ifndef CONFIG_M68KFPU_EMU_ONLY +#if !defined(CONFIG_M68KFPU_EMU_ONLY) && defined(CONFIG_FPU) /* clear the fpu if we have one */ if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060)) { volatile int zero = 0; @@ -534,7 +562,7 @@ void __init floppy_setup(char *str, int void check_bugs(void) { -#ifndef CONFIG_M68KFPU_EMU +#if !defined(CONFIG_M68KFPU_EMU) && defined(CONFIG_FPU) if (m68k_fputype == 0) { printk( KERN_EMERG "*** YOU DO NOT HAVE A FLOATING POINT UNIT, " "WHICH IS REQUIRED BY LINUX/M68K ***\n" ); @@ -542,5 +570,5 @@ void check_bugs(void) "emulation project\n" ); panic( "no FPU" ); } -#endif /* !CONFIG_M68KFPU_EMU */ +#endif /* !CONFIG_M68KFPU_EMU && CONFIG_FPU */ } --- linux-m68k-2.6.8.1+uc0/arch/m68k/kernel/signal.c 2004-08-04 12:13:35.000000000 +0200 +++ uClinux-amiga-2.6.8.1/arch/m68k/kernel/signal.c 2004-06-26 17:17:37.000000000 +0200 @@ -28,6 +28,7 @@ * signal handlers! */ +#include #include #include #include @@ -190,7 +191,15 @@ struct rt_sigframe }; -static unsigned char fpu_version; /* version number of fpu, set by setup_frame */ +#define FPCONTEXT_SIZE 216 +#define uc_fpstate uc_filler[0] +#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] +#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] + +#ifdef CONFIG_FPU + +/* version number of fpu, set by setup_frame */ +static unsigned char fpu_version; static inline int restore_fpu_state(struct sigcontext *sc) { @@ -243,11 +252,6 @@ out: return err; } -#define FPCONTEXT_SIZE 216 -#define uc_fpstate uc_filler[0] -#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] -#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] - static inline int rt_restore_fpu_state(struct ucontext *uc) { unsigned char fpstate[FPCONTEXT_SIZE]; @@ -318,6 +322,100 @@ out: return err; } +static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) +{ + if (FPU_IS_EMU) { + /* save registers */ + memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); + memcpy(sc->sc_fpregs, current->thread.fp, 24); + return; + } + + __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]; + if (CPU_IS_020_OR_030 && + regs->vector >= (VEC_FPBRUC * 4) && + regs->vector <= (VEC_FPNAN * 4)) { + /* Clear pending exception in 68882 idle frame */ + 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"); + } +} + +static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs) +{ + unsigned char fpstate[FPCONTEXT_SIZE]; + int context_size = CPU_IS_060 ? 8 : 0; + int err = 0; + + if (FPU_IS_EMU) { + /* save fpu control register */ + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, + current->thread.fpcntl, 12); + /* save all other fpu register */ + err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, + current->thread.fp, 96); + return err; + } + + __asm__ volatile (".chip 68k/68881\n\t" + "fsave %0\n\t" + ".chip 68k" + : : "m" (*fpstate) : "memory"); + + err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate); + if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { + fpregset_t fpregs; + if (!CPU_IS_060) + context_size = fpstate[1]; + fpu_version = fpstate[0]; + if (CPU_IS_020_OR_030 && + regs->vector >= (VEC_FPBRUC * 4) && + regs->vector <= (VEC_FPNAN * 4)) { + /* Clear pending exception in 68882 idle frame */ + 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"); + err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, + sizeof(fpregs)); + } + if (context_size) + err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4, + context_size); + return err; +} + +#else /* !CONFIG_FPU */ + +#define restore_fpu_state(sc) (0) +#define rt_restore_fpu_state(uc) (0) +#define save_fpu_state(sc, regs) do { } while (0) +#define rt_save_fpu_state(uc, regs) (0) + +#endif /* !CONFIG_FPU */ + static inline int restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, int *pd0) @@ -562,91 +660,6 @@ badframe: * Set up a signal frame. */ -static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) -{ - if (FPU_IS_EMU) { - /* save registers */ - memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); - memcpy(sc->sc_fpregs, current->thread.fp, 24); - return; - } - - __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]; - if (CPU_IS_020_OR_030 && - regs->vector >= (VEC_FPBRUC * 4) && - regs->vector <= (VEC_FPNAN * 4)) { - /* Clear pending exception in 68882 idle frame */ - 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"); - } -} - -static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs) -{ - unsigned char fpstate[FPCONTEXT_SIZE]; - int context_size = CPU_IS_060 ? 8 : 0; - int err = 0; - - if (FPU_IS_EMU) { - /* save fpu control register */ - err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl, - current->thread.fpcntl, 12); - /* save all other fpu register */ - err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, - current->thread.fp, 96); - return err; - } - - __asm__ volatile (".chip 68k/68881\n\t" - "fsave %0\n\t" - ".chip 68k" - : : "m" (*fpstate) : "memory"); - - err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate); - if (CPU_IS_060 ? fpstate[2] : fpstate[0]) { - fpregset_t fpregs; - if (!CPU_IS_060) - context_size = fpstate[1]; - fpu_version = fpstate[0]; - if (CPU_IS_020_OR_030 && - regs->vector >= (VEC_FPBRUC * 4) && - regs->vector <= (VEC_FPNAN * 4)) { - /* Clear pending exception in 68882 idle frame */ - 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"); - err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, - sizeof(fpregs)); - } - if (context_size) - err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4, - context_size); - return err; -} - static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask) { --- linux-m68k-2.6.8.1+uc0/include/asm-m68k/processor.h 2004-04-30 17:54:35.000000000 +0200 +++ uClinux-amiga-2.6.8.1/include/asm-m68k/processor.h 2004-05-03 21:45:15.000000000 +0200 @@ -75,9 +75,11 @@ struct thread_struct { unsigned long esp0; /* points to SR of stack frame */ unsigned long faddr; /* info about last fault */ int signo, code; +#ifdef CONFIG_FPU unsigned long fp[8*3]; unsigned long fpcntl[3]; /* fp control regs */ unsigned char fpstate[FPSTATESIZE]; /* floating point state */ +#endif /* CONFIG_FPU */ struct task_work work; struct thread_info info; };