at v2.6.21-rc2 147 lines 3.1 kB view raw
1/* 2 * Copyright (C) 2002 MontaVista Software Inc. 3 * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License as published by the 7 * Free Software Foundation; either version 2 of the License, or (at your 8 * option) any later version. 9 */ 10#ifndef _ASM_FPU_H 11#define _ASM_FPU_H 12 13#include <linux/sched.h> 14#include <linux/thread_info.h> 15 16#include <asm/mipsregs.h> 17#include <asm/cpu.h> 18#include <asm/cpu-features.h> 19#include <asm/bitops.h> 20#include <asm/processor.h> 21#include <asm/current.h> 22 23#ifdef CONFIG_MIPS_MT_FPAFF 24#include <asm/mips_mt.h> 25#endif 26 27struct sigcontext; 28struct sigcontext32; 29 30extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); 31extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); 32 33extern asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc); 34extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc); 35 36extern void fpu_emulator_init_fpu(void); 37extern void _init_fpu(void); 38extern void _save_fp(struct task_struct *); 39extern void _restore_fp(struct task_struct *); 40 41#if defined(CONFIG_CPU_SB1) 42#define __enable_fpu_hazard() \ 43do { \ 44 asm(".set push \n\t" \ 45 ".set mips64 \n\t" \ 46 ".set noreorder \n\t" \ 47 "ssnop \n\t" \ 48 "bnezl $0, .+4 \n\t" \ 49 "ssnop \n\t" \ 50 ".set pop"); \ 51} while (0) 52#else 53#define __enable_fpu_hazard() \ 54do { \ 55 asm("nop;nop;nop;nop"); /* max. hazard */ \ 56} while (0) 57#endif 58 59#define __enable_fpu() \ 60do { \ 61 set_c0_status(ST0_CU1); \ 62 __enable_fpu_hazard(); \ 63} while (0) 64 65#define __disable_fpu() \ 66do { \ 67 clear_c0_status(ST0_CU1); \ 68 /* We don't care about the c0 hazard here */ \ 69} while (0) 70 71#define enable_fpu() \ 72do { \ 73 if (cpu_has_fpu) \ 74 __enable_fpu(); \ 75} while (0) 76 77#define disable_fpu() \ 78do { \ 79 if (cpu_has_fpu) \ 80 __disable_fpu(); \ 81} while (0) 82 83 84#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU) 85 86static inline int __is_fpu_owner(void) 87{ 88 return test_thread_flag(TIF_USEDFPU); 89} 90 91static inline int is_fpu_owner(void) 92{ 93 return cpu_has_fpu && __is_fpu_owner(); 94} 95 96static inline void own_fpu(void) 97{ 98 if (cpu_has_fpu) { 99 __enable_fpu(); 100 KSTK_STATUS(current) |= ST0_CU1; 101 set_thread_flag(TIF_USEDFPU); 102 } 103} 104 105static inline void lose_fpu(void) 106{ 107 if (cpu_has_fpu) { 108 KSTK_STATUS(current) &= ~ST0_CU1; 109 clear_thread_flag(TIF_USEDFPU); 110 __disable_fpu(); 111 } 112} 113 114static inline void init_fpu(void) 115{ 116 if (cpu_has_fpu) { 117 _init_fpu(); 118 } else { 119 fpu_emulator_init_fpu(); 120 } 121} 122 123static inline void save_fp(struct task_struct *tsk) 124{ 125 if (cpu_has_fpu) 126 _save_fp(tsk); 127} 128 129static inline void restore_fp(struct task_struct *tsk) 130{ 131 if (cpu_has_fpu) 132 _restore_fp(tsk); 133} 134 135static inline fpureg_t *get_fpu_regs(struct task_struct *tsk) 136{ 137 if (tsk == current) { 138 preempt_disable(); 139 if (is_fpu_owner()) 140 _save_fp(current); 141 preempt_enable(); 142 } 143 144 return tsk->thread.fpu.fpr; 145} 146 147#endif /* _ASM_FPU_H */