KV86_FRAME V86Frame;
} KV8086_STACK_FRAME, *PKV8086_STACK_FRAME;
+//
+// Large Pages Support
+//
+typedef struct _LARGE_IDENTITY_MAP
+{
+ PHARDWARE_PTE TopLevelDirectory;
+ ULONG Cr3;
+ ULONG_PTR StartAddress;
+ ULONG PagesCount;
+ PVOID PagesList[30];
+} LARGE_IDENTITY_MAP, *PLARGE_IDENTITY_MAP;
+
/* Diable interrupts and return whether they were enabled before */
FORCEINLINE
BOOLEAN
__writecr3(__readcr3());
}
+FORCEINLINE
+VOID
+KeSweepICache(IN PVOID BaseAddress,
+ IN SIZE_T FlushSize)
+{
+ //
+ // Always sweep the whole cache
+ //
+ UNREFERENCED_PARAMETER(BaseAddress);
+ UNREFERENCED_PARAMETER(FlushSize);
+ __wbinvd();
+}
+
FORCEINLINE
PRKTHREAD
KeGetCurrentThread(VOID)
ULONG_PTR
NTAPI
Ki386EnableGlobalPage(
- IN volatile ULONG_PTR Context
+ IN ULONG_PTR Context
+);
+
+ULONG_PTR
+NTAPI
+Ki386EnableTargetLargePage(
+ IN ULONG_PTR Context
+);
+
+BOOLEAN
+NTAPI
+Ki386CreateIdentityMap(
+ IN PLARGE_IDENTITY_MAP IdentityMap,
+ IN PVOID StartPtr,
+ IN ULONG Length
+);
+
+VOID
+NTAPI
+Ki386FreeIdentityMap(
+ IN PLARGE_IDENTITY_MAP IdentityMap
+);
+
+VOID
+NTAPI
+Ki386EnableCurrentLargePage(
+ IN ULONG_PTR StartAddress,
+ IN ULONG Cr3
);
VOID
IN PKTRAP_FRAME TrapFrame
);
+BOOLEAN
+NTAPI
+VdmDispatchPageFault(
+ _In_ PKTRAP_FRAME TrapFrame
+);
+
BOOLEAN
FASTCALL
KiVdmOpcodePrefix(
NTAPI
KiDispatchExceptionFromTrapFrame(
IN NTSTATUS Code,
+ IN ULONG Flags,
IN ULONG_PTR Address,
IN ULONG ParameterCount,
IN ULONG_PTR Parameter1,
IN PKTRAP_FRAME TrapFrame
);
+NTSTATUS
+NTAPI
+KiConvertToGuiThread(
+ VOID
+);
+
//
// Global x86 only Kernel data
//
extern ULONG KiMXCsrMask;
extern ULONG KeI386CpuType;
extern ULONG KeI386CpuStep;
-extern ULONG Ke386CacheAlignment;
extern ULONG KiFastSystemCallDisable;
extern UCHAR KiDebugRegisterTrapOffsets[9];
extern UCHAR KiDebugRegisterContextOffsets[9];
extern VOID NTAPI ExpInterlockedPopEntrySListResume(VOID);
extern VOID __cdecl CopyParams(VOID);
extern VOID __cdecl ReadBatch(VOID);
-extern VOID __cdecl FrRestore(VOID);
extern CHAR KiSystemCallExitBranch[];
extern CHAR KiSystemCallExit[];
extern CHAR KiSystemCallExit2[];
//
// Returns a thread's FPU save area
//
-PFX_SAVE_AREA
FORCEINLINE
+PFX_SAVE_AREA
KiGetThreadNpxArea(IN PKTHREAD Thread)
{
+ ASSERT((ULONG_PTR)Thread->InitialStack % 16 == 0);
return (PFX_SAVE_AREA)((ULONG_PTR)Thread->InitialStack - sizeof(FX_SAVE_AREA));
}
//
// Exception with no arguments
//
-VOID
FORCEINLINE
DECLSPEC_NORETURN
+VOID
KiDispatchException0Args(IN NTSTATUS Code,
IN ULONG_PTR Address,
IN PKTRAP_FRAME TrapFrame)
{
/* Helper for exceptions with no arguments */
- KiDispatchExceptionFromTrapFrame(Code, Address, 0, 0, 0, 0, TrapFrame);
+ KiDispatchExceptionFromTrapFrame(Code, 0, Address, 0, 0, 0, 0, TrapFrame);
}
//
// Exception with one argument
//
-VOID
FORCEINLINE
DECLSPEC_NORETURN
+VOID
KiDispatchException1Args(IN NTSTATUS Code,
IN ULONG_PTR Address,
IN ULONG P1,
IN PKTRAP_FRAME TrapFrame)
{
/* Helper for exceptions with no arguments */
- KiDispatchExceptionFromTrapFrame(Code, Address, 1, P1, 0, 0, TrapFrame);
+ KiDispatchExceptionFromTrapFrame(Code, 0, Address, 1, P1, 0, 0, TrapFrame);
}
//
// Exception with two arguments
//
-VOID
FORCEINLINE
DECLSPEC_NORETURN
+VOID
KiDispatchException2Args(IN NTSTATUS Code,
IN ULONG_PTR Address,
IN ULONG P1,
IN PKTRAP_FRAME TrapFrame)
{
/* Helper for exceptions with no arguments */
- KiDispatchExceptionFromTrapFrame(Code, Address, 2, P1, P2, 0, TrapFrame);
+ KiDispatchExceptionFromTrapFrame(Code, 0, Address, 2, P1, P2, 0, TrapFrame);
}
//
*
*/
#ifdef __GNUC__
-NTSTATUS
FORCEINLINE
+NTSTATUS
KiSystemCallTrampoline(IN PVOID Handler,
IN PVOID Arguments,
IN ULONG StackBytes)
__asm__ __volatile__
(
- "subl %1, %%esp\n"
- "movl %%esp, %%edi\n"
- "movl %2, %%esi\n"
- "shrl $2, %1\n"
- "rep movsd\n"
- "call *%3\n"
- "movl %%eax, %0\n"
+ "subl %1, %%esp\n\t"
+ "movl %%esp, %%edi\n\t"
+ "movl %2, %%esi\n\t"
+ "shrl $2, %1\n\t"
+ "rep movsd\n\t"
+ "call *%3\n\t"
+ "movl %%eax, %0"
: "=r"(Result)
: "c"(StackBytes),
"d"(Arguments),
return Result;
}
#elif defined(_MSC_VER)
-NTSTATUS
FORCEINLINE
+NTSTATUS
KiSystemCallTrampoline(IN PVOID Handler,
IN PVOID Arguments,
IN ULONG StackBytes)
//
// Checks for pending APCs
//
-VOID
FORCEINLINE
+VOID
KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
{
PKTHREAD Thread;
}
}
-//
-// Converts a base thread to a GUI thread
-//
-#ifdef __GNUC__
-NTSTATUS
-FORCEINLINE
-KiConvertToGuiThread(VOID)
-{
- NTSTATUS Result;
- PVOID StackFrame;
-
- /*
- * Converting to a GUI thread safely updates ESP in-place as well as the
- * current Thread->TrapFrame and EBP when KeSwitchKernelStack is called.
- *
- * However, PsConvertToGuiThread "helpfully" restores EBP to the original
- * caller's value, since it is considered a nonvolatile register. As such,
- * as soon as we're back after the conversion and we try to store the result
- * which will probably be in some stack variable (EBP-based), we'll crash as
- * we are touching the de-allocated non-expanded stack.
- *
- * Thus we need a way to update our EBP before EBP is touched, and the only
- * way to guarantee this is to do the call itself in assembly, use the EAX
- * register to store the result, fixup EBP, and then let the C code continue
- * on its merry way.
- *
- */
- __asm__ __volatile__
- (
- "movl %%ebp, %1\n\t"
- "subl %%esp, %1\n\t"
- "call _PsConvertToGuiThread@0\n\t"
- "addl %%esp, %1\n\t"
- "movl %1, %%ebp"
- : "=a"(Result), "=r"(StackFrame)
- :
- : "%esp", "%ecx", "%edx", "memory"
- );
- return Result;
-}
-#elif defined(_MSC_VER)
-NTSTATUS
-NTAPI
-KiConvertToGuiThread(VOID);
-#else
-#error Unknown Compiler
-#endif
-
//
// Switches from boot loader to initial kernel stack
//
-VOID
FORCEINLINE
+VOID
KiSwitchToBootStack(IN ULONG_PTR InitialStack)
{
+ VOID NTAPI KiSystemStartupBootStack(VOID);
+
/* We have to switch to a new stack before continuing kernel initialization */
#ifdef __GNUC__
__asm__
(
- "movl %0, %%esp\n"
- "subl %1, %%esp\n"
- "pushl %2\n"
- "jmp _KiSystemStartupBootStack@0\n"
+ "movl %0, %%esp\n\t"
+ "subl %1, %%esp\n\t"
+ "pushl %2\n\t"
+ "jmp _KiSystemStartupBootStack@0"
:
: "c"(InitialStack),
"i"(NPX_FRAME_LENGTH + KTRAP_FRAME_ALIGN + KTRAP_FRAME_LENGTH),
- "i"(CR0_EM | CR0_TS | CR0_MP)
+ "i"(CR0_EM | CR0_TS | CR0_MP),
+ "p"(KiSystemStartupBootStack)
: "%esp"
);
#elif defined(_MSC_VER)
- VOID NTAPI KiSystemStartupBootStack(VOID);
__asm
{
mov esp, InitialStack
//
// Emits the iret instruction for C code
//
+FORCEINLINE
DECLSPEC_NORETURN
VOID
-FORCEINLINE
KiIret(VOID)
{
#if defined(__GNUC__)
__asm__ __volatile__
(
- "iret\n"
+ "iret"
);
#elif defined(_MSC_VER)
__asm
// Normally this is done by the HAL, but on x86 as an optimization, the kernel
// initiates the end by calling back into the HAL and exiting the trap here.
//
-VOID
FORCEINLINE
+VOID
KiEndInterrupt(IN KIRQL Irql,
IN PKTRAP_FRAME TrapFrame)
{
//
// PERF Code
//
-VOID
FORCEINLINE
+VOID
Ki386PerfEnd(VOID)
{
extern ULONGLONG BootCyclesEnd, BootCycles;