1c2c66affSColin Finck #ifndef __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H
2c2c66affSColin Finck #define __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H
3c2c66affSColin Finck
49658c6a2STimo Kreuzer #ifdef __cplusplus
59658c6a2STimo Kreuzer extern "C" {
69658c6a2STimo Kreuzer #endif
79658c6a2STimo Kreuzer
8c2c66affSColin Finck #define X86_EFLAGS_TF 0x00000100 /* Trap flag */
9c2c66affSColin Finck #define X86_EFLAGS_IF 0x00000200 /* Interrupt Enable flag */
10c2c66affSColin Finck #define X86_EFLAGS_IOPL 0x00003000 /* I/O Privilege Level bits */
11c2c66affSColin Finck #define X86_EFLAGS_NT 0x00004000 /* Nested Task flag */
12c2c66affSColin Finck #define X86_EFLAGS_RF 0x00010000 /* Resume flag */
13c2c66affSColin Finck #define X86_EFLAGS_VM 0x00020000 /* Virtual Mode */
14c2c66affSColin Finck #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
15c2c66affSColin Finck
16c2c66affSColin Finck #define X86_CR0_PE 0x00000001 /* enable Protected Mode */
17c2c66affSColin Finck #define X86_CR0_NE 0x00000020 /* enable native FPU error reporting */
18c2c66affSColin Finck #define X86_CR0_TS 0x00000008 /* enable exception on FPU instruction for task switch */
19c2c66affSColin Finck #define X86_CR0_EM 0x00000004 /* enable FPU emulation (disable FPU) */
20c2c66affSColin Finck #define X86_CR0_MP 0x00000002 /* enable FPU monitoring */
21c2c66affSColin Finck #define X86_CR0_WP 0x00010000 /* enable Write Protect (copy on write) */
22c2c66affSColin Finck #define X86_CR0_PG 0x80000000 /* enable Paging */
23c2c66affSColin Finck
24c2c66affSColin Finck #define X86_CR4_PAE 0x00000020 /* enable physical address extensions */
25c2c66affSColin Finck #define X86_CR4_PGE 0x00000080 /* enable global pages */
26c2c66affSColin Finck #define X86_CR4_OSFXSR 0x00000200 /* enable FXSAVE/FXRSTOR instructions */
27c2c66affSColin Finck #define X86_CR4_OSXMMEXCPT 0x00000400 /* enable #XF exception */
28c2c66affSColin Finck
29ede3f4d4SIvan Labutin /* EDX flags */
30ede3f4d4SIvan Labutin #define X86_FEATURE_FPU 0x00000001 /* x87 FPU is present */
31c2c66affSColin Finck #define X86_FEATURE_VME 0x00000002 /* Virtual 8086 Extensions are present */
32ede3f4d4SIvan Labutin #define X86_FEATURE_DBG 0x00000004 /* Debugging extensions are present */
33ede3f4d4SIvan Labutin #define X86_FEATURE_PSE 0x00000008 /* Page Size Extension is present */
34c2c66affSColin Finck #define X86_FEATURE_TSC 0x00000010 /* time stamp counters are present */
35c2c66affSColin Finck #define X86_FEATURE_PAE 0x00000040 /* physical address extension is present */
36c2c66affSColin Finck #define X86_FEATURE_CX8 0x00000100 /* CMPXCHG8B instruction present */
37c2c66affSColin Finck #define X86_FEATURE_SYSCALL 0x00000800 /* SYSCALL/SYSRET support present */
38ede3f4d4SIvan Labutin #define X86_FEATURE_MTTR 0x00001000 /* Memory type range registers are present */
39c2c66affSColin Finck #define X86_FEATURE_PGE 0x00002000 /* Page Global Enable */
40ede3f4d4SIvan Labutin #define X86_FEATURE_CMOV 0x00008000 /* "Conditional move" instruction supported */
41ede3f4d4SIvan Labutin #define X86_FEATURE_PAT 0x00010000 /* Page Attribute Table is supported */
42ede3f4d4SIvan Labutin #define X86_FEATURE_DS 0x00200000 /* Debug Store is present */
43c2c66affSColin Finck #define X86_FEATURE_MMX 0x00800000 /* MMX extension present */
44c2c66affSColin Finck #define X86_FEATURE_FXSR 0x01000000 /* FXSAVE/FXRSTOR instructions present */
45c2c66affSColin Finck #define X86_FEATURE_SSE 0x02000000 /* SSE extension present */
46c2c66affSColin Finck #define X86_FEATURE_SSE2 0x04000000 /* SSE2 extension present */
47c2c66affSColin Finck #define X86_FEATURE_HT 0x10000000 /* Hyper-Threading present */
48c2c66affSColin Finck
49ede3f4d4SIvan Labutin /* ECX flags */
50ede3f4d4SIvan Labutin #define X86_FEATURE_SSE3 0x00000001 /* SSE3 is supported */
51ede3f4d4SIvan Labutin #define X86_FEATURE_MONITOR 0x00000008 /* SSE3 Monitor instructions supported */
52ede3f4d4SIvan Labutin #define X86_FEATURE_VMX 0x00000020 /* Virtual Machine eXtensions are available */
53ede3f4d4SIvan Labutin #define X86_FEATURE_SSSE3 0x00000200 /* Supplemental SSE3 are available */
54ede3f4d4SIvan Labutin #define X86_FEATURE_FMA3 0x00001000 /* Fused multiple-add supported */
55ede3f4d4SIvan Labutin #define X86_FEATURE_CX16 0x00002000 /* CMPXCHG16B instruction are available */
56ede3f4d4SIvan Labutin #define X86_FEATURE_PCID 0x00020000 /* Process Context IDentifiers are supported */
57ede3f4d4SIvan Labutin #define X86_FEATURE_SSE41 0x00080000 /* SSE 4.1 is supported */
58ede3f4d4SIvan Labutin #define X86_FEATURE_SSE42 0x00100000 /* SSE 4.2 is supported */
59ede3f4d4SIvan Labutin #define X86_FEATURE_POPCNT 0x00800000 /* POPCNT instruction is available */
60ede3f4d4SIvan Labutin #define X86_FEATURE_XSAVE 0x04000000 /* XSAVE family are available */
61ede3f4d4SIvan Labutin
62ede3f4d4SIvan Labutin /* EDX extended flags */
63ede3f4d4SIvan Labutin #define X86_FEATURE_NX 0x00100000 /* NX support present */
64ede3f4d4SIvan Labutin
65c2c66affSColin Finck #define X86_EXT_FEATURE_SSE3 0x00000001 /* SSE3 extension present */
66c2c66affSColin Finck #define X86_EXT_FEATURE_3DNOW 0x40000000 /* 3DNOW! extension present */
67c2c66affSColin Finck
68c2c66affSColin Finck #define FRAME_EDITED 0xFFF8
69c2c66affSColin Finck
70c2c66affSColin Finck #define X86_MSR_GSBASE 0xC0000101
71c2c66affSColin Finck #define X86_MSR_KERNEL_GSBASE 0xC0000102
72c2c66affSColin Finck #define X86_MSR_EFER 0xC0000080
73c2c66affSColin Finck #define X86_MSR_STAR 0xC0000081
74c2c66affSColin Finck #define X86_MSR_LSTAR 0xC0000082
75c2c66affSColin Finck #define X86_MSR_CSTAR 0xC0000083
76c2c66affSColin Finck #define X86_MSR_SFMASK 0xC0000084
77c2c66affSColin Finck
78b9f592c0SIvan Labutin #define EFER_SCE 0x0001
79b9f592c0SIvan Labutin #define EFER_LME 0x0100
80b9f592c0SIvan Labutin #define EFER_LMA 0x0400
81b9f592c0SIvan Labutin #define EFER_NXE 0x0800
82b9f592c0SIvan Labutin #define EFER_SVME 0x1000
83b9f592c0SIvan Labutin #define EFER_FFXSR 0x4000
84c2c66affSColin Finck
85c2c66affSColin Finck #define AMD64_TSS 9
86c2c66affSColin Finck
87c2c66affSColin Finck #define APIC_EOI_REGISTER 0xFFFFFFFFFFFE00B0ULL
88c2c66affSColin Finck
89c2c66affSColin Finck #ifndef __ASM__
90c2c66affSColin Finck
91c2c66affSColin Finck #include "intrin_i.h"
92c2c66affSColin Finck
93c2c66affSColin Finck typedef struct _KIDT_INIT
94c2c66affSColin Finck {
95c2c66affSColin Finck UCHAR InterruptId;
96c2c66affSColin Finck UCHAR Dpl;
97c2c66affSColin Finck UCHAR IstIndex;
98c2c66affSColin Finck PVOID ServiceRoutine;
99c2c66affSColin Finck } KIDT_INIT, *PKIDT_INIT;
100c2c66affSColin Finck
101c2c66affSColin Finck #include <pshpack1.h>
102c2c66affSColin Finck typedef struct _KI_INTERRUPT_DISPATCH_ENTRY
103c2c66affSColin Finck {
104c2c66affSColin Finck UCHAR _Op_nop;
105c2c66affSColin Finck UCHAR _Op_push;
106c2c66affSColin Finck UCHAR _Vector;
107c2c66affSColin Finck UCHAR _Op_jmp;
108c2c66affSColin Finck ULONG RelativeAddress;
109c2c66affSColin Finck } KI_INTERRUPT_DISPATCH_ENTRY, *PKI_INTERRUPT_DISPATCH_ENTRY;
110c2c66affSColin Finck #include <poppack.h>
111c2c66affSColin Finck
112c2c66affSColin Finck extern ULONG KeI386NpxPresent;
113c2c66affSColin Finck extern ULONG KeI386XMMIPresent;
114c2c66affSColin Finck extern ULONG KeI386FxsrPresent;
115c2c66affSColin Finck extern ULONG KeI386CpuType;
116c2c66affSColin Finck extern ULONG KeI386CpuStep;
117c2c66affSColin Finck
118c2c66affSColin Finck //
119c2c66affSColin Finck // INT3 is 1 byte long
120c2c66affSColin Finck //
121c2c66affSColin Finck #define KD_BREAKPOINT_TYPE UCHAR
122c2c66affSColin Finck #define KD_BREAKPOINT_SIZE sizeof(UCHAR)
123c2c66affSColin Finck #define KD_BREAKPOINT_VALUE 0xCC
124c2c66affSColin Finck
125c2c66affSColin Finck //
1263726b992SJérôme Gardou // One-liners for getting and setting special purpose registers in portable code
127c2c66affSColin Finck //
1283726b992SJérôme Gardou FORCEINLINE
1293726b992SJérôme Gardou ULONG_PTR
KeGetContextPc(PCONTEXT Context)1303726b992SJérôme Gardou KeGetContextPc(PCONTEXT Context)
1313726b992SJérôme Gardou {
1323726b992SJérôme Gardou return Context->Rip;
1333726b992SJérôme Gardou }
134c2c66affSColin Finck
1353726b992SJérôme Gardou FORCEINLINE
1363726b992SJérôme Gardou VOID
KeSetContextPc(PCONTEXT Context,ULONG_PTR ProgramCounter)1373726b992SJérôme Gardou KeSetContextPc(PCONTEXT Context, ULONG_PTR ProgramCounter)
1383726b992SJérôme Gardou {
1393726b992SJérôme Gardou Context->Rip = ProgramCounter;
1403726b992SJérôme Gardou }
141c2c66affSColin Finck
1423726b992SJérôme Gardou FORCEINLINE
1433726b992SJérôme Gardou ULONG_PTR
KeGetContextReturnRegister(PCONTEXT Context)1443726b992SJérôme Gardou KeGetContextReturnRegister(PCONTEXT Context)
1453726b992SJérôme Gardou {
1463726b992SJérôme Gardou return Context->Rax;
1473726b992SJérôme Gardou }
148c2c66affSColin Finck
1493726b992SJérôme Gardou FORCEINLINE
1503726b992SJérôme Gardou VOID
KeSetContextReturnRegister(PCONTEXT Context,ULONG_PTR ReturnValue)1513726b992SJérôme Gardou KeSetContextReturnRegister(PCONTEXT Context, ULONG_PTR ReturnValue)
1523726b992SJérôme Gardou {
1533726b992SJérôme Gardou Context->Rax = ReturnValue;
1543726b992SJérôme Gardou }
155c2c66affSColin Finck
1563726b992SJérôme Gardou FORCEINLINE
1573726b992SJérôme Gardou ULONG_PTR
KeGetContextStackRegister(PCONTEXT Context)1583726b992SJérôme Gardou KeGetContextStackRegister(PCONTEXT Context)
1593726b992SJérôme Gardou {
1603726b992SJérôme Gardou return Context->Rsp;
1613726b992SJérôme Gardou }
162c2c66affSColin Finck
1633726b992SJérôme Gardou FORCEINLINE
1643726b992SJérôme Gardou ULONG_PTR
KeGetContextFrameRegister(PCONTEXT Context)1653726b992SJérôme Gardou KeGetContextFrameRegister(PCONTEXT Context)
1663726b992SJérôme Gardou {
1673726b992SJérôme Gardou return Context->Rbp;
1683726b992SJérôme Gardou }
1693726b992SJérôme Gardou
1703726b992SJérôme Gardou FORCEINLINE
1713726b992SJérôme Gardou VOID
KeSetContextFrameRegister(PCONTEXT Context,ULONG_PTR Frame)1723726b992SJérôme Gardou KeSetContextFrameRegister(PCONTEXT Context, ULONG_PTR Frame)
1733726b992SJérôme Gardou {
1743726b992SJérôme Gardou Context->Rbp = Frame;
1753726b992SJérôme Gardou }
1763726b992SJérôme Gardou
1773726b992SJérôme Gardou FORCEINLINE
1783726b992SJérôme Gardou ULONG_PTR
KeGetTrapFramePc(PKTRAP_FRAME TrapFrame)1793726b992SJérôme Gardou KeGetTrapFramePc(PKTRAP_FRAME TrapFrame)
1803726b992SJérôme Gardou {
1813726b992SJérôme Gardou return TrapFrame->Rip;
1823726b992SJérôme Gardou }
1833726b992SJérôme Gardou
1843726b992SJérôme Gardou FORCEINLINE
1853726b992SJérôme Gardou PKTRAP_FRAME
KiGetLinkedTrapFrame(PKTRAP_FRAME TrapFrame)1863726b992SJérôme Gardou KiGetLinkedTrapFrame(PKTRAP_FRAME TrapFrame)
1873726b992SJérôme Gardou {
1883726b992SJérôme Gardou return (PKTRAP_FRAME)TrapFrame->TrapFrame;
1893726b992SJérôme Gardou }
1903726b992SJérôme Gardou
1913726b992SJérôme Gardou FORCEINLINE
1923726b992SJérôme Gardou ULONG_PTR
KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)1933726b992SJérôme Gardou KeGetTrapFrameStackRegister(PKTRAP_FRAME TrapFrame)
1943726b992SJérôme Gardou {
1953726b992SJérôme Gardou return TrapFrame->Rsp;
1963726b992SJérôme Gardou }
1973726b992SJérôme Gardou
1983726b992SJérôme Gardou FORCEINLINE
1993726b992SJérôme Gardou ULONG_PTR
KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)2003726b992SJérôme Gardou KeGetTrapFrameFrameRegister(PKTRAP_FRAME TrapFrame)
2013726b992SJérôme Gardou {
2023726b992SJérôme Gardou return TrapFrame->Rbp;
2033726b992SJérôme Gardou }
204c2c66affSColin Finck
205c2c66affSColin Finck //
206c2c66affSColin Finck // Macro to get trap and exception frame from a thread stack
207c2c66affSColin Finck //
208c2c66affSColin Finck #define KeGetTrapFrame(Thread) \
209c69371ccSTimo Kreuzer ((PKTRAP_FRAME)((ULONG_PTR)((Thread)->InitialStack) - \
210c69371ccSTimo Kreuzer sizeof(KTRAP_FRAME)))
211c2c66affSColin Finck
212c2c66affSColin Finck //
213c2c66affSColin Finck // Macro to get context switches from the PRCB
214c2c66affSColin Finck // All architectures but x86 have it in the PRCB's KeContextSwitches
215c2c66affSColin Finck //
216c2c66affSColin Finck #define KeGetContextSwitches(Prcb) \
217c2c66affSColin Finck (Prcb->KeContextSwitches)
218c2c66affSColin Finck
219c2c66affSColin Finck //
220c2c66affSColin Finck // Macro to get the second level cache size field name which differs between
221c2c66affSColin Finck // CISC and RISC architectures, as the former has unified I/D cache
222c2c66affSColin Finck //
223c2c66affSColin Finck #define KiGetSecondLevelDCacheSize() ((PKIPCR)KeGetPcr())->SecondLevelCacheSize
224c2c66affSColin Finck
225c2c66affSColin Finck #define KeGetExceptionFrame(Thread) \
226c2c66affSColin Finck (PKEXCEPTION_FRAME)((ULONG_PTR)KeGetTrapFrame(Thread) - \
227c2c66affSColin Finck sizeof(KEXCEPTION_FRAME))
228c2c66affSColin Finck
229c2c66affSColin Finck //
230c2c66affSColin Finck // Returns the Interrupt State from a Trap Frame.
231c2c66affSColin Finck // ON = TRUE, OFF = FALSE
232c2c66affSColin Finck //
233c2c66affSColin Finck #define KeGetTrapFrameInterruptState(TrapFrame) \
234c2c66affSColin Finck BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK)
235c2c66affSColin Finck
236c2c66affSColin Finck /* Diable interrupts and return whether they were enabled before */
237c2c66affSColin Finck FORCEINLINE
238c2c66affSColin Finck BOOLEAN
KeDisableInterrupts(VOID)239c2c66affSColin Finck KeDisableInterrupts(VOID)
240c2c66affSColin Finck {
241c2c66affSColin Finck ULONG_PTR Flags;
242c2c66affSColin Finck
243c2c66affSColin Finck /* Get EFLAGS and check if the interrupt bit is set */
244c2c66affSColin Finck Flags = __readeflags();
245c2c66affSColin Finck
246c2c66affSColin Finck /* Disable interrupts */
247c2c66affSColin Finck _disable();
248c2c66affSColin Finck return (Flags & EFLAGS_INTERRUPT_MASK) ? TRUE : FALSE;
249c2c66affSColin Finck }
250c2c66affSColin Finck
251c2c66affSColin Finck /* Restore previous interrupt state */
252c2c66affSColin Finck FORCEINLINE
253c2c66affSColin Finck VOID
KeRestoreInterrupts(BOOLEAN WereEnabled)254c2c66affSColin Finck KeRestoreInterrupts(BOOLEAN WereEnabled)
255c2c66affSColin Finck {
256c2c66affSColin Finck if (WereEnabled) _enable();
257c2c66affSColin Finck }
258c2c66affSColin Finck
259c2c66affSColin Finck //
260c2c66affSColin Finck // Invalidates the TLB entry for a specified address
261c2c66affSColin Finck //
262c2c66affSColin Finck FORCEINLINE
263c2c66affSColin Finck VOID
KeInvalidateTlbEntry(IN PVOID Address)264c2c66affSColin Finck KeInvalidateTlbEntry(IN PVOID Address)
265c2c66affSColin Finck {
266c2c66affSColin Finck /* Invalidate the TLB entry for this address */
267c2c66affSColin Finck __invlpg(Address);
268c2c66affSColin Finck }
269c2c66affSColin Finck
270c2c66affSColin Finck FORCEINLINE
271c2c66affSColin Finck VOID
KeFlushProcessTb(VOID)272c2c66affSColin Finck KeFlushProcessTb(VOID)
273c2c66affSColin Finck {
274c2c66affSColin Finck /* Flush the TLB by resetting CR3 */
275c2c66affSColin Finck __writecr3(__readcr3());
276c2c66affSColin Finck }
277c2c66affSColin Finck
278c2c66affSColin Finck FORCEINLINE
279c2c66affSColin Finck VOID
KeSweepICache(IN PVOID BaseAddress,IN SIZE_T FlushSize)280c2c66affSColin Finck KeSweepICache(IN PVOID BaseAddress,
281c2c66affSColin Finck IN SIZE_T FlushSize)
282c2c66affSColin Finck {
283c2c66affSColin Finck //
284c2c66affSColin Finck // Always sweep the whole cache
285c2c66affSColin Finck //
286c2c66affSColin Finck UNREFERENCED_PARAMETER(BaseAddress);
287c2c66affSColin Finck UNREFERENCED_PARAMETER(FlushSize);
288c2c66affSColin Finck __wbinvd();
289c2c66affSColin Finck }
290c2c66affSColin Finck
291c2c66affSColin Finck FORCEINLINE
292c2c66affSColin Finck VOID
KiRundownThread(IN PKTHREAD Thread)293c2c66affSColin Finck KiRundownThread(IN PKTHREAD Thread)
294c2c66affSColin Finck {
295c2c66affSColin Finck /* Nothing to do */
296c2c66affSColin Finck }
297c2c66affSColin Finck
298c2c66affSColin Finck /* Registers an interrupt handler with an IDT vector */
299c2c66affSColin Finck FORCEINLINE
300c2c66affSColin Finck VOID
KeRegisterInterruptHandler(IN ULONG Vector,IN PVOID Handler)301c2c66affSColin Finck KeRegisterInterruptHandler(IN ULONG Vector,
302c2c66affSColin Finck IN PVOID Handler)
303c2c66affSColin Finck {
304c2c66affSColin Finck UCHAR Entry;
305c2c66affSColin Finck PKIDTENTRY64 Idt;
306c2c66affSColin Finck
307c2c66affSColin Finck /* Get the entry from the HAL */
308c2c66affSColin Finck Entry = HalVectorToIDTEntry(Vector);
309c2c66affSColin Finck
310c2c66affSColin Finck /* Now set the data */
311c2c66affSColin Finck Idt = &KeGetPcr()->IdtBase[Entry];
312c2c66affSColin Finck Idt->OffsetLow = (ULONG_PTR)Handler & 0xffff;
313c2c66affSColin Finck Idt->OffsetMiddle = ((ULONG_PTR)Handler >> 16) & 0xffff;
314c2c66affSColin Finck Idt->OffsetHigh = (ULONG_PTR)Handler >> 32;
315c2c66affSColin Finck Idt->Selector = KGDT64_R0_CODE;
316c2c66affSColin Finck Idt->IstIndex = 0;
317c2c66affSColin Finck Idt->Type = 0x0e;
318c2c66affSColin Finck Idt->Dpl = 0;
319c2c66affSColin Finck Idt->Present = 1;
320c2c66affSColin Finck Idt->Reserved0 = 0;
321c2c66affSColin Finck Idt->Reserved1 = 0;
322c2c66affSColin Finck }
323c2c66affSColin Finck
324c2c66affSColin Finck /* Returns the registered interrupt handler for a given IDT vector */
325c2c66affSColin Finck FORCEINLINE
326c2c66affSColin Finck PVOID
KeQueryInterruptHandler(IN ULONG Vector)327c2c66affSColin Finck KeQueryInterruptHandler(IN ULONG Vector)
328c2c66affSColin Finck {
329c2c66affSColin Finck UCHAR Entry;
330c2c66affSColin Finck PKIDTENTRY64 Idt;
331c2c66affSColin Finck
332c2c66affSColin Finck /* Get the entry from the HAL */
333c2c66affSColin Finck Entry = HalVectorToIDTEntry(Vector);
334c2c66affSColin Finck
335c2c66affSColin Finck /* Get the IDT entry */
336c2c66affSColin Finck Idt = &KeGetPcr()->IdtBase[Entry];
337c2c66affSColin Finck
338c2c66affSColin Finck /* Return the address */
339c2c66affSColin Finck return (PVOID)((ULONG64)Idt->OffsetHigh << 32 |
340c2c66affSColin Finck (ULONG64)Idt->OffsetMiddle << 16 |
341c2c66affSColin Finck (ULONG64)Idt->OffsetLow);
342c2c66affSColin Finck }
343c2c66affSColin Finck
344c2c66affSColin Finck FORCEINLINE
3458314c8eeSHervé Poussineau VOID
KiSendEOI(VOID)346c2c66affSColin Finck KiSendEOI(VOID)
347c2c66affSColin Finck {
348c2c66affSColin Finck /* Write 0 to the apic EOI register */
349c2c66affSColin Finck *((volatile ULONG*)APIC_EOI_REGISTER) = 0;
350c2c66affSColin Finck }
351c2c66affSColin Finck
352c2c66affSColin Finck FORCEINLINE
3538314c8eeSHervé Poussineau VOID
KiEndInterrupt(IN KIRQL Irql,IN PKTRAP_FRAME TrapFrame)354c2c66affSColin Finck KiEndInterrupt(IN KIRQL Irql,
355c2c66affSColin Finck IN PKTRAP_FRAME TrapFrame)
356c2c66affSColin Finck {
357c2c66affSColin Finck /* Make sure this is from the clock handler */
358c2c66affSColin Finck ASSERT(TrapFrame->ErrorCode == 0xc10c4);
359*5ebd4783STimo Kreuzer
360*5ebd4783STimo Kreuzer /* Disable interrupts and end the interrupt */
361*5ebd4783STimo Kreuzer _disable();
362*5ebd4783STimo Kreuzer HalEndSystemInterrupt(Irql, TrapFrame);
363c2c66affSColin Finck }
364c2c66affSColin Finck
365c2c66affSColin Finck FORCEINLINE
3668314c8eeSHervé Poussineau BOOLEAN
KiUserTrap(IN PKTRAP_FRAME TrapFrame)367c2c66affSColin Finck KiUserTrap(IN PKTRAP_FRAME TrapFrame)
368c2c66affSColin Finck {
369c2c66affSColin Finck /* Anything else but Ring 0 is Ring 3 */
370c2c66affSColin Finck return !!(TrapFrame->SegCs & MODE_MASK);
371c2c66affSColin Finck }
372c2c66affSColin Finck
3739658c6a2STimo Kreuzer //
3749658c6a2STimo Kreuzer // PERF Code
3759658c6a2STimo Kreuzer //
3769658c6a2STimo Kreuzer FORCEINLINE
3779658c6a2STimo Kreuzer VOID
Ki386PerfEnd(VOID)3789658c6a2STimo Kreuzer Ki386PerfEnd(VOID)
3799658c6a2STimo Kreuzer {
3809658c6a2STimo Kreuzer extern ULONGLONG BootCyclesEnd, BootCycles;
3819658c6a2STimo Kreuzer BootCyclesEnd = __rdtsc();
3829658c6a2STimo Kreuzer DbgPrint("Boot took %I64u cycles!\n", BootCyclesEnd - BootCycles);
3839658c6a2STimo Kreuzer DbgPrint("Interrupts: %u System Calls: %u Context Switches: %u\n",
3849658c6a2STimo Kreuzer KeGetCurrentPrcb()->InterruptCount,
3859658c6a2STimo Kreuzer KeGetCurrentPrcb()->KeSystemCalls,
3869658c6a2STimo Kreuzer KeGetContextSwitches(KeGetCurrentPrcb()));
3879658c6a2STimo Kreuzer }
388c2c66affSColin Finck
389c2c66affSColin Finck struct _KPCR;
390c2c66affSColin Finck
391e0400e78SSerge Gautherie DECLSPEC_NORETURN VOID KiSwitchToBootStack(IN ULONG_PTR InitialStack);
392c2c66affSColin Finck VOID KiDivideErrorFault(VOID);
393c2c66affSColin Finck VOID KiDebugTrapOrFault(VOID);
394c2c66affSColin Finck VOID KiNmiInterrupt(VOID);
395c2c66affSColin Finck VOID KiBreakpointTrap(VOID);
396c2c66affSColin Finck VOID KiOverflowTrap(VOID);
397c2c66affSColin Finck VOID KiBoundFault(VOID);
398c2c66affSColin Finck VOID KiInvalidOpcodeFault(VOID);
399c2c66affSColin Finck VOID KiNpxNotAvailableFault(VOID);
400c2c66affSColin Finck VOID KiDoubleFaultAbort(VOID);
401c2c66affSColin Finck VOID KiNpxSegmentOverrunAbort(VOID);
402c2c66affSColin Finck VOID KiInvalidTssFault(VOID);
403c2c66affSColin Finck VOID KiSegmentNotPresentFault(VOID);
404c2c66affSColin Finck VOID KiStackFault(VOID);
405c2c66affSColin Finck VOID KiGeneralProtectionFault(VOID);
406c2c66affSColin Finck VOID KiPageFault(VOID);
407c2c66affSColin Finck VOID KiFloatingErrorFault(VOID);
408c2c66affSColin Finck VOID KiAlignmentFault(VOID);
409c2c66affSColin Finck VOID KiMcheckAbort(VOID);
410c2c66affSColin Finck VOID KiXmmException(VOID);
411c2c66affSColin Finck VOID KiApcInterrupt(VOID);
412c2c66affSColin Finck VOID KiRaiseAssertion(VOID);
413c2c66affSColin Finck VOID KiDebugServiceTrap(VOID);
414c2c66affSColin Finck VOID KiDpcInterrupt(VOID);
415c2c66affSColin Finck VOID KiIpiInterrupt(VOID);
416c2c66affSColin Finck
417c2c66affSColin Finck VOID KiGdtPrepareForApplicationProcessorInit(ULONG Id);
418c2c66affSColin Finck VOID Ki386InitializeLdt(VOID);
419c2c66affSColin Finck VOID Ki386SetProcessorFeatures(VOID);
420c2c66affSColin Finck VOID KiGetCacheInformation(VOID);
421c2c66affSColin Finck VOID KiSetProcessorType(VOID);
42270f6ed8eSTimo Kreuzer ULONG64 KiGetFeatureBits(VOID);
423c2c66affSColin Finck VOID KiInitializeCpuFeatures(VOID);
4245ae65ab7SStanislav Motylkov #if DBG
4255ae65ab7SStanislav Motylkov VOID KiReportCpuFeatures(IN PKPRCB Prcb);
4265ae65ab7SStanislav Motylkov #endif
427c2c66affSColin Finck
428c2c66affSColin Finck ULONG KeAllocateGdtSelector(ULONG Desc[2]);
429c2c66affSColin Finck VOID KeFreeGdtSelector(ULONG Entry);
430c2c66affSColin Finck VOID NtEarlyInitVdm(VOID);
431c2c66affSColin Finck VOID KeApplicationProcessorInitDispatcher(VOID);
432c2c66affSColin Finck VOID KeCreateApplicationProcessorIdleThread(ULONG Id);
433c2c66affSColin Finck
434c2c66affSColin Finck VOID
435c2c66affSColin Finck Ke386InitThreadWithContext(PKTHREAD Thread,
436c2c66affSColin Finck PKSYSTEM_ROUTINE SystemRoutine,
437c2c66affSColin Finck PKSTART_ROUTINE StartRoutine,
438c2c66affSColin Finck PVOID StartContext,
439c2c66affSColin Finck PCONTEXT Context);
440c2c66affSColin Finck #define KeArchInitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context) \
441c2c66affSColin Finck Ke386InitThreadWithContext(Thread,SystemRoutine,StartRoutine,StartContext,Context)
442c2c66affSColin Finck
443c2c66affSColin Finck #ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */
444c2c66affSColin Finck VOID
445c2c66affSColin Finck KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
446c2c66affSColin Finck PKSTART_ROUTINE StartRoutine,
447c2c66affSColin Finck PVOID StartContext,
448c2c66affSColin Finck BOOLEAN UserThread,
449c2c66affSColin Finck KTRAP_FRAME TrapFrame);
450c2c66affSColin Finck #endif
451c2c66affSColin Finck
452c2c66affSColin Finck #endif /* __ASM__ */
453c2c66affSColin Finck
454c2c66affSColin Finck // HACK
455c2c66affSColin Finck extern NTKERNELAPI volatile KSYSTEM_TIME KeTickCount;
456c2c66affSColin Finck
457c2c66affSColin Finck // win64 uses DMA macros, this one is not defined
458c2c66affSColin Finck NTHALAPI
459c2c66affSColin Finck NTSTATUS
460c2c66affSColin Finck NTAPI
461c2c66affSColin Finck HalAllocateAdapterChannel(
462c2c66affSColin Finck IN PADAPTER_OBJECT AdapterObject,
463c2c66affSColin Finck IN PWAIT_CONTEXT_BLOCK Wcb,
464c2c66affSColin Finck IN ULONG NumberOfMapRegisters,
465c2c66affSColin Finck IN PDRIVER_CONTROL ExecutionRoutine);
466c2c66affSColin Finck
467fdc1261fSTimo Kreuzer FORCEINLINE
468fdc1261fSTimo Kreuzer PULONG_PTR
KiGetUserModeStackAddress(void)469fdc1261fSTimo Kreuzer KiGetUserModeStackAddress(void)
470fdc1261fSTimo Kreuzer {
471fdc1261fSTimo Kreuzer return &PsGetCurrentThread()->Tcb.TrapFrame->Rsp;
472fdc1261fSTimo Kreuzer }
473fdc1261fSTimo Kreuzer
474e8496b4fSTimo Kreuzer VOID
475e8496b4fSTimo Kreuzer KiSetTrapContext(
476e8496b4fSTimo Kreuzer _Out_ PKTRAP_FRAME TrapFrame,
477e8496b4fSTimo Kreuzer _In_ PCONTEXT Context,
478e8496b4fSTimo Kreuzer _In_ KPROCESSOR_MODE RequestorMode);
479e8496b4fSTimo Kreuzer
48034576c70STimo Kreuzer // Exits to user mode, only restores the trap frame, zeroes the non-volatile registers
48134576c70STimo Kreuzer DECLSPEC_NORETURN
48234576c70STimo Kreuzer VOID
48334576c70STimo Kreuzer KiUserCallbackExit(
48434576c70STimo Kreuzer _In_ PKTRAP_FRAME TrapFrame);
48534576c70STimo Kreuzer
4864bc591c6STimo Kreuzer DECLSPEC_NORETURN
4874bc591c6STimo Kreuzer VOID
4884bc591c6STimo Kreuzer KiExceptionExit(
4894bc591c6STimo Kreuzer _In_ PKTRAP_FRAME TrapFrame,
4904bc591c6STimo Kreuzer _In_ PKEXCEPTION_FRAME ExceptionFrame);
4914bc591c6STimo Kreuzer
49292297093STimo Kreuzer BOOLEAN
49392297093STimo Kreuzer KiProcessorFreezeHandler(
49492297093STimo Kreuzer _In_ PKTRAP_FRAME TrapFrame,
49592297093STimo Kreuzer _In_ PKEXCEPTION_FRAME ExceptionFrame);
49692297093STimo Kreuzer
4979658c6a2STimo Kreuzer #ifdef __cplusplus
4989658c6a2STimo Kreuzer } // extern "C"
4999658c6a2STimo Kreuzer #endif
5009658c6a2STimo Kreuzer
501c2c66affSColin Finck #endif /* __NTOSKRNL_INCLUDE_INTERNAL_AMD64_KE_H */
502c2c66affSColin Finck
503c2c66affSColin Finck /* EOF */
504