base/include/asm/rtai_fpu.h

Go to the documentation of this file.
00001 /* 00002 * This program is free software; you can redistribute it and/or modify 00003 * it under the terms of the GNU General Public License as published by 00004 * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, 00005 * USA; either version 2 of the License, or (at your option) any later 00006 * version. 00007 * 00008 * This program is distributed in the hope that it will be useful, 00009 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 * GNU General Public License for more details. 00012 * 00013 * You should have received a copy of the GNU General Public License 00014 * along with this program; if not, write to the Free Software 00015 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00016 */ 00017 00018 /* 00019 * Part of this code acked from Linux i387.h and i387.c: 00020 * Copyright (C) 1994 Linus Torvalds, 00021 * Copyright (C) 2000 Gareth Hughes <gareth@valinux.com>, 00022 * original idea of an RTAI own header file for the FPU stuff: 00023 * Copyright (C) 2000 Pierre Cloutier <pcloutier@PoseidonControls.com>, 00024 * this final rewrite and cleanup: 00025 * Copyright (C) 2005 Paolo Mantegazza <mantegazza@aero.polimi.it>. 00026 */ 00027 00028 #ifndef _RTAI_ASM_I386_FPU_H 00029 #define _RTAI_ASM_I386_FPU_H 00030 00031 #ifndef __cplusplus 00032 #include <asm/processor.h> 00033 #endif /* !__cplusplus */ 00034 00035 typedef union i387_union FPU_ENV; 00036 00037 #ifdef CONFIG_RTAI_FPU_SUPPORT 00038 00039 // RAW FPU MANAGEMENT FOR USAGE FROM WHAT/WHEREVER RTAI DOES IN KERNEL 00040 00041 #define enable_fpu() do { \ 00042 __asm__ __volatile__ ("clts"); \ 00043 } while(0) 00044 00045 #define save_fpcr_and_enable_fpu(fpcr) do { \ 00046 __asm__ __volatile__ ("movl %%cr0, %0; clts": "=r" (fpcr)); \ 00047 } while (0) 00048 00049 #define restore_fpcr(fpcr) do { \ 00050 if (fpcr & 8) { \ 00051 __asm__ __volatile__ ("movl %%cr0, %0": "=r" (fpcr)); \ 00052 __asm__ __volatile__ ("movl %0, %%cr0": :"r" (fpcr | 8)); \ 00053 } \ 00054 } while (0) 00055 00056 // initialise the hard fpu unit directly 00057 #define init_hard_fpenv() do { \ 00058 __asm__ __volatile__ ("clts; fninit"); \ 00059 if (cpu_has_xmm) { \ 00060 unsigned long __mxcsr = (0xffbfu & 0x1f80u); \ 00061 __asm__ __volatile__ ("ldmxcsr %0": : "m" (__mxcsr)); \ 00062 } \ 00063 } while (0) 00064 00065 // initialise the given fpenv union, without touching the related hard fpu unit 00066 #define init_fpenv(fpenv) do { \ 00067 if (cpu_has_fxsr) { \ 00068 memset(&(fpenv).fxsave, 0, sizeof(struct i387_fxsave_struct)); \ 00069 (fpenv).fxsave.cwd = 0x37f; \ 00070 if (cpu_has_xmm) { \ 00071 (fpenv).fxsave.mxcsr = 0x1f80; \ 00072 } \ 00073 } else { \ 00074 memset(&(fpenv).fsave, 0, sizeof(struct i387_fsave_struct)); \ 00075 (fpenv).fsave.cwd = 0xffff037fu; \ 00076 (fpenv).fsave.swd = 0xffff0000u; \ 00077 (fpenv).fsave.twd = 0xffffffffu; \ 00078 (fpenv).fsave.fos = 0xffff0000u; \ 00079 } \ 00080 } while (0) 00081 00082 #define save_fpenv(fpenv) do { \ 00083 if (cpu_has_fxsr) { \ 00084 __asm__ __volatile__ ("fxsave %0; fnclex": "=m" ((fpenv).fxsave)); \ 00085 } else { \ 00086 __asm__ __volatile__ ("fnsave %0; fwait": "=m" ((fpenv).fsave)); \ 00087 } \ 00088 } while (0) 00089 00090 #define restore_fpenv(fpenv) do { \ 00091 if (cpu_has_fxsr) { \ 00092 __asm__ __volatile__ ("fxrstor %0": : "m" ((fpenv).fxsave)); \ 00093 } else { \ 00094 __asm__ __volatile__ ("frstor %0": : "m" ((fpenv).fsave)); \ 00095 } \ 00096 } while (0) 00097 00098 // FPU MANAGEMENT DRESSED FOR IN KTHREAD/THREAD/PROCESS FPU USAGE FROM RTAI 00099 00100 #define init_hard_fpu(lnxtsk) do { \ 00101 init_hard_fpenv(); \ 00102 set_lnxtsk_uses_fpu(lnxtsk); \ 00103 set_lnxtsk_using_fpu(lnxtsk); \ 00104 } while (0) 00105 00106 #define init_fpu(lnxtsk) do { \ 00107 init_fpenv((lnxtsk)->thread.i387); \ 00108 set_lnxtsk_uses_fpu(lnxtsk); \ 00109 } while (0) 00110 00111 #define restore_fpu(lnxtsk) do { \ 00112 enable_fpu(); \ 00113 restore_fpenv((lnxtsk)->thread.i387); \ 00114 set_lnxtsk_using_fpu(lnxtsk); \ 00115 } while (0) 00116 00117 #else /* !CONFIG_RTAI_FPU_SUPPORT */ 00118 00119 #define enable_fpu() 00120 #define save_fpcr_and_enable_fpu(fpcr) 00121 #define restore_fpcr(fpcr) 00122 #define init_hard_fpenv() 00123 #define init_fpenv(fpenv) 00124 #define save_fpenv(fpenv) 00125 #define restore_fpenv(fpenv) 00126 #define init_hard_fpu(lnxtsk) 00127 #define init_fpu(lnxtsk) 00128 #define restore_fpu(lnxtsk) 00129 00130 #endif /* CONFIG_RTAI_FPU_SUPPORT */ 00131 00132 00133 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) 00134 00135 #define set_lnxtsk_uses_fpu(lnxtsk) \ 00136 do { (lnxtsk)->used_math = 1; } while(0) 00137 #define clear_lnxtsk_uses_fpu(lnxtsk) \ 00138 do { (lnxtsk)->used_math = 0; } while(0) 00139 #define lnxtsk_uses_fpu(lnxtsk) ((lnxtsk)->used_math) 00140 00141 #define set_lnxtsk_using_fpu(lnxtsk) \ 00142 do { (lnxtsk)->flags |= PF_USEDFPU; } while(0) 00143 00144 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */ 00145 00146 00147 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) 00148 00149 #define set_lnxtsk_uses_fpu(lnxtsk) \ 00150 do { (lnxtsk)->used_math = 1; } while(0) 00151 #define clear_lnxtsk_uses_fpu(lnxtsk) \ 00152 do { (lnxtsk)->used_math = 0; } while(0) 00153 #define lnxtsk_uses_fpu(lnxtsk) ((lnxtsk)->used_math) 00154 00155 #define set_lnxtsk_using_fpu(lnxtsk) \ 00156 do { (lnxtsk)->thread_info->status |= TS_USEDFPU; } while(0) 00157 00158 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) */ 00159 00160 00161 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) 00162 00163 #define set_lnxtsk_uses_fpu(lnxtsk) \ 00164 do { set_stopped_child_used_math(lnxtsk); } while(0) 00165 #define clear_lnxtsk_uses_fpu(lnxtsk) \ 00166 do { clear_stopped_child_used_math(lnxtsk); } while(0) 00167 #define lnxtsk_uses_fpu(lnxtsk) (tsk_used_math(lnxtsk)) 00168 00169 #define set_lnxtsk_using_fpu(lnxtsk) \ 00170 do { (lnxtsk)->thread_info->status |= TS_USEDFPU; } while(0) 00171 00172 #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) */ 00173 00174 00175 #endif /* !_RTAI_ASM_I386_FPU_H */

Generated on Thu Nov 20 11:49:48 2008 for RTAI API by doxygen 1.3.8