home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-i386 / i387.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.7 KB  |  148 lines

  1. /*
  2.  * include/asm-i386/i387.h
  3.  *
  4.  * Copyright (C) 1994 Linus Torvalds
  5.  *
  6.  * Pentium III FXSR, SSE support
  7.  * General FPU state handling cleanups
  8.  *    Gareth Hughes <gareth@valinux.com>, May 2000
  9.  */
  10.  
  11. #ifndef __ASM_I386_I387_H
  12. #define __ASM_I386_I387_H
  13.  
  14. #include <linux/sched.h>
  15. #include <linux/init.h>
  16. #include <linux/kernel_stat.h>
  17. #include <asm/processor.h>
  18. #include <asm/sigcontext.h>
  19. #include <asm/user.h>
  20.  
  21. extern void mxcsr_feature_mask_init(void);
  22. extern void init_fpu(struct task_struct *);
  23.  
  24. /*
  25.  * FPU lazy state save handling...
  26.  */
  27.  
  28. /*
  29.  * The "nop" is needed to make the instructions the same
  30.  * length.
  31.  */
  32. #define restore_fpu(tsk)            \
  33.     alternative_input(            \
  34.         "nop ; frstor %1",        \
  35.         "fxrstor %1",            \
  36.         X86_FEATURE_FXSR,        \
  37.         "m" ((tsk)->thread.i387.fxsave))
  38.  
  39. extern void kernel_fpu_begin(void);
  40. #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
  41.  
  42. /* We need a safe address that is cheap to find and that is already
  43.    in L1 during context switch. The best choices are unfortunately
  44.    different for UP and SMP */
  45. #ifdef CONFIG_SMP
  46. #define safe_address (__per_cpu_offset[0])
  47. #else
  48. #define safe_address (kstat_cpu(0).cpustat.user)
  49. #endif
  50.  
  51. /*
  52.  * These must be called with preempt disabled
  53.  */
  54. static inline void __save_init_fpu( struct task_struct *tsk )
  55. {
  56.     /* Use more nops than strictly needed in case the compiler
  57.        varies code */
  58.     alternative_input(
  59.         "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
  60.         "fxsave %[fx]\n"
  61.         "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
  62.         X86_FEATURE_FXSR,
  63.         [fx] "m" (tsk->thread.i387.fxsave),
  64.         [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
  65.     /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
  66.        is pending.  Clear the x87 state here by setting it to fixed
  67.           values. safe_address is a random variable that should be in L1 */
  68.     alternative_input(
  69.         GENERIC_NOP8 GENERIC_NOP2,
  70.         "emms\n\t"          /* clear stack tags */
  71.         "fildl %[addr]",     /* set F?P to defined value */
  72.         X86_FEATURE_FXSAVE_LEAK,
  73.         [addr] "m" (safe_address));
  74.     task_thread_info(tsk)->status &= ~TS_USEDFPU;
  75. }
  76.  
  77. #define __unlazy_fpu( tsk ) do { \
  78.     if (task_thread_info(tsk)->status & TS_USEDFPU) \
  79.         save_init_fpu( tsk ); \
  80. } while (0)
  81.  
  82. #define __clear_fpu( tsk )                    \
  83. do {                                \
  84.     if (task_thread_info(tsk)->status & TS_USEDFPU) {        \
  85.         asm volatile("fnclex ; fwait");                \
  86.         task_thread_info(tsk)->status &= ~TS_USEDFPU;    \
  87.         stts();                        \
  88.     }                            \
  89. } while (0)
  90.  
  91.  
  92. /*
  93.  * These disable preemption on their own and are safe
  94.  */
  95. static inline void save_init_fpu( struct task_struct *tsk )
  96. {
  97.     preempt_disable();
  98.     __save_init_fpu(tsk);
  99.     stts();
  100.     preempt_enable();
  101. }
  102.  
  103. #define unlazy_fpu( tsk ) do {    \
  104.     preempt_disable();    \
  105.     __unlazy_fpu(tsk);    \
  106.     preempt_enable();    \
  107. } while (0)
  108.  
  109. #define clear_fpu( tsk ) do {    \
  110.     preempt_disable();    \
  111.     __clear_fpu( tsk );    \
  112.     preempt_enable();    \
  113. } while (0)
  114.                     \
  115. /*
  116.  * FPU state interaction...
  117.  */
  118. extern unsigned short get_fpu_cwd( struct task_struct *tsk );
  119. extern unsigned short get_fpu_swd( struct task_struct *tsk );
  120. extern unsigned short get_fpu_mxcsr( struct task_struct *tsk );
  121.  
  122. /*
  123.  * Signal frame handlers...
  124.  */
  125. extern int save_i387( struct _fpstate __user *buf );
  126. extern int restore_i387( struct _fpstate __user *buf );
  127.  
  128. /*
  129.  * ptrace request handers...
  130.  */
  131. extern int get_fpregs( struct user_i387_struct __user *buf,
  132.                struct task_struct *tsk );
  133. extern int set_fpregs( struct task_struct *tsk,
  134.                struct user_i387_struct __user *buf );
  135.  
  136. extern int get_fpxregs( struct user_fxsr_struct __user *buf,
  137.             struct task_struct *tsk );
  138. extern int set_fpxregs( struct task_struct *tsk,
  139.             struct user_fxsr_struct __user *buf );
  140.  
  141. /*
  142.  * FPU state for core dumps...
  143.  */
  144. extern int dump_fpu( struct pt_regs *regs,
  145.              struct user_i387_struct *fpu );
  146.  
  147. #endif /* __ASM_I386_I387_H */
  148.