at v2.6.15-rc2 143 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/config.h> 14#include <linux/sched.h> 15#include <linux/thread_info.h> 16 17#include <asm/mipsregs.h> 18#include <asm/cpu.h> 19#include <asm/cpu-features.h> 20#include <asm/bitops.h> 21#include <asm/processor.h> 22#include <asm/current.h> 23 24struct sigcontext; 25struct sigcontext32; 26 27extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); 28extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); 29 30extern asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc); 31extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc); 32 33extern void fpu_emulator_init_fpu(void); 34extern void _init_fpu(void); 35extern void _save_fp(struct task_struct *); 36extern void _restore_fp(struct task_struct *); 37 38#if defined(CONFIG_CPU_SB1) 39#define __enable_fpu_hazard() \ 40do { \ 41 asm(".set push \n\t" \ 42 ".set mips64 \n\t" \ 43 ".set noreorder \n\t" \ 44 "ssnop \n\t" \ 45 "bnezl $0, .+4 \n\t" \ 46 "ssnop \n\t" \ 47 ".set pop"); \ 48} while (0) 49#else 50#define __enable_fpu_hazard() \ 51do { \ 52 asm("nop;nop;nop;nop"); /* max. hazard */ \ 53} while (0) 54#endif 55 56#define __enable_fpu() \ 57do { \ 58 set_c0_status(ST0_CU1); \ 59 __enable_fpu_hazard(); \ 60} while (0) 61 62#define __disable_fpu() \ 63do { \ 64 clear_c0_status(ST0_CU1); \ 65 /* We don't care about the c0 hazard here */ \ 66} while (0) 67 68#define enable_fpu() \ 69do { \ 70 if (cpu_has_fpu) \ 71 __enable_fpu(); \ 72} while (0) 73 74#define disable_fpu() \ 75do { \ 76 if (cpu_has_fpu) \ 77 __disable_fpu(); \ 78} while (0) 79 80 81#define clear_fpu_owner() clear_thread_flag(TIF_USEDFPU) 82 83static inline int __is_fpu_owner(void) 84{ 85 return test_thread_flag(TIF_USEDFPU); 86} 87 88static inline int is_fpu_owner(void) 89{ 90 return cpu_has_fpu && __is_fpu_owner(); 91} 92 93static inline void own_fpu(void) 94{ 95 if (cpu_has_fpu) { 96 __enable_fpu(); 97 KSTK_STATUS(current) |= ST0_CU1; 98 set_thread_flag(TIF_USEDFPU); 99 } 100} 101 102static inline void lose_fpu(void) 103{ 104 if (cpu_has_fpu) { 105 KSTK_STATUS(current) &= ~ST0_CU1; 106 clear_thread_flag(TIF_USEDFPU); 107 __disable_fpu(); 108 } 109} 110 111static inline void init_fpu(void) 112{ 113 if (cpu_has_fpu) { 114 _init_fpu(); 115 } else { 116 fpu_emulator_init_fpu(); 117 } 118} 119 120static inline void save_fp(struct task_struct *tsk) 121{ 122 if (cpu_has_fpu) 123 _save_fp(tsk); 124} 125 126static inline void restore_fp(struct task_struct *tsk) 127{ 128 if (cpu_has_fpu) 129 _restore_fp(tsk); 130} 131 132static inline fpureg_t *get_fpu_regs(struct task_struct *tsk) 133{ 134 if (cpu_has_fpu) { 135 if ((tsk == current) && __is_fpu_owner()) 136 _save_fp(current); 137 return tsk->thread.fpu.hard.fpr; 138 } 139 140 return tsk->thread.fpu.soft.fpr; 141} 142 143#endif /* _ASM_FPU_H */