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