1 #pragma once
2 
3 #ifdef __cplusplus
4 extern "C"
5 {
6 #endif
7 
8 #if defined(__GNUC__)
9 
10 FORCEINLINE
11 VOID
12 __lgdt(_Out_ PVOID Descriptor)
13 {
14     PVOID* desc = (PVOID*)Descriptor;
15     __asm__ __volatile__(
16         "lgdt %0"
17             : "=m" (*desc)
18             : /* no input */
19             : "memory");
20 }
21 
22 FORCEINLINE
23 VOID
24 __sgdt(_Out_ PVOID Descriptor)
25 {
26     PVOID* desc = (PVOID*)Descriptor;
27     __asm__ __volatile__(
28         "sgdt %0"
29             : "=m" (*desc)
30             : /* no input */
31             : "memory");
32 }
33 
34 FORCEINLINE
35 VOID
36 Ke386FxStore(IN PFX_SAVE_AREA SaveArea)
37 {
38     asm volatile ("fxrstor (%0)" : : "r"(SaveArea));
39 }
40 
41 FORCEINLINE
42 VOID
43 Ke386FxSave(IN PFX_SAVE_AREA SaveArea)
44 {
45     asm volatile ("fxsave (%0)" : : "r"(SaveArea));
46 }
47 
48 
49 FORCEINLINE
50 VOID
51 Ke386FnSave(IN PFLOATING_SAVE_AREA SaveArea)
52 {
53     asm volatile ("fnsave (%0); wait" : : "r"(SaveArea));
54 }
55 
56 FORCEINLINE
57 VOID
58 Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea)
59 {
60     extern ULONG KeI386FxsrPresent;
61     if (KeI386FxsrPresent)
62     {
63         __asm__ __volatile__ ("fxsave %0\n" : : "m"(*SaveArea));
64     }
65     else
66     {
67         __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(*SaveArea));
68     }
69 }
70 
71 FORCEINLINE
72 VOID
73 __sldt(PVOID Descriptor)
74 {
75     __asm__ __volatile__(
76         "sldt %0"
77             : "=m" (*((short*)Descriptor))
78             : /* no input */
79             : "memory");
80 }
81 
82 #define Ke386SetLocalDescriptorTable(X) \
83     __asm__("lldt %w0\n\t" \
84     : /* no outputs */ \
85     : "q" (X));
86 
87 #define Ke386SetTr(X)                   __asm__ __volatile__("ltr %%ax" : :"a" (X));
88 
89 FORCEINLINE
90 USHORT
91 Ke386GetTr(VOID)
92 {
93     USHORT Tr;
94     __asm__("str %0\n\t"
95     : "=m" (Tr));
96     return Tr;
97 }
98 
99 #define _Ke386GetSeg(N)           ({ \
100                                      unsigned int __d; \
101                                      __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \
102                                      __d; \
103                                   })
104 
105 #define _Ke386SetSeg(N,X)         __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
106 
107 #define Ke386FnInit()               __asm__("fninit\n\t");
108 #define Ke386ClearDirectionFlag()   __asm__ __volatile__ ("cld")
109 
110 
111 //
112 // CR Macros
113 //
114 #define Ke386SetCr2(X)              __asm__ __volatile__("movl %0,%%cr2" : :"r" (X));
115 
116 //
117 // Segment Macros
118 //
119 #define Ke386GetSs()                _Ke386GetSeg(ss)
120 #define Ke386GetFs()                _Ke386GetSeg(fs)
121 #define Ke386GetDs()                _Ke386GetSeg(ds)
122 #define Ke386GetEs()                _Ke386GetSeg(es)
123 #define Ke386GetGs()                _Ke386GetSeg(gs)
124 #define Ke386SetFs(X)               _Ke386SetSeg(fs, X)
125 #define Ke386SetDs(X)               _Ke386SetSeg(ds, X)
126 #define Ke386SetEs(X)               _Ke386SetSeg(es, X)
127 #define Ke386SetSs(X)               _Ke386SetSeg(ss, X)
128 #define Ke386SetGs(X)               _Ke386SetSeg(gs, X)
129 
130 #elif defined(_MSC_VER)
131 
132 FORCEINLINE
133 VOID
134 Ke386FnInit(VOID)
135 {
136     __asm fninit;
137 }
138 
139 FORCEINLINE
140 VOID
141 __sgdt(OUT PVOID Descriptor)
142 {
143     __asm
144     {
145         mov eax, Descriptor
146         sgdt [eax]
147     }
148 }
149 
150 FORCEINLINE
151 VOID
152 __fxsave(OUT PFX_SAVE_AREA SaveArea)
153 {
154     __asm mov eax, SaveArea
155     __asm fxsave [eax]
156 }
157 
158 FORCEINLINE
159 VOID
160 __fxrstor(IN PFX_SAVE_AREA SaveArea)
161 {
162     __asm mov eax, SaveArea
163     __asm fxrstor [eax]
164 }
165 
166 FORCEINLINE
167 VOID
168 __fnsave(OUT PFLOATING_SAVE_AREA SaveArea)
169 {
170     __asm mov eax, SaveArea
171     __asm fnsave [eax]
172     __asm wait;
173 }
174 
175 FORCEINLINE
176 VOID
177 __lgdt(IN PVOID Descriptor)
178 {
179     __asm
180     {
181         mov eax, Descriptor
182         lgdt [eax]
183     }
184 }
185 
186 FORCEINLINE
187 VOID
188 __sldt(PVOID Descriptor)
189 {
190     __asm
191     {
192         sldt ax
193         mov ecx, Descriptor
194         mov [ecx], ax
195     }
196 }
197 
198 FORCEINLINE
199 VOID
200 Ke386SetLocalDescriptorTable(IN USHORT Descriptor)
201 {
202     __asm lldt Descriptor;
203 }
204 
205 FORCEINLINE
206 VOID
207 Ke386SetTr(IN USHORT Tr)
208 {
209     __asm ltr Tr;
210 }
211 
212 FORCEINLINE
213 USHORT
214 Ke386GetTr(VOID)
215 {
216     __asm str ax;
217 }
218 
219 //
220 // CR Macros
221 //
222 FORCEINLINE
223 VOID
224 Ke386SetCr2(IN ULONG Value)
225 {
226     __asm mov eax, Value;
227     __asm mov cr2, eax;
228 }
229 
230 //
231 // Segment Macros
232 //
233 FORCEINLINE
234 USHORT
235 Ke386GetSs(VOID)
236 {
237     __asm mov ax, ss;
238 }
239 
240 FORCEINLINE
241 USHORT
242 Ke386GetFs(VOID)
243 {
244     __asm mov ax, fs;
245 }
246 
247 FORCEINLINE
248 USHORT
249 Ke386GetDs(VOID)
250 {
251     __asm mov ax, ds;
252 }
253 
254 FORCEINLINE
255 USHORT
256 Ke386GetEs(VOID)
257 {
258     __asm mov ax, es;
259 }
260 
261 FORCEINLINE
262 VOID
263 Ke386SetSs(IN USHORT Value)
264 {
265     __asm mov ax, Value;
266     __asm mov ss, ax;
267 }
268 
269 FORCEINLINE
270 VOID
271 Ke386SetFs(IN USHORT Value)
272 {
273     __asm mov ax, Value;
274     __asm mov fs, ax;
275 }
276 
277 FORCEINLINE
278 VOID
279 Ke386SetDs(IN USHORT Value)
280 {
281     __asm mov ax, Value;
282     __asm mov ds, ax;
283 }
284 
285 FORCEINLINE
286 VOID
287 Ke386SetEs(IN USHORT Value)
288 {
289     __asm mov ax, Value;
290     __asm mov es, ax;
291 }
292 
293 FORCEINLINE
294 VOID
295 Ke386SetGs(IN USHORT Value)
296 {
297     __asm mov ax, Value;
298     __asm mov gs, ax;
299 }
300 
301 extern ULONG KeI386FxsrPresent;
302 
303 FORCEINLINE
304 VOID
305 Ke386SaveFpuState(IN PVOID SaveArea)
306 {
307     if (KeI386FxsrPresent)
308     {
309         __fxsave((PFX_SAVE_AREA)SaveArea);
310     }
311     else
312     {
313         __fnsave((PFLOATING_SAVE_AREA)SaveArea);
314     }
315 }
316 
317 #define Ke386FnSave __fnsave
318 #define Ke386FxSave __fxsave
319 // The name suggest, that the original author didn't understand what frstor means
320 #define Ke386FxStore __fxrstor
321 
322 
323 #else
324 #error Unknown compiler for inline assembler
325 #endif
326 
327 
328 #define Ke386GetGlobalDescriptorTable __sgdt
329 #define Ke386SetGlobalDescriptorTable __lgdt
330 #define Ke386GetLocalDescriptorTable __sldt
331 
332 #ifdef __cplusplus
333 } // extern "C"
334 #endif
335 
336 
337 /* EOF */
338