[NTOS:KE]
[reactos.git] / reactos / ntoskrnl / include / internal / i386 / ke.h
index f4fe39b..cfe674c 100644 (file)
@@ -137,9 +137,8 @@ typedef union _KTRAP_EXIT_SKIP_BITS
                    IN ULONG Flags)                  \
     {                                               \
         /* Not yet handled */                       \
-        UNIMPLEMENTED;                              \
-        while (TRUE);                               \
-        return TRUE;                                \
+        UNIMPLEMENTED_DBGBREAK();                   \
+        return FALSE;                               \
     }
 
 C_ASSERT(NPX_FRAME_LENGTH == sizeof(FX_SAVE_AREA));
@@ -164,6 +163,18 @@ typedef struct _KV8086_STACK_FRAME
     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
@@ -280,6 +291,23 @@ KiRundownThread(IN PKTHREAD Thread)
 #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(
@@ -355,7 +383,34 @@ KeI386VdmInitialize(
 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
@@ -449,6 +504,7 @@ VOID
 NTAPI
 KiDispatchExceptionFromTrapFrame(
     IN NTSTATUS Code,
+    IN ULONG Flags,
     IN ULONG_PTR Address,
     IN ULONG ParameterCount,
     IN ULONG_PTR Parameter1,
@@ -464,7 +520,7 @@ extern PVOID Ki386IopmSaveArea;
 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;
@@ -493,15 +549,16 @@ extern CHAR KiSystemCallExit2[];
 //
 // 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));
 }
 
@@ -539,28 +596,6 @@ Ke386SanitizeFlags(IN ULONG Eflags,
             (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
 //
@@ -581,38 +616,38 @@ Ke386SanitizeDr(IN PVOID DrAddress,
 //
 // 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,
@@ -620,7 +655,7 @@ KiDispatchException2Args(IN NTSTATUS Code,
                          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);
 }
 
 //
@@ -643,8 +678,8 @@ KiDispatchException2Args(IN NTSTATUS Code,
      *
      */
 #ifdef __GNUC__
-NTSTATUS
 FORCEINLINE
+NTSTATUS
 KiSystemCallTrampoline(IN PVOID Handler,
                        IN PVOID Arguments,
                        IN ULONG StackBytes)
@@ -653,13 +688,13 @@ KiSystemCallTrampoline(IN PVOID Handler,
 
     __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),
@@ -669,8 +704,8 @@ KiSystemCallTrampoline(IN PVOID Handler,
     return Result;
 }
 #elif defined(_MSC_VER)
-NTSTATUS
 FORCEINLINE
+NTSTATUS
 KiSystemCallTrampoline(IN PVOID Handler,
                        IN PVOID Arguments,
                        IN ULONG StackBytes)
@@ -696,8 +731,8 @@ KiSystemCallTrampoline(IN PVOID Handler,
 //
 // Checks for pending APCs
 //
-VOID
 FORCEINLINE
+VOID
 KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
 {
     PKTHREAD Thread;
@@ -734,10 +769,11 @@ KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
 // Converts a base thread to a GUI thread
 //
 #ifdef __GNUC__
-NTSTATUS
 FORCEINLINE
+NTSTATUS
 KiConvertToGuiThread(VOID)
 {
+    NTSTATUS NTAPI PsConvertToGuiThread(VOID);
     NTSTATUS Result;
     PVOID StackFrame;
 
@@ -765,7 +801,7 @@ KiConvertToGuiThread(VOID)
         "addl %%esp, %1\n\t"
         "movl %1, %%ebp"
         : "=a"(Result), "=r"(StackFrame)
-        :
+        : "p"(PsConvertToGuiThread)
         : "%esp", "%ecx", "%edx", "memory"
     );
     return Result;
@@ -781,26 +817,28 @@ KiConvertToGuiThread(VOID);
 //
 // 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
@@ -816,15 +854,15 @@ KiSwitchToBootStack(IN ULONG_PTR 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
@@ -841,8 +879,8 @@ KiIret(VOID)
 // 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)
 {
@@ -857,14 +895,14 @@ KiEndInterrupt(IN KIRQL Irql,
 //
 // 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()));