Subversion Repositories Kolibri OS

Rev

Rev 5270 | Rev 6934 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5270 serge 1
#ifndef _ASM_X86_SPECIAL_INSNS_H
2
#define _ASM_X86_SPECIAL_INSNS_H
3
 
4
 
5
#ifdef __KERNEL__
6
 
7
static inline void native_clts(void)
8
{
9
	asm volatile("clts");
10
}
11
 
12
/*
13
 * Volatile isn't enough to prevent the compiler from reordering the
14
 * read/write functions for the control registers and messing everything up.
15
 * A memory clobber would solve the problem, but would prevent reordering of
16
 * all loads stores around it, which can hurt performance. Solution is to
17
 * use a variable and mimic reads and writes to it to enforce serialization
18
 */
19
extern unsigned long __force_order;
20
 
21
static inline unsigned long native_read_cr0(void)
22
{
23
	unsigned long val;
24
	asm volatile("mov %%cr0,%0\n\t" : "=r" (val), "=m" (__force_order));
25
	return val;
26
}
27
 
28
static inline void native_write_cr0(unsigned long val)
29
{
30
	asm volatile("mov %0,%%cr0": : "r" (val), "m" (__force_order));
31
}
32
 
33
static inline unsigned long native_read_cr2(void)
34
{
35
	unsigned long val;
36
	asm volatile("mov %%cr2,%0\n\t" : "=r" (val), "=m" (__force_order));
37
	return val;
38
}
39
 
40
static inline void native_write_cr2(unsigned long val)
41
{
42
	asm volatile("mov %0,%%cr2": : "r" (val), "m" (__force_order));
43
}
44
 
45
static inline unsigned long native_read_cr3(void)
46
{
47
	unsigned long val;
48
	asm volatile("mov %%cr3,%0\n\t" : "=r" (val), "=m" (__force_order));
49
	return val;
50
}
51
 
52
static inline void native_write_cr3(unsigned long val)
53
{
54
	asm volatile("mov %0,%%cr3": : "r" (val), "m" (__force_order));
55
}
56
 
57
static inline unsigned long native_read_cr4(void)
58
{
59
	unsigned long val;
60
	asm volatile("mov %%cr4,%0\n\t" : "=r" (val), "=m" (__force_order));
61
	return val;
62
}
63
 
64
static inline unsigned long native_read_cr4_safe(void)
65
{
66
	unsigned long val;
67
	/* This could fault if %cr4 does not exist. In x86_64, a cr4 always
68
	 * exists, so it will never fail. */
69
#ifdef CONFIG_X86_32
70
	asm volatile("1: mov %%cr4, %0\n"
71
		     "2:\n"
72
		     _ASM_EXTABLE(1b, 2b)
73
		     : "=r" (val), "=m" (__force_order) : "0" (0));
74
#else
75
	val = native_read_cr4();
76
#endif
77
	return val;
78
}
79
 
80
static inline void native_write_cr4(unsigned long val)
81
{
82
	asm volatile("mov %0,%%cr4": : "r" (val), "m" (__force_order));
83
}
84
 
85
#ifdef CONFIG_X86_64
86
static inline unsigned long native_read_cr8(void)
87
{
88
	unsigned long cr8;
89
	asm volatile("movq %%cr8,%0" : "=r" (cr8));
90
	return cr8;
91
}
92
 
93
static inline void native_write_cr8(unsigned long val)
94
{
95
	asm volatile("movq %0,%%cr8" :: "r" (val) : "memory");
96
}
97
#endif
98
 
99
static inline void native_wbinvd(void)
100
{
101
	asm volatile("wbinvd": : :"memory");
102
}
103
 
104
extern asmlinkage void native_load_gs_index(unsigned);
105
 
106
#ifdef CONFIG_PARAVIRT
107
#include 
108
#else
109
 
110
static inline unsigned long read_cr0(void)
111
{
112
	return native_read_cr0();
113
}
114
 
115
static inline void write_cr0(unsigned long x)
116
{
117
	native_write_cr0(x);
118
}
119
 
120
static inline unsigned long read_cr2(void)
121
{
122
	return native_read_cr2();
123
}
124
 
125
static inline void write_cr2(unsigned long x)
126
{
127
	native_write_cr2(x);
128
}
129
 
130
static inline unsigned long read_cr3(void)
131
{
132
	return native_read_cr3();
133
}
134
 
135
static inline void write_cr3(unsigned long x)
136
{
137
	native_write_cr3(x);
138
}
139
 
6082 serge 140
static inline unsigned long __read_cr4(void)
5270 serge 141
{
142
	return native_read_cr4();
143
}
144
 
6082 serge 145
static inline unsigned long __read_cr4_safe(void)
5270 serge 146
{
147
	return native_read_cr4_safe();
148
}
149
 
6082 serge 150
static inline void __write_cr4(unsigned long x)
5270 serge 151
{
152
	native_write_cr4(x);
153
}
154
 
155
static inline void wbinvd(void)
156
{
157
	native_wbinvd();
158
}
159
 
160
#ifdef CONFIG_X86_64
161
 
162
static inline unsigned long read_cr8(void)
163
{
164
	return native_read_cr8();
165
}
166
 
167
static inline void write_cr8(unsigned long x)
168
{
169
	native_write_cr8(x);
170
}
171
 
172
static inline void load_gs_index(unsigned selector)
173
{
174
	native_load_gs_index(selector);
175
}
176
 
177
#endif
178
 
179
/* Clear the 'TS' bit */
180
static inline void clts(void)
181
{
182
	native_clts();
183
}
184
 
185
#endif/* CONFIG_PARAVIRT */
186
 
187
#define stts() write_cr0(read_cr0() | X86_CR0_TS)
188
 
189
static inline void clflush(volatile void *__p)
190
{
191
	asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p));
192
}
193
 
194
static inline void clflushopt(volatile void *__p)
195
{
196
	alternative_io(".byte " __stringify(NOP_DS_PREFIX) "; clflush %P0",
197
		       ".byte 0x66; clflush %P0",
198
		       X86_FEATURE_CLFLUSHOPT,
199
		       "+m" (*(volatile char __force *)__p));
200
}
201
 
202
#define nop() asm volatile ("nop")
203
 
204
 
205
#endif /* __KERNEL__ */
206
 
207
#endif /* _ASM_X86_SPECIAL_INSNS_H */