1/* MN10300 FPU definitions 2 * 3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * Derived from include/asm-i386/i387.h: Copyright (C) 1994 Linus Torvalds 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public Licence 9 * as published by the Free Software Foundation; either version 10 * 2 of the Licence, or (at your option) any later version. 11 */ 12#ifndef _ASM_FPU_H 13#define _ASM_FPU_H 14 15#ifndef __ASSEMBLY__ 16 17#include <linux/sched.h> 18#include <asm/exceptions.h> 19#include <asm/sigcontext.h> 20 21#ifdef __KERNEL__ 22 23extern asmlinkage void fpu_disabled(void); 24 25#ifdef CONFIG_FPU 26 27#ifdef CONFIG_LAZY_SAVE_FPU 28/* the task that currently owns the FPU state */ 29extern struct task_struct *fpu_state_owner; 30#endif 31 32#if (THREAD_USING_FPU & ~0xff) 33#error THREAD_USING_FPU must be smaller than 0x100. 34#endif 35 36static inline void set_using_fpu(struct task_struct *tsk) 37{ 38 asm volatile( 39 "bset %0,(0,%1)" 40 : 41 : "i"(THREAD_USING_FPU), "a"(&tsk->thread.fpu_flags) 42 : "memory", "cc"); 43} 44 45static inline void clear_using_fpu(struct task_struct *tsk) 46{ 47 asm volatile( 48 "bclr %0,(0,%1)" 49 : 50 : "i"(THREAD_USING_FPU), "a"(&tsk->thread.fpu_flags) 51 : "memory", "cc"); 52} 53 54#define is_using_fpu(tsk) ((tsk)->thread.fpu_flags & THREAD_USING_FPU) 55 56extern asmlinkage void fpu_kill_state(struct task_struct *); 57extern asmlinkage void fpu_exception(struct pt_regs *, enum exception_code); 58extern asmlinkage void fpu_init_state(void); 59extern asmlinkage void fpu_save(struct fpu_state_struct *); 60extern int fpu_setup_sigcontext(struct fpucontext *buf); 61extern int fpu_restore_sigcontext(struct fpucontext *buf); 62 63static inline void unlazy_fpu(struct task_struct *tsk) 64{ 65 preempt_disable(); 66#ifndef CONFIG_LAZY_SAVE_FPU 67 if (tsk->thread.fpu_flags & THREAD_HAS_FPU) { 68 fpu_save(&tsk->thread.fpu_state); 69 tsk->thread.fpu_flags &= ~THREAD_HAS_FPU; 70 tsk->thread.uregs->epsw &= ~EPSW_FE; 71 } 72#else 73 if (fpu_state_owner == tsk) 74 fpu_save(&tsk->thread.fpu_state); 75#endif 76 preempt_enable(); 77} 78 79static inline void exit_fpu(void) 80{ 81#ifdef CONFIG_LAZY_SAVE_FPU 82 struct task_struct *tsk = current; 83 84 preempt_disable(); 85 if (fpu_state_owner == tsk) 86 fpu_state_owner = NULL; 87 preempt_enable(); 88#endif 89} 90 91static inline void flush_fpu(void) 92{ 93 struct task_struct *tsk = current; 94 95 preempt_disable(); 96#ifndef CONFIG_LAZY_SAVE_FPU 97 if (tsk->thread.fpu_flags & THREAD_HAS_FPU) { 98 tsk->thread.fpu_flags &= ~THREAD_HAS_FPU; 99 tsk->thread.uregs->epsw &= ~EPSW_FE; 100 } 101#else 102 if (fpu_state_owner == tsk) { 103 fpu_state_owner = NULL; 104 tsk->thread.uregs->epsw &= ~EPSW_FE; 105 } 106#endif 107 preempt_enable(); 108 clear_using_fpu(tsk); 109} 110 111#else /* CONFIG_FPU */ 112 113extern asmlinkage 114void unexpected_fpu_exception(struct pt_regs *, enum exception_code); 115#define fpu_exception unexpected_fpu_exception 116 117struct task_struct; 118struct fpu_state_struct; 119static inline bool is_using_fpu(struct task_struct *tsk) { return false; } 120static inline void set_using_fpu(struct task_struct *tsk) {} 121static inline void clear_using_fpu(struct task_struct *tsk) {} 122static inline void fpu_init_state(void) {} 123static inline void fpu_save(struct fpu_state_struct *s) {} 124static inline void fpu_kill_state(struct task_struct *tsk) {} 125static inline void unlazy_fpu(struct task_struct *tsk) {} 126static inline void exit_fpu(void) {} 127static inline void flush_fpu(void) {} 128static inline int fpu_setup_sigcontext(struct fpucontext *buf) { return 0; } 129static inline int fpu_restore_sigcontext(struct fpucontext *buf) { return 0; } 130#endif /* CONFIG_FPU */ 131 132#endif /* __KERNEL__ */ 133#endif /* !__ASSEMBLY__ */ 134#endif /* _ASM_FPU_H */ 135