sync with trunk head (34904)
[reactos.git] / reactos / ntoskrnl / include / internal / amd64 / intrin_i.h
1 #ifndef _INTRIN_INTERNAL_
2 #define _INTRIN_INTERNAL_
3
4 #ifdef CONFIG_SMP
5 #define LOCK "lock ; "
6 #else
7 #define LOCK ""
8 #endif
9
10 #if defined(__GNUC__)
11
12 #define Ke386SetInterruptDescriptorTable(X) \
13 __asm__("lidt %0\n\t" \
14 : /* no outputs */ \
15 : "m" (X));
16
17 #define Ke386GetInterruptDescriptorTable(X) \
18 __asm__("sidt %0\n\t" \
19 : /* no outputs */ \
20 : "m" (X));
21
22 #define Ke386SetGlobalDescriptorTable(X) \
23 __asm__("lgdt %0\n\t" \
24 : /* no outputs */ \
25 : "m" (X));
26
27 #define Ke386GetGlobalDescriptorTable(X) \
28 __asm__("sgdt %0\n\t" \
29 : /* no outputs */ \
30 : "m" (X));
31
32 #define Ke386GetLocalDescriptorTable(X) \
33 __asm__("sldt %0\n\t" \
34 : /* no outputs */ \
35 : "m" (X));
36
37 #define Ke386SetLocalDescriptorTable(X) \
38 __asm__("lldt %w0\n\t" \
39 : /* no outputs */ \
40 : "q" (X));
41
42 #define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X));
43
44 #define Ke386GetTr(X) \
45 __asm__("str %0\n\t" \
46 : /* no outputs */ \
47 : "m" (X));
48
49 #define Ke386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
50 #define Ke386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
51
52 #define _Ke386GetSeg(N) ({ \
53 unsigned int __d; \
54 __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \
55 __d; \
56 })
57
58 #define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
59
60 #define _Ke386GetDr(N) ({ \
61 unsigned int __d; \
62 __asm__("movl %%dr" #N ",%0\n\t" :"=r" (__d)); \
63 __d; \
64 })
65
66 #define _Ke386SetDr(N,X) __asm__ __volatile__("movl %0,%%dr" #N : :"r" (X));
67
68
69 static inline void Ki386Cpuid(ULONG Op, PULONG Eax, PULONG Ebx, PULONG Ecx, PULONG Edx)
70 {
71 __asm__("cpuid"
72 : "=a" (*Eax), "=b" (*Ebx), "=c" (*Ecx), "=d" (*Edx)
73 : "0" (Op));
74 }
75
76 #define Ke386Rdmsr(msr,val1,val2) __asm__ __volatile__("rdmsr" : "=a" (val1), "=d" (val2) : "c" (msr))
77 #define Ke386Wrmsr(msr,val1,val2) __asm__ __volatile__("wrmsr" : /* no outputs */ : "c" (msr), "a" (val1), "d" (val2))
78
79 #define Ke386HaltProcessor() __asm__("hlt\n\t");
80
81 #define Ke386FnInit() __asm__("fninit\n\t");
82
83
84 //
85 // CR Macros
86 //
87 #define Ke386SetCr2(X) __asm__ __volatile__("movl %0,%%cr2" : :"r" (X));
88
89 //
90 // DR Macros
91 //
92 #define Ke386GetDr0() _Ke386GetDr(0)
93 #define Ke386GetDr1() _Ke386GetDr(1)
94 #define Ke386SetDr0(X) _Ke386SetDr(0,X)
95 #define Ke386SetDr1(X) _Ke386SetDr(1,X)
96 #define Ke386GetDr2() _Ke386GetDr(2)
97 #define Ke386SetDr2(X) _Ke386SetDr(2,X)
98 #define Ke386GetDr3() _Ke386GetDr(3)
99 #define Ke386SetDr3(X) _Ke386SetDr(3,X)
100 #define Ke386GetDr4() _Ke386GetDr(4)
101 #define Ke386SetDr4(X) _Ke386SetDr(4,X)
102 #define Ke386GetDr6() _Ke386GetDr(6)
103 #define Ke386SetDr6(X) _Ke386SetDr(6,X)
104 #define Ke386GetDr7() _Ke386GetDr(7)
105 #define Ke386SetDr7(X) _Ke386SetDr(7,X)
106
107 //
108 // Segment Macros
109 //
110 #define Ke386GetSs() _Ke386GetSeg(ss)
111 #define Ke386GetFs() _Ke386GetSeg(fs)
112 #define Ke386SetFs(X) _Ke386SetSeg(fs, X)
113 #define Ke386SetDs(X) _Ke386SetSeg(ds, X)
114 #define Ke386SetEs(X) _Ke386SetSeg(es, X)
115
116 #elif defined(_MSC_VER)
117
118 VOID
119 FORCEINLINE
120 Ke386Wrmsr(IN ULONG Register,
121 IN ULONG Var1,
122 IN ULONG Var2)
123 {
124 __asm mov eax, Var1;
125 __asm mov edx, Var2;
126 __asm wrmsr;
127 }
128
129 ULONGLONG
130 FORCEINLINE
131 Ke386Rdmsr(IN ULONG Register,
132 IN ULONG Var1,
133 IN ULONG Var2)
134 {
135 __asm mov eax, Var1;
136 __asm mov edx, Var2;
137 __asm rdmsr;
138 }
139
140 VOID
141 FORCEINLINE
142 Ki386Cpuid(IN ULONG Operation,
143 OUT PULONG Var1,
144 OUT PULONG Var2,
145 OUT PULONG Var3,
146 OUT PULONG Var4)
147 {
148 __asm mov eax, Operation;
149 __asm cpuid;
150 __asm mov [Var1], eax;
151 __asm mov [Var2], ebx;
152 __asm mov [Var3], ecx;
153 __asm mov [Var4], edx;
154 }
155
156 VOID
157 FORCEINLINE
158 Ke386FnInit(VOID)
159 {
160 __asm fninit;
161 }
162
163 VOID
164 FORCEINLINE
165 Ke386HaltProcessor(VOID)
166 {
167 __asm hlt;
168 }
169
170 VOID
171 FORCEINLINE
172 Ke386GetInterruptDescriptorTable(OUT KDESCRIPTOR Descriptor)
173 {
174 __asm sidt Descriptor;
175 }
176
177 VOID
178 FORCEINLINE
179 Ke386SetInterruptDescriptorTable(IN KDESCRIPTOR Descriptor)
180 {
181 __asm lidt Descriptor;
182 }
183
184 VOID
185 FORCEINLINE
186 Ke386GetGlobalDescriptorTable(OUT KDESCRIPTOR Descriptor)
187 {
188 __asm sgdt Descriptor;
189 }
190
191 VOID
192 FORCEINLINE
193 Ke386SetGlobalDescriptorTable(IN KDESCRIPTOR Descriptor)
194 {
195 __asm lgdt Descriptor;
196 }
197
198 VOID
199 FORCEINLINE
200 Ke386GetLocalDescriptorTable(OUT USHORT Descriptor)
201 {
202 __asm sldt Descriptor;
203 }
204
205 VOID
206 FORCEINLINE
207 Ke386SetLocalDescriptorTable(IN USHORT Descriptor)
208 {
209 __asm lldt Descriptor;
210 }
211
212 VOID
213 FORCEINLINE
214 Ke386SaveFlags(IN ULONG Flags)
215 {
216 __asm pushf;
217 __asm pop Flags;
218 }
219
220 VOID
221 FORCEINLINE
222 Ke386RestoreFlags(IN ULONG Flags)
223 {
224 __asm push Flags;
225 __asm popf;
226 }
227
228 VOID
229 FORCEINLINE
230 Ke386SetTr(IN USHORT Tr)
231 {
232 __asm ltr Tr;
233 }
234
235 USHORT
236 FORCEINLINE
237 Ke386GetTr(IN USHORT Tr)
238 {
239 __asm str Tr;
240 }
241
242 //
243 // CR Macros
244 //
245 VOID
246 FORCEINLINE
247 Ke386SetCr2(IN ULONG Value)
248 {
249 __asm mov eax, Value;
250 __asm mov cr2, eax;
251 }
252
253 //
254 // DR Macros
255 //
256 ULONG
257 FORCEINLINE
258 Ke386GetDr0(VOID)
259 {
260 __asm mov eax, dr0;
261 }
262
263 ULONG
264 FORCEINLINE
265 Ke386GetDr1(VOID)
266 {
267 __asm mov eax, dr1;
268 }
269
270 ULONG
271 FORCEINLINE
272 Ke386GetDr2(VOID)
273 {
274 __asm mov eax, dr2;
275 }
276
277 ULONG
278 FORCEINLINE
279 Ke386GetDr3(VOID)
280 {
281 __asm mov eax, dr3;
282 }
283
284 ULONG
285 FORCEINLINE
286 Ke386GetDr6(VOID)
287 {
288 __asm mov eax, dr6;
289 }
290
291 ULONG
292 FORCEINLINE
293 Ke386GetDr7(VOID)
294 {
295 __asm mov eax, dr7;
296 }
297
298 VOID
299 FORCEINLINE
300 Ke386SetDr0(IN ULONG Value)
301 {
302 __asm mov eax, Value;
303 __asm mov dr0, eax;
304 }
305
306 VOID
307 FORCEINLINE
308 Ke386SetDr1(IN ULONG Value)
309 {
310 __asm mov eax, Value;
311 __asm mov dr1, eax;
312 }
313
314 VOID
315 FORCEINLINE
316 Ke386SetDr2(IN ULONG Value)
317 {
318 __asm mov eax, Value;
319 __asm mov dr2, eax;
320 }
321
322 VOID
323 FORCEINLINE
324 Ke386SetDr3(IN ULONG Value)
325 {
326 __asm mov eax, Value;
327 __asm mov dr3, eax;
328 }
329
330 VOID
331 FORCEINLINE
332 Ke386SetDr6(IN ULONG Value)
333 {
334 __asm mov eax, Value;
335 __asm mov dr6, eax;
336 }
337
338 VOID
339 FORCEINLINE
340 Ke386SetDr7(IN ULONG Value)
341 {
342 __asm mov eax, Value;
343 __asm mov dr7, eax;
344 }
345
346 //
347 // Segment Macros
348 //
349 USHORT
350 FORCEINLINE
351 Ke386GetSs(VOID)
352 {
353 __asm mov ax, ss;
354 }
355
356 USHORT
357 FORCEINLINE
358 Ke386GetFs(VOID)
359 {
360 __asm mov ax, fs;
361 }
362
363 USHORT
364 FORCEINLINE
365 Ke386GetDs(VOID)
366 {
367 __asm mov ax, ds;
368 }
369
370 USHORT
371 FORCEINLINE
372 Ke386GetEs(VOID)
373 {
374 __asm mov ax, es;
375 }
376
377 VOID
378 FORCEINLINE
379 Ke386SetSs(IN USHORT Value)
380 {
381 __asm mov ax, Value;
382 __asm mov ss, ax;
383 }
384
385 VOID
386 FORCEINLINE
387 Ke386SetFs(IN USHORT Value)
388 {
389 __asm mov ax, Value;
390 __asm mov fs, ax;
391 }
392
393 VOID
394 FORCEINLINE
395 Ke386SetDs(IN USHORT Value)
396 {
397 __asm mov ax, Value;
398 __asm mov ds, ax;
399 }
400
401 VOID
402 FORCEINLINE
403 Ke386SetEs(IN USHORT Value)
404 {
405 __asm mov ax, Value;
406 __asm mov es, ax;
407 }
408
409 #else
410 #error Unknown compiler for inline assembler
411 #endif
412
413 #endif
414
415 /* EOF */