1c2c66affSColin Finck #pragma once
2c2c66affSColin Finck 
331afbf10SJérôme Gardou #ifdef __cplusplus
431afbf10SJérôme Gardou extern "C"
531afbf10SJérôme Gardou {
631afbf10SJérôme Gardou #endif
731afbf10SJérôme Gardou 
8*516ccad3SJustin Miller FORCEINLINE
9*516ccad3SJustin Miller PKGDTENTRY
KiGetGdtEntry(_In_ PVOID pGdt,_In_ USHORT Selector)10*516ccad3SJustin Miller KiGetGdtEntry(
11*516ccad3SJustin Miller     _In_ PVOID pGdt,
12*516ccad3SJustin Miller     _In_ USHORT Selector)
13*516ccad3SJustin Miller {
14*516ccad3SJustin Miller     return (PKGDTENTRY)((ULONG_PTR)pGdt + (Selector & ~RPL_MASK));
15*516ccad3SJustin Miller }
16*516ccad3SJustin Miller 
17*516ccad3SJustin Miller FORCEINLINE
18*516ccad3SJustin Miller VOID
KiSetGdtDescriptorBase(_Inout_ PKGDTENTRY Entry,_In_ ULONG32 Base)19*516ccad3SJustin Miller KiSetGdtDescriptorBase(
20*516ccad3SJustin Miller     _Inout_ PKGDTENTRY Entry,
21*516ccad3SJustin Miller     _In_ ULONG32 Base)
22*516ccad3SJustin Miller {
23*516ccad3SJustin Miller     Entry->BaseLow = (USHORT)(Base & 0xffff);
24*516ccad3SJustin Miller     Entry->HighWord.Bytes.BaseMid = (UCHAR)((Base >> 16) & 0xff);
25*516ccad3SJustin Miller     Entry->HighWord.Bytes.BaseHi  = (UCHAR)((Base >> 24) & 0xff);
26*516ccad3SJustin Miller     // Entry->BaseUpper = (ULONG)(Base >> 32);
27*516ccad3SJustin Miller }
28*516ccad3SJustin Miller 
29*516ccad3SJustin Miller FORCEINLINE
30*516ccad3SJustin Miller VOID
KiSetGdtDescriptorLimit(_Inout_ PKGDTENTRY Entry,_In_ ULONG Limit)31*516ccad3SJustin Miller KiSetGdtDescriptorLimit(
32*516ccad3SJustin Miller     _Inout_ PKGDTENTRY Entry,
33*516ccad3SJustin Miller     _In_ ULONG Limit)
34*516ccad3SJustin Miller {
35*516ccad3SJustin Miller     if (Limit < 0x100000)
36*516ccad3SJustin Miller     {
37*516ccad3SJustin Miller         Entry->HighWord.Bits.Granularity = 0;
38*516ccad3SJustin Miller     }
39*516ccad3SJustin Miller     else
40*516ccad3SJustin Miller     {
41*516ccad3SJustin Miller         Limit >>= 12;
42*516ccad3SJustin Miller         Entry->HighWord.Bits.Granularity = 1;
43*516ccad3SJustin Miller     }
44*516ccad3SJustin Miller     Entry->LimitLow = (USHORT)(Limit & 0xffff);
45*516ccad3SJustin Miller     Entry->HighWord.Bits.LimitHi = ((Limit >> 16) & 0x0f);
46*516ccad3SJustin Miller }
47*516ccad3SJustin Miller 
48*516ccad3SJustin Miller FORCEINLINE
49*516ccad3SJustin Miller VOID
KiSetGdtEntryEx(_Inout_ PKGDTENTRY Entry,_In_ ULONG32 Base,_In_ ULONG Limit,_In_ UCHAR Type,_In_ UCHAR Dpl,_In_ BOOLEAN Granularity,_In_ UCHAR SegMode)50*516ccad3SJustin Miller KiSetGdtEntryEx(
51*516ccad3SJustin Miller     _Inout_ PKGDTENTRY Entry,
52*516ccad3SJustin Miller     _In_ ULONG32 Base,
53*516ccad3SJustin Miller     _In_ ULONG Limit,
54*516ccad3SJustin Miller     _In_ UCHAR Type,
55*516ccad3SJustin Miller     _In_ UCHAR Dpl,
56*516ccad3SJustin Miller     _In_ BOOLEAN Granularity,
57*516ccad3SJustin Miller     _In_ UCHAR SegMode) // 0: 16-bit, 1: 32-bit, 2: 64-bit
58*516ccad3SJustin Miller {
59*516ccad3SJustin Miller     KiSetGdtDescriptorBase(Entry, Base);
60*516ccad3SJustin Miller     KiSetGdtDescriptorLimit(Entry, Limit);
61*516ccad3SJustin Miller     Entry->HighWord.Bits.Type = (Type & 0x1f);
62*516ccad3SJustin Miller     Entry->HighWord.Bits.Dpl  = (Dpl & 0x3);
63*516ccad3SJustin Miller     Entry->HighWord.Bits.Pres = (Type != 0); // Present, must be 1 when the GDT entry is valid.
64*516ccad3SJustin Miller     Entry->HighWord.Bits.Sys  = 0;           // System
65*516ccad3SJustin Miller     Entry->HighWord.Bits.Reserved_0  = 0;    // LongMode = !!(SegMode & 1);
66*516ccad3SJustin Miller     Entry->HighWord.Bits.Default_Big = !!(SegMode & 2);
67*516ccad3SJustin Miller     Entry->HighWord.Bits.Granularity |= !!Granularity; // The flag may have been already set by KiSetGdtDescriptorLimit().
68*516ccad3SJustin Miller     // Entry->MustBeZero = 0;
69*516ccad3SJustin Miller }
70*516ccad3SJustin Miller 
71*516ccad3SJustin Miller FORCEINLINE
72*516ccad3SJustin Miller VOID
KiSetGdtEntry(_Inout_ PKGDTENTRY Entry,_In_ ULONG32 Base,_In_ ULONG Limit,_In_ UCHAR Type,_In_ UCHAR Dpl,_In_ UCHAR SegMode)73*516ccad3SJustin Miller KiSetGdtEntry(
74*516ccad3SJustin Miller     _Inout_ PKGDTENTRY Entry,
75*516ccad3SJustin Miller     _In_ ULONG32 Base,
76*516ccad3SJustin Miller     _In_ ULONG Limit,
77*516ccad3SJustin Miller     _In_ UCHAR Type,
78*516ccad3SJustin Miller     _In_ UCHAR Dpl,
79*516ccad3SJustin Miller     _In_ UCHAR SegMode) // 0: 16-bit, 1: 32-bit, 2: 64-bit
80*516ccad3SJustin Miller {
81*516ccad3SJustin Miller     KiSetGdtEntryEx(Entry, Base, Limit, Type, Dpl, FALSE, SegMode);
82*516ccad3SJustin Miller }
83*516ccad3SJustin Miller 
84c2c66affSColin Finck #if defined(__GNUC__)
85c2c66affSColin Finck 
863726b992SJérôme Gardou FORCEINLINE
873726b992SJérôme Gardou VOID
__lgdt(_Out_ PVOID Descriptor)883726b992SJérôme Gardou __lgdt(_Out_ PVOID Descriptor)
893726b992SJérôme Gardou {
9031afbf10SJérôme Gardou     PVOID* desc = (PVOID*)Descriptor;
913726b992SJérôme Gardou     __asm__ __volatile__(
923726b992SJérôme Gardou         "lgdt %0"
933726b992SJérôme Gardou             : "=m" (*desc)
943726b992SJérôme Gardou             : /* no input */
95c2c66affSColin Finck             : "memory");
963726b992SJérôme Gardou }
973726b992SJérôme Gardou 
983726b992SJérôme Gardou FORCEINLINE
993726b992SJérôme Gardou VOID
__sgdt(_Out_ PVOID Descriptor)1003726b992SJérôme Gardou __sgdt(_Out_ PVOID Descriptor)
1013726b992SJérôme Gardou {
10231afbf10SJérôme Gardou     PVOID* desc = (PVOID*)Descriptor;
1033726b992SJérôme Gardou     __asm__ __volatile__(
1043726b992SJérôme Gardou         "sgdt %0"
1053726b992SJérôme Gardou             : "=m" (*desc)
1063726b992SJérôme Gardou             : /* no input */
1073726b992SJérôme Gardou             : "memory");
1083726b992SJérôme Gardou }
109c2c66affSColin Finck 
110c2c66affSColin Finck FORCEINLINE
111c2c66affSColin Finck VOID
Ke386FxStore(IN PFX_SAVE_AREA SaveArea)112c2c66affSColin Finck Ke386FxStore(IN PFX_SAVE_AREA SaveArea)
113c2c66affSColin Finck {
114c2c66affSColin Finck     asm volatile ("fxrstor (%0)" : : "r"(SaveArea));
115c2c66affSColin Finck }
116c2c66affSColin Finck 
117c2c66affSColin Finck FORCEINLINE
118c2c66affSColin Finck VOID
Ke386FxSave(IN PFX_SAVE_AREA SaveArea)119c2c66affSColin Finck Ke386FxSave(IN PFX_SAVE_AREA SaveArea)
120c2c66affSColin Finck {
121c2c66affSColin Finck     asm volatile ("fxsave (%0)" : : "r"(SaveArea));
122c2c66affSColin Finck }
123c2c66affSColin Finck 
124c2c66affSColin Finck FORCEINLINE
125c2c66affSColin Finck VOID
Ke386FnSave(IN PFLOATING_SAVE_AREA SaveArea)126c2c66affSColin Finck Ke386FnSave(IN PFLOATING_SAVE_AREA SaveArea)
127c2c66affSColin Finck {
128c2c66affSColin Finck     asm volatile ("fnsave (%0); wait" : : "r"(SaveArea));
129c2c66affSColin Finck }
130c2c66affSColin Finck 
131c2c66affSColin Finck FORCEINLINE
132c2c66affSColin Finck VOID
Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)133c2c66affSColin Finck Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
134c2c66affSColin Finck {
135c2c66affSColin Finck     extern ULONG KeI386FxsrPresent;
136c2c66affSColin Finck     if (KeI386FxsrPresent)
137c2c66affSColin Finck     {
138c2c66affSColin Finck         __asm__ __volatile__ ("fxsave %0\n" : : "m"(*SaveArea));
139c2c66affSColin Finck     }
140c2c66affSColin Finck     else
141c2c66affSColin Finck     {
142c2c66affSColin Finck         __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(*SaveArea));
143c2c66affSColin Finck     }
144c2c66affSColin Finck }
145c2c66affSColin Finck 
146c2c66affSColin Finck FORCEINLINE
1473726b992SJérôme Gardou VOID
Ke386RestoreFpuState(_In_ PFX_SAVE_AREA SaveArea)148d88cd0eeSGeorge Bișoc Ke386RestoreFpuState(_In_ PFX_SAVE_AREA SaveArea)
149d88cd0eeSGeorge Bișoc {
150d88cd0eeSGeorge Bișoc     extern ULONG KeI386FxsrPresent;
151d88cd0eeSGeorge Bișoc     if (KeI386FxsrPresent)
152d88cd0eeSGeorge Bișoc     {
153d88cd0eeSGeorge Bișoc         __asm__ __volatile__ ("fxrstor %0\n" : : "m"(*SaveArea));
154d88cd0eeSGeorge Bișoc     }
155d88cd0eeSGeorge Bișoc     else
156d88cd0eeSGeorge Bișoc     {
157d88cd0eeSGeorge Bișoc         __asm__ __volatile__ ("frstor %0\n\t" : "=m" (*SaveArea));
158d88cd0eeSGeorge Bișoc     }
159d88cd0eeSGeorge Bișoc }
160d88cd0eeSGeorge Bișoc 
161d88cd0eeSGeorge Bișoc FORCEINLINE
162d88cd0eeSGeorge Bișoc VOID
Ke386ClearFpExceptions(VOID)163d88cd0eeSGeorge Bișoc Ke386ClearFpExceptions(VOID)
164d88cd0eeSGeorge Bișoc {
165d88cd0eeSGeorge Bișoc     __asm__ __volatile__ ("fnclex");
166d88cd0eeSGeorge Bișoc }
167d88cd0eeSGeorge Bișoc 
168d88cd0eeSGeorge Bișoc FORCEINLINE
169d88cd0eeSGeorge Bișoc VOID
__sldt(PVOID Descriptor)1703726b992SJérôme Gardou __sldt(PVOID Descriptor)
171c2c66affSColin Finck {
1723726b992SJérôme Gardou     __asm__ __volatile__(
1733726b992SJérôme Gardou         "sldt %0"
1743726b992SJérôme Gardou             : "=m" (*((short*)Descriptor))
175c2c66affSColin Finck             : /* no input */
176c2c66affSColin Finck             : "memory");
177c2c66affSColin Finck }
178c2c66affSColin Finck 
179c2c66affSColin Finck #define Ke386SetLocalDescriptorTable(X) \
180c2c66affSColin Finck     __asm__("lldt %w0\n\t" \
181c2c66affSColin Finck     : /* no outputs */ \
182c2c66affSColin Finck     : "q" (X));
183c2c66affSColin Finck 
184c2c66affSColin Finck #define Ke386SetTr(X)                   __asm__ __volatile__("ltr %%ax" : :"a" (X));
185c2c66affSColin Finck 
186c2c66affSColin Finck FORCEINLINE
187c2c66affSColin Finck USHORT
Ke386GetTr(VOID)188c2c66affSColin Finck Ke386GetTr(VOID)
189c2c66affSColin Finck {
190c2c66affSColin Finck     USHORT Tr;
191c2c66affSColin Finck     __asm__("str %0\n\t"
192c2c66affSColin Finck     : "=m" (Tr));
193c2c66affSColin Finck     return Tr;
194c2c66affSColin Finck }
195c2c66affSColin Finck 
196c2c66affSColin Finck #define _Ke386GetSeg(N)           ({ \
197c2c66affSColin Finck                                      unsigned int __d; \
198c2c66affSColin Finck                                      __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \
199c2c66affSColin Finck                                      __d; \
200c2c66affSColin Finck                                   })
201c2c66affSColin Finck 
202c2c66affSColin Finck #define _Ke386SetSeg(N,X)         __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
203c2c66affSColin Finck 
204c2c66affSColin Finck #define Ke386FnInit()               __asm__("fninit\n\t");
205c2c66affSColin Finck #define Ke386ClearDirectionFlag()   __asm__ __volatile__ ("cld")
206c2c66affSColin Finck 
207c2c66affSColin Finck 
208c2c66affSColin Finck //
209c2c66affSColin Finck // CR Macros
210c2c66affSColin Finck //
211c2c66affSColin Finck #define Ke386SetCr2(X)              __asm__ __volatile__("movl %0,%%cr2" : :"r" (X));
212c2c66affSColin Finck 
213c2c66affSColin Finck //
214c2c66affSColin Finck // Segment Macros
215c2c66affSColin Finck //
216c2c66affSColin Finck #define Ke386GetSs()                _Ke386GetSeg(ss)
217c2c66affSColin Finck #define Ke386GetFs()                _Ke386GetSeg(fs)
218c2c66affSColin Finck #define Ke386GetDs()                _Ke386GetSeg(ds)
219c2c66affSColin Finck #define Ke386GetEs()                _Ke386GetSeg(es)
220c2c66affSColin Finck #define Ke386GetGs()                _Ke386GetSeg(gs)
221c2c66affSColin Finck #define Ke386SetFs(X)               _Ke386SetSeg(fs, X)
222c2c66affSColin Finck #define Ke386SetDs(X)               _Ke386SetSeg(ds, X)
223c2c66affSColin Finck #define Ke386SetEs(X)               _Ke386SetSeg(es, X)
224c2c66affSColin Finck #define Ke386SetSs(X)               _Ke386SetSeg(ss, X)
225c2c66affSColin Finck #define Ke386SetGs(X)               _Ke386SetSeg(gs, X)
226c2c66affSColin Finck 
227c2c66affSColin Finck #elif defined(_MSC_VER)
228c2c66affSColin Finck 
229c2c66affSColin Finck FORCEINLINE
230c2c66affSColin Finck VOID
Ke386FnInit(VOID)231c2c66affSColin Finck Ke386FnInit(VOID)
232c2c66affSColin Finck {
233c2c66affSColin Finck     __asm fninit;
234c2c66affSColin Finck }
235c2c66affSColin Finck 
236c2c66affSColin Finck FORCEINLINE
237c2c66affSColin Finck VOID
__sgdt(OUT PVOID Descriptor)238c2c66affSColin Finck __sgdt(OUT PVOID Descriptor)
239c2c66affSColin Finck {
240c2c66affSColin Finck     __asm
241c2c66affSColin Finck     {
242c2c66affSColin Finck         mov eax, Descriptor
243c2c66affSColin Finck         sgdt [eax]
244c2c66affSColin Finck     }
245c2c66affSColin Finck }
246c2c66affSColin Finck 
247c2c66affSColin Finck FORCEINLINE
248c2c66affSColin Finck VOID
__fxsave(OUT PFX_SAVE_AREA SaveArea)249c2c66affSColin Finck __fxsave(OUT PFX_SAVE_AREA SaveArea)
250c2c66affSColin Finck {
251c2c66affSColin Finck     __asm mov eax, SaveArea
252c2c66affSColin Finck     __asm fxsave [eax]
253c2c66affSColin Finck }
254c2c66affSColin Finck 
255c2c66affSColin Finck FORCEINLINE
256c2c66affSColin Finck VOID
__fxrstor(IN PFX_SAVE_AREA SaveArea)257c2c66affSColin Finck __fxrstor(IN PFX_SAVE_AREA SaveArea)
258c2c66affSColin Finck {
259c2c66affSColin Finck     __asm mov eax, SaveArea
260c2c66affSColin Finck     __asm fxrstor [eax]
261c2c66affSColin Finck }
262c2c66affSColin Finck 
263c2c66affSColin Finck FORCEINLINE
264c2c66affSColin Finck VOID
__frstor(_In_ PFX_SAVE_AREA SaveArea)265d88cd0eeSGeorge Bișoc __frstor(_In_ PFX_SAVE_AREA SaveArea)
266d88cd0eeSGeorge Bișoc {
267d88cd0eeSGeorge Bișoc     __asm mov eax, SaveArea
268d88cd0eeSGeorge Bișoc     __asm frstor [eax]
269d88cd0eeSGeorge Bișoc }
270d88cd0eeSGeorge Bișoc 
271d88cd0eeSGeorge Bișoc FORCEINLINE
272d88cd0eeSGeorge Bișoc VOID
__fnsave(OUT PFLOATING_SAVE_AREA SaveArea)273c2c66affSColin Finck __fnsave(OUT PFLOATING_SAVE_AREA SaveArea)
274c2c66affSColin Finck {
275c2c66affSColin Finck     __asm mov eax, SaveArea
276c2c66affSColin Finck     __asm fnsave [eax]
277c2c66affSColin Finck     __asm wait;
278c2c66affSColin Finck }
279c2c66affSColin Finck 
280c2c66affSColin Finck FORCEINLINE
281c2c66affSColin Finck VOID
__lgdt(IN PVOID Descriptor)282c2c66affSColin Finck __lgdt(IN PVOID Descriptor)
283c2c66affSColin Finck {
284c2c66affSColin Finck     __asm
285c2c66affSColin Finck     {
286c2c66affSColin Finck         mov eax, Descriptor
287c2c66affSColin Finck         lgdt [eax]
288c2c66affSColin Finck     }
289c2c66affSColin Finck }
290c2c66affSColin Finck 
291c2c66affSColin Finck FORCEINLINE
2923726b992SJérôme Gardou VOID
__sldt(PVOID Descriptor)2933726b992SJérôme Gardou __sldt(PVOID Descriptor)
294c2c66affSColin Finck {
2953726b992SJérôme Gardou     __asm
2963726b992SJérôme Gardou     {
2973726b992SJérôme Gardou         sldt ax
2983726b992SJérôme Gardou         mov ecx, Descriptor
2993726b992SJérôme Gardou         mov [ecx], ax
3003726b992SJérôme Gardou     }
301c2c66affSColin Finck }
302c2c66affSColin Finck 
303c2c66affSColin Finck FORCEINLINE
304c2c66affSColin Finck VOID
Ke386SetLocalDescriptorTable(IN USHORT Descriptor)305c2c66affSColin Finck Ke386SetLocalDescriptorTable(IN USHORT Descriptor)
306c2c66affSColin Finck {
307c2c66affSColin Finck     __asm lldt Descriptor;
308c2c66affSColin Finck }
309c2c66affSColin Finck 
310c2c66affSColin Finck FORCEINLINE
311c2c66affSColin Finck VOID
Ke386SetTr(IN USHORT Tr)312c2c66affSColin Finck Ke386SetTr(IN USHORT Tr)
313c2c66affSColin Finck {
314c2c66affSColin Finck     __asm ltr Tr;
315c2c66affSColin Finck }
316c2c66affSColin Finck 
317c2c66affSColin Finck FORCEINLINE
318c2c66affSColin Finck USHORT
Ke386GetTr(VOID)319c2c66affSColin Finck Ke386GetTr(VOID)
320c2c66affSColin Finck {
321c2c66affSColin Finck     __asm str ax;
322c2c66affSColin Finck }
323c2c66affSColin Finck 
324c2c66affSColin Finck //
325c2c66affSColin Finck // CR Macros
326c2c66affSColin Finck //
327c2c66affSColin Finck FORCEINLINE
328c2c66affSColin Finck VOID
Ke386SetCr2(IN ULONG Value)329c2c66affSColin Finck Ke386SetCr2(IN ULONG Value)
330c2c66affSColin Finck {
331c2c66affSColin Finck     __asm mov eax, Value;
332c2c66affSColin Finck     __asm mov cr2, eax;
333c2c66affSColin Finck }
334c2c66affSColin Finck 
335c2c66affSColin Finck //
336c2c66affSColin Finck // Segment Macros
337c2c66affSColin Finck //
338c2c66affSColin Finck FORCEINLINE
339c2c66affSColin Finck USHORT
Ke386GetSs(VOID)340c2c66affSColin Finck Ke386GetSs(VOID)
341c2c66affSColin Finck {
342c2c66affSColin Finck     __asm mov ax, ss;
343c2c66affSColin Finck }
344c2c66affSColin Finck 
345c2c66affSColin Finck FORCEINLINE
346c2c66affSColin Finck USHORT
Ke386GetFs(VOID)347c2c66affSColin Finck Ke386GetFs(VOID)
348c2c66affSColin Finck {
349c2c66affSColin Finck     __asm mov ax, fs;
350c2c66affSColin Finck }
351c2c66affSColin Finck 
352c2c66affSColin Finck FORCEINLINE
353c2c66affSColin Finck USHORT
Ke386GetDs(VOID)354c2c66affSColin Finck Ke386GetDs(VOID)
355c2c66affSColin Finck {
356c2c66affSColin Finck     __asm mov ax, ds;
357c2c66affSColin Finck }
358c2c66affSColin Finck 
359c2c66affSColin Finck FORCEINLINE
360c2c66affSColin Finck USHORT
Ke386GetEs(VOID)361c2c66affSColin Finck Ke386GetEs(VOID)
362c2c66affSColin Finck {
363c2c66affSColin Finck     __asm mov ax, es;
364c2c66affSColin Finck }
365c2c66affSColin Finck 
366c2c66affSColin Finck FORCEINLINE
367c2c66affSColin Finck VOID
Ke386SetSs(IN USHORT Value)368c2c66affSColin Finck Ke386SetSs(IN USHORT Value)
369c2c66affSColin Finck {
370c2c66affSColin Finck     __asm mov ax, Value;
371c2c66affSColin Finck     __asm mov ss, ax;
372c2c66affSColin Finck }
373c2c66affSColin Finck 
374c2c66affSColin Finck FORCEINLINE
375c2c66affSColin Finck VOID
Ke386SetFs(IN USHORT Value)376c2c66affSColin Finck Ke386SetFs(IN USHORT Value)
377c2c66affSColin Finck {
378c2c66affSColin Finck     __asm mov ax, Value;
379c2c66affSColin Finck     __asm mov fs, ax;
380c2c66affSColin Finck }
381c2c66affSColin Finck 
382c2c66affSColin Finck FORCEINLINE
383c2c66affSColin Finck VOID
Ke386SetDs(IN USHORT Value)384c2c66affSColin Finck Ke386SetDs(IN USHORT Value)
385c2c66affSColin Finck {
386c2c66affSColin Finck     __asm mov ax, Value;
387c2c66affSColin Finck     __asm mov ds, ax;
388c2c66affSColin Finck }
389c2c66affSColin Finck 
390c2c66affSColin Finck FORCEINLINE
391c2c66affSColin Finck VOID
Ke386SetEs(IN USHORT Value)392c2c66affSColin Finck Ke386SetEs(IN USHORT Value)
393c2c66affSColin Finck {
394c2c66affSColin Finck     __asm mov ax, Value;
395c2c66affSColin Finck     __asm mov es, ax;
396c2c66affSColin Finck }
397c2c66affSColin Finck 
398c2c66affSColin Finck FORCEINLINE
399c2c66affSColin Finck VOID
Ke386SetGs(IN USHORT Value)400c2c66affSColin Finck Ke386SetGs(IN USHORT Value)
401c2c66affSColin Finck {
402c2c66affSColin Finck     __asm mov ax, Value;
403c2c66affSColin Finck     __asm mov gs, ax;
404c2c66affSColin Finck }
405c2c66affSColin Finck 
406c2c66affSColin Finck extern ULONG KeI386FxsrPresent;
407c2c66affSColin Finck 
408c2c66affSColin Finck FORCEINLINE
409c2c66affSColin Finck VOID
Ke386SaveFpuState(IN PVOID SaveArea)410c2c66affSColin Finck Ke386SaveFpuState(IN PVOID SaveArea)
411c2c66affSColin Finck {
412c2c66affSColin Finck     if (KeI386FxsrPresent)
413c2c66affSColin Finck     {
41431afbf10SJérôme Gardou         __fxsave((PFX_SAVE_AREA)SaveArea);
415c2c66affSColin Finck     }
416c2c66affSColin Finck     else
417c2c66affSColin Finck     {
41831afbf10SJérôme Gardou         __fnsave((PFLOATING_SAVE_AREA)SaveArea);
419c2c66affSColin Finck     }
420c2c66affSColin Finck }
421c2c66affSColin Finck 
422d88cd0eeSGeorge Bișoc FORCEINLINE
423d88cd0eeSGeorge Bișoc VOID
Ke386RestoreFpuState(_In_ PVOID SaveArea)424d88cd0eeSGeorge Bișoc Ke386RestoreFpuState(_In_ PVOID SaveArea)
425d88cd0eeSGeorge Bișoc {
426d88cd0eeSGeorge Bișoc     if (KeI386FxsrPresent)
427d88cd0eeSGeorge Bișoc     {
428d88cd0eeSGeorge Bișoc         __fxrstor((PFX_SAVE_AREA)SaveArea);
429d88cd0eeSGeorge Bișoc     }
430d88cd0eeSGeorge Bișoc     else
431d88cd0eeSGeorge Bișoc     {
432d88cd0eeSGeorge Bișoc         __frstor((PFX_SAVE_AREA)SaveArea);
433d88cd0eeSGeorge Bișoc     }
434d88cd0eeSGeorge Bișoc }
435d88cd0eeSGeorge Bișoc 
436d88cd0eeSGeorge Bișoc FORCEINLINE
437d88cd0eeSGeorge Bișoc VOID
Ke386ClearFpExceptions(VOID)438d88cd0eeSGeorge Bișoc Ke386ClearFpExceptions(VOID)
439d88cd0eeSGeorge Bișoc {
440d88cd0eeSGeorge Bișoc     __asm fnclex;
441d88cd0eeSGeorge Bișoc }
442d88cd0eeSGeorge Bișoc 
443c2c66affSColin Finck #define Ke386FnSave __fnsave
444c2c66affSColin Finck #define Ke386FxSave __fxsave
445c2c66affSColin Finck // The name suggest, that the original author didn't understand what frstor means
446c2c66affSColin Finck #define Ke386FxStore __fxrstor
447c2c66affSColin Finck 
448c2c66affSColin Finck #else
449c2c66affSColin Finck #error Unknown compiler for inline assembler
450c2c66affSColin Finck #endif
451c2c66affSColin Finck 
4523726b992SJérôme Gardou #define Ke386GetGlobalDescriptorTable __sgdt
4533726b992SJérôme Gardou #define Ke386SetGlobalDescriptorTable __lgdt
4543726b992SJérôme Gardou #define Ke386GetLocalDescriptorTable __sldt
4553726b992SJérôme Gardou 
45631afbf10SJérôme Gardou #ifdef __cplusplus
45731afbf10SJérôme Gardou } // extern "C"
45831afbf10SJérôme Gardou #endif
45931afbf10SJérôme Gardou 
460c2c66affSColin Finck /* EOF */
461