unbreak build
[reactos.git] / reactos / ntoskrnl / include / internal / i386 / ke.h
index ea2f8bc..abcaba7 100644 (file)
@@ -41,6 +41,24 @@ extern ULONG Ke386CacheAlignment;
 #define KeSetContextReturnRegister(Context, ReturnValue) \
     ((Context)->Eax = (ReturnValue))
 
+//
+// Macro to get trap and exception frame from a thread stack
+//
+#define KeGetTrapFrame(Thread) \
+    (PKTRAP_FRAME)((ULONG_PTR)((Thread)->InitialStack) - \
+                   sizeof(KTRAP_FRAME) - \
+                   sizeof(FX_SAVE_AREA))
+
+#define KeGetExceptionFrame(Thread) \
+    NULL
+
+//
+// Macro to get context switches from the PRCB
+// All architectures but x86 have it in the PRCB's KeContextSwitches
+//
+#define KeGetContextSwitches(Prcb)  \
+    CONTAINING_RECORD(Prcb, KIPCR, PrcbData)->ContextSwitches
+
 //
 // Returns the Interrupt State from a Trap Frame.
 // ON = TRUE, OFF = FALSE
@@ -48,6 +66,127 @@ extern ULONG Ke386CacheAlignment;
 #define KeGetTrapFrameInterruptState(TrapFrame) \
         BooleanFlagOn((TrapFrame)->EFlags, EFLAGS_INTERRUPT_MASK)
 
+//
+// Flags for exiting a trap
+//
+#define KTE_SKIP_PM_BIT  (((KTRAP_EXIT_SKIP_BITS) { { .SkipPreviousMode = TRUE } }).Bits)
+#define KTE_SKIP_SEG_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipSegments  = TRUE } }).Bits)
+#define KTE_SKIP_VOL_BIT (((KTRAP_EXIT_SKIP_BITS) { { .SkipVolatiles = TRUE } }).Bits)
+typedef union _KTRAP_EXIT_SKIP_BITS
+{
+    struct
+    {
+        UCHAR SkipPreviousMode:1;
+        UCHAR SkipSegments:1;
+        UCHAR SkipVolatiles:1;
+        UCHAR Reserved:5;
+    };
+    UCHAR Bits;
+} KTRAP_EXIT_SKIP_BITS, *PKTRAP_EXIT_SKIP_BITS;
+
+
+//
+// Flags used by the VDM/V8086 emulation engine for determining instruction prefixes
+//
+#define PFX_FLAG_ES                0x00000100
+#define PFX_FLAG_CS                0x00000200
+#define PFX_FLAG_SS                0x00000400
+#define PFX_FLAG_DS                0x00000800
+#define PFX_FLAG_FS                0x00001000
+#define PFX_FLAG_GS                0x00002000
+#define PFX_FLAG_OPER32            0x00004000
+#define PFX_FLAG_ADDR32            0x00008000
+#define PFX_FLAG_LOCK              0x00010000
+#define PFX_FLAG_REPNE             0x00020000
+#define PFX_FLAG_REP               0x00040000
+
+//
+// VDM Helper Macros
+//
+// All VDM/V8086 opcode emulators have the same FASTCALL function definition.
+// We need to keep 2 parameters while the original ASM implementation uses 4:
+// TrapFrame, PrefixFlags, Eip, InstructionSize;
+//
+// We pass the trap frame, and prefix flags, in our two parameters.
+//
+// We then realize that since the smallest prefix flag is 0x100, this gives us
+// a count of up to 0xFF. So we OR in the instruction size with the prefix flags
+//
+// We further realize that we always have access to EIP from the trap frame, and
+// that if we want the *current instruction* EIP, we simply have to add the
+// instruction size *MINUS ONE*, and that gives us the EIP we should be looking
+// at now, so we don't need to use the stack to push this parameter.
+//
+// We actually only care about the *current instruction* EIP in one location,
+// so although it may be slightly more expensive to re-calculate the EIP one
+// more time, this way we don't redefine ALL opcode handlers to have 3 parameters,
+// which would be forcing stack usage in all other scenarios.
+//
+#define KiVdmSetVdmEFlags(x)        InterlockedOr((PLONG)KiNtVdmState, (x));
+#define KiVdmClearVdmEFlags(x)      InterlockedAnd((PLONG)KiNtVdmState, ~(x))
+#define KiCallVdmHandler(x)         KiVdmOpcode##x(TrapFrame, Flags)
+#define KiCallVdmPrefixHandler(x)   KiVdmOpcodePrefix(TrapFrame, Flags | x)
+#define KiVdmUnhandledOpcode(x)                     \
+    BOOLEAN                                         \
+    FASTCALL                                        \
+    KiVdmOpcode##x(IN PKTRAP_FRAME TrapFrame,       \
+                   IN ULONG Flags)                  \
+    {                                               \
+        /* Not yet handled */                       \
+        UNIMPLEMENTED;                              \
+        while (TRUE);                               \
+        return TRUE;                                \
+    }
+
+              
+//
+// Registers an interrupt handler with an IDT vector
+//
+FORCEINLINE
+VOID
+KeRegisterInterruptHandler(IN ULONG Vector,
+                           IN PVOID Handler)
+{                           
+    UCHAR Entry;
+    ULONG_PTR Address;
+    PKIPCR Pcr = (PKIPCR)KeGetPcr();
+
+    //
+    // Get the entry from the HAL
+    //
+    Entry = HalVectorToIDTEntry(Vector);
+    Address = PtrToUlong(Handler);
+
+    //
+    // Now set the data
+    //
+    Pcr->IDT[Entry].ExtendedOffset = (USHORT)(Address >> 16);
+    Pcr->IDT[Entry].Offset = (USHORT)Address;
+}
+
+//
+// Returns the registered interrupt handler for a given IDT vector
+//
+FORCEINLINE
+PVOID
+KeQueryInterruptHandler(IN ULONG Vector)
+{
+    PKIPCR Pcr = (PKIPCR)KeGetPcr();
+    UCHAR Entry;
+
+    //
+    // Get the entry from the HAL
+    //
+    Entry = HalVectorToIDTEntry(Vector);
+
+    //
+    // Read the entry from the IDT
+    //
+    return (PVOID)(((Pcr->IDT[Entry].ExtendedOffset << 16) & 0xFFFF0000) |
+                    (Pcr->IDT[Entry].Offset & 0xFFFF));
+}
+
 //
 // Invalidates the TLB entry for a specified address
 //
