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