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