1 #ifndef _INTRIN_INTERNAL_
2 #define _INTRIN_INTERNAL_
10 #define KeSetCurrentIrql(x) __writecr8(x)
14 KiGetGdtEntry(PVOID pGdt
, USHORT Selector
)
16 return (PKGDTENTRY64
)((ULONG64
)pGdt
+ (Selector
& ~RPL_MASK
));
21 KiGetGdtDescriptorBase(PKGDTENTRY Entry
)
23 return (PVOID
)((ULONG64
)Entry
->BaseLow
|
24 (ULONG64
)Entry
->Bytes
.BaseMiddle
<< 16 |
25 (ULONG64
)Entry
->Bytes
.BaseHigh
<< 24 |
26 (ULONG64
)Entry
->BaseUpper
<< 32);
31 KiSetGdtDescriptorBase(PKGDTENTRY Entry
, ULONG64 Base
)
33 Entry
->BaseLow
= Base
& 0xffff;
34 Entry
->Bits
.BaseMiddle
= (Base
>> 16) & 0xff;
35 Entry
->Bits
.BaseHigh
= (Base
>> 24) & 0xff;
36 Entry
->BaseUpper
= Base
>> 32;
41 KiSetGdtDescriptorLimit(PKGDTENTRY Entry
, ULONG Limit
)
43 Entry
->LimitLow
= Limit
& 0xffff;
44 Entry
->Bits
.LimitHigh
= Limit
>> 16;
49 KiInitGdtEntry(PKGDTENTRY64 Entry
, ULONG64 Base
, ULONG Size
, UCHAR Type
, UCHAR Dpl
)
51 KiSetGdtDescriptorBase(Entry
, Base
);
52 KiSetGdtDescriptorLimit(Entry
, Size
- 1);
53 Entry
->Bits
.Type
= Type
;
54 Entry
->Bits
.Dpl
= Dpl
;
55 Entry
->Bits
.Present
= 1;
56 Entry
->Bits
.System
= 0;
57 Entry
->Bits
.LongMode
= 0;
58 Entry
->Bits
.DefaultBig
= 0;
59 Entry
->Bits
.Granularity
= 0;
60 Entry
->MustBeZero
= 0;
65 static __inline__
__attribute__((always_inline
)) void __lgdt(void *Source
)
67 __asm__
__volatile__("lgdt %0" : : "m"(*(short*)Source
));
70 static __inline__
__attribute__((always_inline
)) void __sgdt(void *Destination
)
72 __asm__
__volatile__("sgdt %0" : : "m"(*(short*)Destination
) : "memory");
75 static __inline__
__attribute__((always_inline
)) void __lldt(void *Source
)
77 __asm__
__volatile__("lldt %0" : : "m"(*(short*)Source
));
80 static __inline__
__attribute__((always_inline
)) void __sldt(void *Destination
)
82 __asm__
__volatile__("sldt %0" : : "m"(*(short*)Destination
) : "memory");
85 static __inline__
__attribute__((always_inline
)) void __ldmxcsr(unsigned long *Source
)
87 __asm__
__volatile__("ldmxcsr %0" : : "m"(*Source
));
90 static __inline__
__attribute__((always_inline
)) void __stmxcsr(unsigned long *Destination
)
92 __asm__
__volatile__("stmxcsr %0" : : "m"(*Destination
) : "memory");
95 static __inline__
__attribute__((always_inline
)) void __ltr(unsigned short Source
)
97 __asm__
__volatile__("ltr %0" : : "rm"(Source
));
100 static __inline__
__attribute__((always_inline
)) void __str(unsigned short *Destination
)
102 __asm__
__volatile__("str %0" : : "m"(*Destination
) : "memory");
106 #define _Ke386GetSeg(N) ({ \
108 __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \
112 #define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
114 #define _Ke386GetDr(N) ({ \
116 __asm__("movq %%dr" #N ",%0\n\t" :"=r" (__d)); \
120 #define _Ke386SetDr(N,X) __asm__ __volatile__("movl %0,%%dr" #N : :"r" (X));
123 static inline void Ki386Cpuid(ULONG Op
, PULONG Eax
, PULONG Ebx
, PULONG Ecx
, PULONG Edx
)
126 : "=a" (*Eax
), "=b" (*Ebx
), "=c" (*Ecx
), "=d" (*Edx
)
130 #define Ke386Rdmsr(msr,val1,val2) __asm__ __volatile__("rdmsr" : "=a" (val1), "=d" (val2) : "c" (msr))
131 #define Ke386Wrmsr(msr,val1,val2) __asm__ __volatile__("wrmsr" : /* no outputs */ : "c" (msr), "a" (val1), "d" (val2))
133 #define Ke386HaltProcessor() __asm__("hlt\n\t");
135 #define Ke386FnInit() __asm__("fninit\n\t");
141 #define Ke386SetCr2(X) __asm__ __volatile__("movq %0,%%cr2" : :"r" ((void*)X));
146 #define Ke386GetDr0() _Ke386GetDr(0)
147 #define Ke386GetDr1() _Ke386GetDr(1)
148 #define Ke386SetDr0(X) _Ke386SetDr(0,X)
149 #define Ke386SetDr1(X) _Ke386SetDr(1,X)
150 #define Ke386GetDr2() _Ke386GetDr(2)
151 #define Ke386SetDr2(X) _Ke386SetDr(2,X)
152 #define Ke386GetDr3() _Ke386GetDr(3)
153 #define Ke386SetDr3(X) _Ke386SetDr(3,X)
154 #define Ke386GetDr4() _Ke386GetDr(4)
155 #define Ke386SetDr4(X) _Ke386SetDr(4,X)
156 #define Ke386GetDr6() _Ke386GetDr(6)
157 #define Ke386SetDr6(X) _Ke386SetDr(6,X)
158 #define Ke386GetDr7() _Ke386GetDr(7)
159 #define Ke386SetDr7(X) _Ke386SetDr(7,X)
164 #define Ke386GetSs() _Ke386GetSeg(ss)
165 #define Ke386GetFs() _Ke386GetSeg(fs)
166 #define Ke386SetFs(X) _Ke386SetSeg(fs, X)
167 #define Ke386SetGs(X) _Ke386SetSeg(gs, X)
168 #define Ke386SetDs(X) _Ke386SetSeg(ds, X)
169 #define Ke386SetEs(X) _Ke386SetSeg(es, X)
170 #define Ke386SetSs(X) _Ke386SetSeg(ss, X)
172 #elif defined(_MSC_VER)
176 Ke386Wrmsr(IN ULONG Register
,
187 Ke386Rdmsr(IN ULONG Register
,
198 Ki386Cpuid(IN ULONG Operation
,
204 __asm mov eax
, Operation
;
206 __asm mov
[Var1
], eax
;
207 __asm mov
[Var2
], ebx
;
208 __asm mov
[Var3
], ecx
;
209 __asm mov
[Var4
], edx
;
221 Ke386HaltProcessor(VOID
)
228 Ke386GetInterruptDescriptorTable(OUT KDESCRIPTOR Descriptor
)
230 __asm sidt Descriptor
;
235 Ke386SetInterruptDescriptorTable(IN KDESCRIPTOR Descriptor
)
237 __asm lidt Descriptor
;
242 Ke386GetGlobalDescriptorTable(OUT KDESCRIPTOR Descriptor
)
244 __asm sgdt Descriptor
;
249 Ke386SetGlobalDescriptorTable(IN KDESCRIPTOR Descriptor
)
251 __asm lgdt Descriptor
;
256 Ke386GetLocalDescriptorTable(OUT USHORT Descriptor
)
258 __asm sldt Descriptor
;
263 Ke386SetLocalDescriptorTable(IN USHORT Descriptor
)
265 __asm lldt Descriptor
;
270 Ke386SaveFlags(IN ULONG Flags
)
278 Ke386RestoreFlags(IN ULONG Flags
)
286 Ke386SetTr(IN USHORT Tr
)
293 Ke386GetTr(IN USHORT Tr
)
303 Ke386SetCr2(IN ULONG Value
)
305 __asm mov eax
, Value
;
356 Ke386SetDr0(IN ULONG Value
)
358 __asm mov eax
, Value
;
364 Ke386SetDr1(IN ULONG Value
)
366 __asm mov eax
, Value
;
372 Ke386SetDr2(IN ULONG Value
)
374 __asm mov eax
, Value
;
380 Ke386SetDr3(IN ULONG Value
)
382 __asm mov eax
, Value
;
388 Ke386SetDr6(IN ULONG Value
)
390 __asm mov eax
, Value
;
396 Ke386SetDr7(IN ULONG Value
)
398 __asm mov eax
, Value
;
435 Ke386SetSs(IN USHORT Value
)
443 Ke386SetFs(IN USHORT Value
)
451 Ke386SetDs(IN USHORT Value
)
459 Ke386SetEs(IN USHORT Value
)
466 #error Unknown compiler for inline assembler