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