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 FORCEINLINE 49 VOID 50 Ke386FnSave(IN PFLOATING_SAVE_AREA SaveArea) 51 { 52 asm volatile ("fnsave (%0); wait" : : "r"(SaveArea)); 53 } 54 55 FORCEINLINE 56 VOID 57 Ke386SaveFpuState(IN PFX_SAVE_AREA SaveArea) 58 { 59 extern ULONG KeI386FxsrPresent; 60 if (KeI386FxsrPresent) 61 { 62 __asm__ __volatile__ ("fxsave %0\n" : : "m"(*SaveArea)); 63 } 64 else 65 { 66 __asm__ __volatile__ ("fnsave %0\n wait\n" : : "m"(*SaveArea)); 67 } 68 } 69 70 FORCEINLINE 71 VOID 72 Ke386RestoreFpuState(_In_ PFX_SAVE_AREA SaveArea) 73 { 74 extern ULONG KeI386FxsrPresent; 75 if (KeI386FxsrPresent) 76 { 77 __asm__ __volatile__ ("fxrstor %0\n" : : "m"(*SaveArea)); 78 } 79 else 80 { 81 __asm__ __volatile__ ("frstor %0\n\t" : "=m" (*SaveArea)); 82 } 83 } 84 85 FORCEINLINE 86 VOID 87 Ke386ClearFpExceptions(VOID) 88 { 89 __asm__ __volatile__ ("fnclex"); 90 } 91 92 FORCEINLINE 93 VOID 94 __sldt(PVOID Descriptor) 95 { 96 __asm__ __volatile__( 97 "sldt %0" 98 : "=m" (*((short*)Descriptor)) 99 : /* no input */ 100 : "memory"); 101 } 102 103 #define Ke386SetLocalDescriptorTable(X) \ 104 __asm__("lldt %w0\n\t" \ 105 : /* no outputs */ \ 106 : "q" (X)); 107 108 #define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X)); 109 110 FORCEINLINE 111 USHORT 112 Ke386GetTr(VOID) 113 { 114 USHORT Tr; 115 __asm__("str %0\n\t" 116 : "=m" (Tr)); 117 return Tr; 118 } 119 120 #define _Ke386GetSeg(N) ({ \ 121 unsigned int __d; \ 122 __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \ 123 __d; \ 124 }) 125 126 #define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X)); 127 128 #define Ke386FnInit() __asm__("fninit\n\t"); 129 #define Ke386ClearDirectionFlag() __asm__ __volatile__ ("cld") 130 131 132 // 133 // CR Macros 134 // 135 #define Ke386SetCr2(X) __asm__ __volatile__("movl %0,%%cr2" : :"r" (X)); 136 137 // 138 // Segment Macros 139 // 140 #define Ke386GetSs() _Ke386GetSeg(ss) 141 #define Ke386GetFs() _Ke386GetSeg(fs) 142 #define Ke386GetDs() _Ke386GetSeg(ds) 143 #define Ke386GetEs() _Ke386GetSeg(es) 144 #define Ke386GetGs() _Ke386GetSeg(gs) 145 #define Ke386SetFs(X) _Ke386SetSeg(fs, X) 146 #define Ke386SetDs(X) _Ke386SetSeg(ds, X) 147 #define Ke386SetEs(X) _Ke386SetSeg(es, X) 148 #define Ke386SetSs(X) _Ke386SetSeg(ss, X) 149 #define Ke386SetGs(X) _Ke386SetSeg(gs, X) 150 151 #elif defined(_MSC_VER) 152 153 FORCEINLINE 154 VOID 155 Ke386FnInit(VOID) 156 { 157 __asm fninit; 158 } 159 160 FORCEINLINE 161 VOID 162 __sgdt(OUT PVOID Descriptor) 163 { 164 __asm 165 { 166 mov eax, Descriptor 167 sgdt [eax] 168 } 169 } 170 171 FORCEINLINE 172 VOID 173 __fxsave(OUT PFX_SAVE_AREA SaveArea) 174 { 175 __asm mov eax, SaveArea 176 __asm fxsave [eax] 177 } 178 179 FORCEINLINE 180 VOID 181 __fxrstor(IN PFX_SAVE_AREA SaveArea) 182 { 183 __asm mov eax, SaveArea 184 __asm fxrstor [eax] 185 } 186 187 FORCEINLINE 188 VOID 189 __frstor(_In_ PFX_SAVE_AREA SaveArea) 190 { 191 __asm mov eax, SaveArea 192 __asm frstor [eax] 193 } 194 195 FORCEINLINE 196 VOID 197 __fnsave(OUT PFLOATING_SAVE_AREA SaveArea) 198 { 199 __asm mov eax, SaveArea 200 __asm fnsave [eax] 201 __asm wait; 202 } 203 204 FORCEINLINE 205 VOID 206 __lgdt(IN PVOID Descriptor) 207 { 208 __asm 209 { 210 mov eax, Descriptor 211 lgdt [eax] 212 } 213 } 214 215 FORCEINLINE 216 VOID 217 __sldt(PVOID Descriptor) 218 { 219 __asm 220 { 221 sldt ax 222 mov ecx, Descriptor 223 mov [ecx], ax 224 } 225 } 226 227 FORCEINLINE 228 VOID 229 Ke386SetLocalDescriptorTable(IN USHORT Descriptor) 230 { 231 __asm lldt Descriptor; 232 } 233 234 FORCEINLINE 235 VOID 236 Ke386SetTr(IN USHORT Tr) 237 { 238 __asm ltr Tr; 239 } 240 241 FORCEINLINE 242 USHORT 243 Ke386GetTr(VOID) 244 { 245 __asm str ax; 246 } 247 248 // 249 // CR Macros 250 // 251 FORCEINLINE 252 VOID 253 Ke386SetCr2(IN ULONG Value) 254 { 255 __asm mov eax, Value; 256 __asm mov cr2, eax; 257 } 258 259 // 260 // Segment Macros 261 // 262 FORCEINLINE 263 USHORT 264 Ke386GetSs(VOID) 265 { 266 __asm mov ax, ss; 267 } 268 269 FORCEINLINE 270 USHORT 271 Ke386GetFs(VOID) 272 { 273 __asm mov ax, fs; 274 } 275 276 FORCEINLINE 277 USHORT 278 Ke386GetDs(VOID) 279 { 280 __asm mov ax, ds; 281 } 282 283 FORCEINLINE 284 USHORT 285 Ke386GetEs(VOID) 286 { 287 __asm mov ax, es; 288 } 289 290 FORCEINLINE 291 VOID 292 Ke386SetSs(IN USHORT Value) 293 { 294 __asm mov ax, Value; 295 __asm mov ss, ax; 296 } 297 298 FORCEINLINE 299 VOID 300 Ke386SetFs(IN USHORT Value) 301 { 302 __asm mov ax, Value; 303 __asm mov fs, ax; 304 } 305 306 FORCEINLINE 307 VOID 308 Ke386SetDs(IN USHORT Value) 309 { 310 __asm mov ax, Value; 311 __asm mov ds, ax; 312 } 313 314 FORCEINLINE 315 VOID 316 Ke386SetEs(IN USHORT Value) 317 { 318 __asm mov ax, Value; 319 __asm mov es, ax; 320 } 321 322 FORCEINLINE 323 VOID 324 Ke386SetGs(IN USHORT Value) 325 { 326 __asm mov ax, Value; 327 __asm mov gs, ax; 328 } 329 330 extern ULONG KeI386FxsrPresent; 331 332 FORCEINLINE 333 VOID 334 Ke386SaveFpuState(IN PVOID SaveArea) 335 { 336 if (KeI386FxsrPresent) 337 { 338 __fxsave((PFX_SAVE_AREA)SaveArea); 339 } 340 else 341 { 342 __fnsave((PFLOATING_SAVE_AREA)SaveArea); 343 } 344 } 345 346 FORCEINLINE 347 VOID 348 Ke386RestoreFpuState(_In_ PVOID SaveArea) 349 { 350 if (KeI386FxsrPresent) 351 { 352 __fxrstor((PFX_SAVE_AREA)SaveArea); 353 } 354 else 355 { 356 __frstor((PFX_SAVE_AREA)SaveArea); 357 } 358 } 359 360 FORCEINLINE 361 VOID 362 Ke386ClearFpExceptions(VOID) 363 { 364 __asm fnclex; 365 } 366 367 #define Ke386FnSave __fnsave 368 #define Ke386FxSave __fxsave 369 // The name suggest, that the original author didn't understand what frstor means 370 #define Ke386FxStore __fxrstor 371 372 #else 373 #error Unknown compiler for inline assembler 374 #endif 375 376 #define Ke386GetGlobalDescriptorTable __sgdt 377 #define Ke386SetGlobalDescriptorTable __lgdt 378 #define Ke386GetLocalDescriptorTable __sldt 379 380 #ifdef __cplusplus 381 } // extern "C" 382 #endif 383 384 /* EOF */ 385