~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to xen/include/asm-x86/i387.h

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 <xen/sched.h>
 
15
#include <asm/processor.h>
 
16
 
 
17
extern unsigned int xsave_cntxt_size;
 
18
extern u32 xfeature_low, xfeature_high;
 
19
 
 
20
extern void xsave_init(void);
 
21
extern void xsave_init_save_area(void *save_area);
 
22
 
 
23
#define XSTATE_FP       (1 << 0)
 
24
#define XSTATE_SSE      (1 << 1)
 
25
#define XSTATE_YMM      (1 << 2)
 
26
#define XSTATE_FP_SSE   (XSTATE_FP | XSTATE_SSE)
 
27
#define XCNTXT_MASK     (XSTATE_FP | XSTATE_SSE | XSTATE_YMM)
 
28
#define XSTATE_YMM_OFFSET  (512 + 64)
 
29
#define XSTATE_YMM_SIZE    256
 
30
 
 
31
struct xsave_struct
 
32
{
 
33
    struct { char x[512]; } fpu_sse;         /* FPU/MMX, SSE */
 
34
 
 
35
    struct {
 
36
        u64 xstate_bv;
 
37
        u64 reserved[7];
 
38
    } xsave_hdr;                            /* The 64-byte header */
 
39
 
 
40
    struct { char x[XSTATE_YMM_SIZE]; } ymm; /* YMM */
 
41
    char   data[];                           /* Future new states */
 
42
} __attribute__ ((packed, aligned (64)));
 
43
 
 
44
#define XCR_XFEATURE_ENABLED_MASK   0
 
45
 
 
46
#ifdef CONFIG_X86_64
 
47
#define REX_PREFIX "0x48, "
 
48
#else
 
49
#define REX_PREFIX
 
50
#endif
 
51
 
 
52
static inline void xsetbv(u32 index, u64 xfeature_mask)
 
53
{
 
54
    u32 hi = xfeature_mask >> 32;
 
55
    u32 lo = (u32)xfeature_mask;
 
56
 
 
57
    asm volatile (".byte 0x0f,0x01,0xd1" :: "c" (index),
 
58
            "a" (lo), "d" (hi));
 
59
}
 
60
 
 
61
static inline void set_xcr0(u64 xfeature_mask)
 
62
{
 
63
    xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeature_mask);
 
64
}
 
65
 
 
66
static inline void xsave(struct vcpu *v)
 
67
{
 
68
    u64 mask = v->arch.hvm_vcpu.xfeature_mask | XSTATE_FP_SSE;
 
69
    u32 lo = mask, hi = mask >> 32;
 
70
    struct xsave_struct *ptr;
 
71
 
 
72
    ptr =(struct xsave_struct *)v->arch.hvm_vcpu.xsave_area;
 
73
 
 
74
    asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x27"
 
75
        :
 
76
        : "a" (lo), "d" (hi), "D"(ptr)
 
77
        : "memory");
 
78
}
 
79
 
 
80
static inline void xrstor(struct vcpu *v)
 
81
{
 
82
    u64 mask = v->arch.hvm_vcpu.xfeature_mask | XSTATE_FP_SSE;
 
83
    u32 lo = mask, hi = mask >> 32;
 
84
    struct xsave_struct *ptr;
 
85
 
 
86
    ptr =(struct xsave_struct *)v->arch.hvm_vcpu.xsave_area;
 
87
 
 
88
    asm volatile (".byte " REX_PREFIX "0x0f,0xae,0x2f"
 
89
        :
 
90
        : "m" (*ptr), "a" (lo), "d" (hi), "D"(ptr));
 
91
}
 
92
 
 
93
extern void init_fpu(void);
 
94
extern void save_init_fpu(struct vcpu *v);
 
95
extern void restore_fpu(struct vcpu *v);
 
96
 
 
97
#define unlazy_fpu(v) do {                      \
 
98
    if ( (v)->fpu_dirtied )                     \
 
99
        save_init_fpu(v);                       \
 
100
} while ( 0 )
 
101
 
 
102
#define load_mxcsr(val) do {                                    \
 
103
    unsigned long __mxcsr = ((unsigned long)(val) & 0xffbf);    \
 
104
    __asm__ __volatile__ ( "ldmxcsr %0" : : "m" (__mxcsr) );    \
 
105
} while ( 0 )
 
106
 
 
107
static inline void setup_fpu(struct vcpu *v)
 
108
{
 
109
    /* Avoid recursion. */
 
110
    clts();
 
111
 
 
112
    if ( !v->fpu_dirtied )
 
113
    {
 
114
        v->fpu_dirtied = 1;
 
115
        if ( cpu_has_xsave && is_hvm_vcpu(v) )
 
116
        {
 
117
            if ( !v->fpu_initialised )
 
118
                v->fpu_initialised = 1;
 
119
 
 
120
            set_xcr0(v->arch.hvm_vcpu.xfeature_mask | XSTATE_FP_SSE);
 
121
            xrstor(v);
 
122
            set_xcr0(v->arch.hvm_vcpu.xfeature_mask);
 
123
        }
 
124
        else
 
125
        {
 
126
            if ( v->fpu_initialised )
 
127
                restore_fpu(v);
 
128
            else
 
129
                init_fpu();
 
130
        }
 
131
    }
 
132
}
 
133
 
 
134
#endif /* __ASM_I386_I387_H */