@@ -59,6 +198,39 @@ KeInvalidateTlbEntry(IN PVOID Address)
     __invlpg(Address);
 }
 
+FORCEINLINE
+VOID
+KeFlushProcessTb(VOID)
+{
+    /* Flush the TLB by resetting CR3 */
+    __writecr3(__readcr3());
+}
+
+FORCEINLINE
+PRKTHREAD
+KeGetCurrentThread(VOID)
+{
+    /* Return the current thread */
+    return ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
+}
+
+FORCEINLINE
+VOID
+KiRundownThread(IN PKTHREAD Thread)
+{
+#ifndef CONFIG_SMP
+    /* Check if this is the NPX Thread */
+    if (KeGetCurrentPrcb()->NpxThread == Thread)
+    {
+        /* Clear it */
+        KeGetCurrentPrcb()->NpxThread = NULL;
+        Ke386FnInit();
+    }
+#else
+    /* Nothing to do */
+#endif
+}
+
 VOID
 FASTCALL
 Ki386InitializeTss(
@@ -191,6 +363,25 @@ Ki386EnableXMMIExceptions(
     IN ULONG_PTR Context
 );
 
+BOOLEAN
+NTAPI
+VdmDispatchBop(
+    IN PKTRAP_FRAME TrapFrame
+);
+BOOLEAN
+FASTCALL
+KiVdmOpcodePrefix(
+    IN PKTRAP_FRAME TrapFrame,
+    IN ULONG Flags
+);
+
+BOOLEAN
+FASTCALL
+Ki386HandleOpcodeV86(
+    IN PKTRAP_FRAME TrapFrame
+);
+
 //
 // Global x86 only Kernel data
 //
@@ -214,6 +405,10 @@ extern VOID __cdecl KiTrap2(VOID);
 extern VOID __cdecl KiTrap8(VOID);
 extern VOID __cdecl KiTrap19(VOID);
 extern VOID __cdecl KiFastCallEntry(VOID);
+extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
+extern VOID __cdecl CopyParams(VOID);
+extern VOID __cdecl ReadBatch(VOID);
+extern VOID __cdecl FrRestore(VOID);
 
 //
 // Sanitizes a selector