1 #ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H
2 #define __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H
9 extern ULONG Ke386CacheAlignment
;
12 // Thread Dispatcher Header DebugActive Mask
14 #define DR_MASK(x) (1 << (x))
15 #define DR_REG_MASK 0x4F
17 #define IMAGE_FILE_MACHINE_ARCHITECTURE IMAGE_FILE_MACHINE_I386
20 // INT3 is 1 byte long
22 #define KD_BREAKPOINT_TYPE UCHAR
23 #define KD_BREAKPOINT_SIZE sizeof(UCHAR)
24 #define KD_BREAKPOINT_VALUE 0xCC
27 // Macros for getting and setting special purpose registers in portable code
29 #define KeGetContextPc(Context) \
32 #define KeSetContextPc(Context, ProgramCounter) \
33 ((Context)->Eip = (ProgramCounter))
35 #define KeGetTrapFramePc(TrapFrame) \
38 #define KeGetContextReturnRegister(Context) \
41 #define KeSetContextReturnRegister(Context, ReturnValue) \
42 ((Context)->Eax = (ReturnValue))
45 // Macro to get trap and exception frame from a thread stack
47 #define KeGetTrapFrame(Thread) \
48 (PKTRAP_FRAME)((ULONG_PTR)((Thread)->InitialStack) - \
49 sizeof(KTRAP_FRAME) - \
52 #define KeGetExceptionFrame(Thread) \
56 // Macro to get context switches from the PRCB
57 // All architectures but x86 have it in the PRCB's KeContextSwitches
59 #define KeGetContextSwitches(Prcb) \
60 CONTAINING_RECORD(Prcb, KIPCR, PrcbData)->ContextSwitches
63 // Returns the Interrupt State from a Trap Frame.
64 // ON = TRUE, OFF = FALSE
66 #define KeGetTrapFrameInterruptState(TrapFrame) \
67 BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK)
70 // Flags for exiting a trap
72 #define KTE_SKIP_PM_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipPreviousMode = TRUE } }).Bits)
73 #define KTE_SKIP_SEG_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipSegments = TRUE } }).Bits)
74 #define KTE_SKIP_VOL_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipVolatiles = TRUE } }).Bits)
76 typedef union _KTRAP_EXIT_SKIP_BITS
80 UCHAR SkipPreviousMode
:1;
82 UCHAR SkipVolatiles
:1;
86 } KTRAP_EXIT_SKIP_BITS
, *PKTRAP_EXIT_SKIP_BITS
;
89 // Registers an interrupt handler with an IDT vector
93 KeRegisterInterruptHandler(IN ULONG Vector
,
98 PKIPCR Pcr
= (PKIPCR
)KeGetPcr();
101 // Get the entry from the HAL
103 Entry
= HalVectorToIDTEntry(Vector
);
104 Address
= PtrToUlong(Handler
);
109 Pcr
->IDT
[Entry
].ExtendedOffset
= (USHORT
)(Address
>> 16);
110 Pcr
->IDT
[Entry
].Offset
= (USHORT
)Address
;
114 // Returns the registered interrupt handler for a given IDT vector
118 KeQueryInterruptHandler(IN ULONG Vector
)
120 PKIPCR Pcr
= (PKIPCR
)KeGetPcr();
124 // Get the entry from the HAL
126 Entry
= HalVectorToIDTEntry(Vector
);
129 // Read the entry from the IDT
131 return (PVOID
)(((Pcr
->IDT
[Entry
].ExtendedOffset
<< 16) & 0xFFFF0000) |
132 (Pcr
->IDT
[Entry
].Offset
& 0xFFFF));
136 // Invalidates the TLB entry for a specified address
140 KeInvalidateTlbEntry(IN PVOID Address
)
142 /* Invalidate the TLB entry for this address */
148 KeFlushProcessTb(VOID
)
150 /* Flush the TLB by resetting CR3 */
151 __writecr3(__readcr3());
156 KeGetCurrentThread(VOID
)
158 /* Return the current thread */
159 return ((PKIPCR
)KeGetPcr())->PrcbData
.CurrentThread
;
164 KiRundownThread(IN PKTHREAD Thread
)
167 /* Check if this is the NPX Thread */
168 if (KeGetCurrentPrcb()->NpxThread
== Thread
)
171 KeGetCurrentPrcb()->NpxThread
= NULL
;
193 KiGetCacheInformation(VOID
);
203 KiIsNpxErrataPresent(
209 KiSetProcessorType(VOID
);
213 KiGetFeatureBits(VOID
);
215 #ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */
218 KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine
,
219 PKSTART_ROUTINE StartRoutine
,
222 KTRAP_FRAME TrapFrame
);
227 Ke386GetGdtEntryThread(
230 IN PKGDTENTRY Descriptor
236 IN FLOATING_SAVE_AREA
*SaveArea
242 IN PKTRAP_FRAME TrapFrame
247 Ki386SetupAndExitToV86Mode(
259 Ki386EnableGlobalPage(
260 IN
volatile ULONG_PTR Context
265 KiI386PentiumLockErrataFixup(
283 KiAmdK6InitializeMTRR(
289 KiRestoreFastSyscallReturnState(
307 Ki386EnableXMMIExceptions(
314 IN PKTRAP_FRAME TrapFrame
320 IN PKTRAP_FRAME TrapFrame
,
326 Ki386HandleOpcodeV86(
327 IN PKTRAP_FRAME TrapFrame
331 // Global x86 only Kernel data
333 extern PVOID Ki386IopmSaveArea
;
334 extern ULONG KeI386EFlagsAndMaskV86
;
335 extern ULONG KeI386EFlagsOrMaskV86
;
336 extern BOOLEAN KeI386VirtualIntExtensions
;
337 extern KIDTENTRY KiIdt
[MAXIMUM_IDTVECTOR
];
338 extern KDESCRIPTOR KiIdtDescriptor
;
339 extern ULONG Ke386GlobalPagesEnabled
;
340 extern BOOLEAN KiI386PentiumLockErrataPresent
;
341 extern ULONG KeI386NpxPresent
;
342 extern ULONG KeI386XMMIPresent
;
343 extern ULONG KeI386FxsrPresent
;
344 extern ULONG KiMXCsrMask
;
345 extern ULONG KeI386CpuType
;
346 extern ULONG KeI386CpuStep
;
347 extern UCHAR KiDebugRegisterTrapOffsets
[9];
348 extern UCHAR KiDebugRegisterContextOffsets
[9];
349 extern VOID __cdecl
KiTrap2(VOID
);
350 extern VOID __cdecl
KiTrap8(VOID
);
351 extern VOID __cdecl
KiTrap19(VOID
);
352 extern VOID __cdecl
KiFastCallEntry(VOID
);
353 extern VOID NTAPI
ExpInterlockedPopEntrySListFault(VOID
);
354 extern VOID __cdecl
CopyParams(VOID
);
355 extern VOID __cdecl
ReadBatch(VOID
);
356 extern VOID __cdecl
FrRestore(VOID
);
359 // Sanitizes a selector
363 Ke386SanitizeSeg(IN ULONG Cs
,
364 IN KPROCESSOR_MODE Mode
)
367 // Check if we're in kernel-mode, and force CPL 0 if so.
368 // Otherwise, force CPL 3.
370 return ((Mode
== KernelMode
) ?
371 (Cs
& (0xFFFF & ~RPL_MASK
)) :
372 (RPL_MASK
| (Cs
& 0xFFFF)));
380 Ke386SanitizeFlags(IN ULONG Eflags
,
381 IN KPROCESSOR_MODE Mode
)
384 // Check if we're in kernel-mode, and sanitize EFLAGS if so.
385 // Otherwise, also force interrupt mask on.
387 return ((Mode
== KernelMode
) ?
388 (Eflags
& (EFLAGS_USER_SANITIZE
| EFLAGS_INTERRUPT_MASK
)) :
389 (EFLAGS_INTERRUPT_MASK
| (Eflags
& EFLAGS_USER_SANITIZE
)));
393 // Gets a DR register from a CONTEXT structure
397 KiDrFromContext(IN ULONG Dr
,
400 return *(PVOID
*)((ULONG_PTR
)Context
+ KiDebugRegisterContextOffsets
[Dr
]);
404 // Gets a DR register from a KTRAP_FRAME structure
408 KiDrFromTrapFrame(IN ULONG Dr
,
409 IN PKTRAP_FRAME TrapFrame
)
411 return (PVOID
*)((ULONG_PTR
)TrapFrame
+ KiDebugRegisterTrapOffsets
[Dr
]);
415 // Sanitizes a Debug Register
419 Ke386SanitizeDr(IN PVOID DrAddress
,
420 IN KPROCESSOR_MODE Mode
)
423 // Check if we're in kernel-mode, and return the address directly if so.
424 // Otherwise, make sure it's not inside the kernel-mode address space.
425 // If it is, then clear the address.
427 return ((Mode
== KernelMode
) ? DrAddress
:
428 (DrAddress
<= MM_HIGHEST_USER_ADDRESS
) ? DrAddress
: 0);
432 #endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_KE_H */