IN ULONG Flags) \
{ \
/* Not yet handled */ \
- UNIMPLEMENTED; \
- while (TRUE); \
- return TRUE; \
+ UNIMPLEMENTED_DBGBREAK(); \
+ return FALSE; \
}
C_ASSERT(NPX_FRAME_LENGTH == sizeof(FX_SAVE_AREA));
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
#endif
}
+FORCEINLINE
+VOID
+Ke386SetGdtEntryBase(PKGDTENTRY GdtEntry, PVOID BaseAddress)
+{
+ GdtEntry->BaseLow = (USHORT)((ULONG_PTR)BaseAddress & 0xFFFF);
+ GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)BaseAddress >> 16);
+ GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)BaseAddress >> 24);
+}
+
+FORCEINLINE
+VOID
+KiSetTebBase(PKPCR Pcr, PVOID TebAddress)
+{
+ Pcr->NtTib.Self = TebAddress;
+ Ke386SetGdtEntryBase(&Pcr->GDT[KGDT_R3_TEB / sizeof(KGDTENTRY)], TebAddress);
+}
+
VOID
FASTCALL
Ki386InitializeTss(
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
NTAPI
KiDispatchExceptionFromTrapFrame(
IN NTSTATUS Code,
+ IN ULONG Flags,
IN ULONG_PTR Address,
IN ULONG ParameterCount,
IN ULONG_PTR Parameter1,
extern ULONG KeI386EFlagsAndMaskV86;
extern ULONG KeI386EFlagsOrMaskV86;
extern BOOLEAN KeI386VirtualIntExtensions;
-extern KIDTENTRY KiIdt[MAXIMUM_IDTVECTOR];
+extern KIDTENTRY KiIdt[MAXIMUM_IDTVECTOR+1];
extern KDESCRIPTOR KiIdtDescriptor;
extern BOOLEAN KiI386PentiumLockErrataPresent;
extern ULONG KeI386NpxPresent;
//
// Trap Macros
//
-#include "../trap_x.h"
+#include "trap_x.h"
//
// 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));
}
(EFLAGS_INTERRUPT_MASK | (Eflags & EFLAGS_USER_SANITIZE)));
}
-//
-// Gets a DR register from a CONTEXT structure
-//
-FORCEINLINE
-PVOID
-KiDrFromContext(IN ULONG Dr,
- IN PCONTEXT Context)
-{
- return *(PVOID*)((ULONG_PTR)Context + KiDebugRegisterContextOffsets[Dr]);
-}
-
-//
-// Gets a DR register from a KTRAP_FRAME structure
-//
-FORCEINLINE
-PVOID*
-KiDrFromTrapFrame(IN ULONG Dr,
- IN PKTRAP_FRAME TrapFrame)
-{
- return (PVOID*)((ULONG_PTR)TrapFrame + KiDebugRegisterTrapOffsets[Dr]);
-}
-
//
// Sanitizes a Debug Register
//
//
// 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
+NTSTATUS
KiConvertToGuiThread(VOID)
{
+ NTSTATUS NTAPI PsConvertToGuiThread(VOID);
NTSTATUS Result;
PVOID StackFrame;
"addl %%esp, %1\n\t"
"movl %1, %%ebp"
: "=a"(Result), "=r"(StackFrame)
- :
+ : "p"(PsConvertToGuiThread)
: "%esp", "%ecx", "%edx", "memory"
);
return Result;
//
// 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;
BootCyclesEnd = __rdtsc();
- DbgPrint("Boot took %I64d cycles!\n", BootCyclesEnd - BootCycles);
- DbgPrint("Interrupts: %d System Calls: %d Context Switches: %d\n",
+ DbgPrint("Boot took %I64u cycles!\n", BootCyclesEnd - BootCycles);
+ DbgPrint("Interrupts: %u System Calls: %u Context Switches: %u\n",
KeGetCurrentPrcb()->InterruptCount,
KeGetCurrentPrcb()->KeSystemCalls,
KeGetContextSwitches(KeGetCurrentPrcb()));