Author: jcatena
Date: Thu Feb 4 13:05:14 2010
New Revision: 45417
URL:
http://svn.reactos.org/svn/reactos?rev=45417&view=rev
Log:
[NTOS] msvc build Update, work in progress
Modified:
branches/jcatena-branch/include/ddk/wdm.h
branches/jcatena-branch/include/ddk/winddk.h
branches/jcatena-branch/include/ndk/i386/asm.h
branches/jcatena-branch/include/psdk/winbase.h
branches/jcatena-branch/include/psdk/winnt.h
branches/jcatena-branch/include/reactos/msc/i386/cpu_c.h
branches/jcatena-branch/include/reactos/msc/i386/platf.h
branches/jcatena-branch/include/reactos/msc/intrin2.h
branches/jcatena-branch/lib/cpu/i386/RegSave.c
branches/jcatena-branch/lib/rtl/critical.c
branches/jcatena-branch/lib/rtl/timerqueue.c
branches/jcatena-branch/ntoskrnl/ex/sysinfo.c
branches/jcatena-branch/ntoskrnl/include/internal/i386/asmmacro.S
branches/jcatena-branch/ntoskrnl/include/internal/i386/ke.h
branches/jcatena-branch/ntoskrnl/include/internal/ke.h
branches/jcatena-branch/ntoskrnl/include/internal/trap_x.h
branches/jcatena-branch/ntoskrnl/include/ntoskrnl_bld.h
branches/jcatena-branch/ntoskrnl/kdbg/kdb.c
branches/jcatena-branch/ntoskrnl/ke/i386/cpu.c
branches/jcatena-branch/ntoskrnl/ke/i386/exp.c
branches/jcatena-branch/ntoskrnl/ke/i386/irqobj.c
branches/jcatena-branch/ntoskrnl/ke/i386/kiinit.c
branches/jcatena-branch/ntoskrnl/ke/i386/traphdlr.c
branches/jcatena-branch/ntoskrnl/ke/ke.vcproj
branches/jcatena-branch/ntoskrnl/ntoskrnl.sln
branches/jcatena-branch/ntoskrnl/ntoskrnl.vcproj
branches/jcatena-branch/ntoskrnl/trap/i386/TrapStub.h
branches/jcatena-branch/ntoskrnl/trap/trap.c
Modified: branches/jcatena-branch/include/ddk/wdm.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/ddk/wdm.…
==============================================================================
--- branches/jcatena-branch/include/ddk/wdm.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/ddk/wdm.h [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -1,3 +1,4 @@
+_ONCE
#ifndef _WDMDDK_
#define _WDMDDK_
@@ -365,51 +366,6 @@
#define PF_CHANNELS_ENABLED 16
-
-//
-// Intrinsics (note: taken from our winnt.h)
-// FIXME: 64-bit
-//
-#if defined(__GNUC__)
-
-static __inline__ BOOLEAN
-InterlockedBitTestAndSet(IN LONG volatile *Base,
- IN LONG Bit)
-{
-#if defined(_M_IX86)
- LONG OldBit;
- __asm__ __volatile__("lock "
- "btsl %2,%1\n\t"
- "sbbl %0,%0\n\t"
- :"=r" (OldBit),"+m" (*Base)
- :"Ir" (Bit)
- : "memory");
- return OldBit;
-#else
- return (_InterlockedOr(Base, 1 << Bit) >> Bit) & 1;
-#endif
-}
-
-static __inline__ BOOLEAN
-InterlockedBitTestAndReset(IN LONG volatile *Base,
- IN LONG Bit)
-{
-#if defined(_M_IX86)
- LONG OldBit;
- __asm__ __volatile__("lock "
- "btrl %2,%1\n\t"
- "sbbl %0,%0\n\t"
- :"=r" (OldBit),"+m" (*Base)
- :"Ir" (Bit)
- : "memory");
- return OldBit;
-#else
- return (_InterlockedAnd(Base, ~(1 << Bit)) >> Bit) & 1;
-#endif
-}
-
-#endif
-
#define BitScanForward _BitScanForward
#define BitScanReverse _BitScanReverse
Modified: branches/jcatena-branch/include/ddk/winddk.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/ddk/wind…
==============================================================================
--- branches/jcatena-branch/include/ddk/winddk.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/ddk/winddk.h [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -8452,22 +8452,7 @@
KeLeaveCriticalRegion(
VOID);
-#ifdef _X86_
-
-static __inline
-VOID
-KeMemoryBarrier(
- VOID)
-{
- volatile LONG Barrier;
-#if defined(__GNUC__)
- __asm__ __volatile__ ("xchg %%eax, %0" : : "m" (Barrier) :
"%eax");
-#elif defined(_MSC_VER)
- __asm xchg [Barrier], eax
-#endif
-}
-
-#endif
+#define KeMemoryBarrier _MemoryBarrier
NTKERNELAPI
LONG
Modified: branches/jcatena-branch/include/ndk/i386/asm.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/ndk/i386…
==============================================================================
--- branches/jcatena-branch/include/ndk/i386/asm.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/ndk/i386/asm.h [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -55,16 +55,16 @@
#ifdef __ASM__
#define RPL_MASK 0x0003
#define MODE_MASK 0x0001
-#define KGDT_R0_CODE (0x8)
-#define KGDT_R0_DATA (0x10)
-#define KGDT_R3_CODE (0x18)
-#define KGDT_R3_DATA (0x20)
-#define KGDT_TSS (0x28)
-#define KGDT_R0_PCR (0x30)
-#define KGDT_R3_TEB (0x38)
-#define KGDT_LDT (0x48)
-#define KGDT_DF_TSS (0x50)
-#define KGDT_NMI_TSS (0x58)
+#define KGDT_R0_CODE 0x8
+#define KGDT_R0_DATA 0x10
+#define KGDT_R3_CODE 0x18
+#define KGDT_R3_DATA 0x20
+#define KGDT_TSS 0x28
+#define KGDT_R0_PCR 0x30
+#define KGDT_R3_TEB 0x38
+#define KGDT_LDT 0x48
+#define KGDT_DF_TSS 0x50
+#define KGDT_NMI_TSS 0x58
#endif
//
Modified: branches/jcatena-branch/include/psdk/winbase.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/psdk/win…
==============================================================================
--- branches/jcatena-branch/include/psdk/winbase.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/psdk/winbase.h [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -1849,11 +1849,12 @@
#else // !(defined (_M_AMD64) || defined (_M_IA64))
+#define InterlockedExchange _InterlockedExchange
+#define InterlockedCompareExchange _InterlockedCompareExchange
+
LONG WINAPI InterlockedOr(IN OUT LONG volatile *,LONG);
LONG WINAPI InterlockedAnd(IN OUT LONG volatile *,LONG);
-LONG WINAPI InterlockedCompareExchange(IN OUT LONG volatile *,LONG,LONG);
LONG WINAPI InterlockedDecrement(IN OUT LONG volatile *);
-LONG WINAPI InterlockedExchange(IN OUT LONG volatile *,LONG);
#if defined(_WIN64)
/* PVOID WINAPI InterlockedExchangePointer(PVOID*,PVOID); */
#define InterlockedExchangePointer(t,v) \
@@ -1866,7 +1867,7 @@
#define InterlockedExchangePointer(t,v) \
(PVOID)InterlockedExchange((LPLONG)(t),(LONG)(v))
/* PVOID WINAPI InterlockedCompareExchangePointer(PVOID*,PVOID,PVOID); */
- #define InterlockedCompareExchangePointer(d,e,c) \
+#define InterlockedCompareExchangePointer(d,e,c) \
(PVOID)InterlockedCompareExchange((LPLONG)(d),(LONG)(e),(LONG)(c))
#endif
LONG WINAPI InterlockedExchangeAdd(IN OUT LONG volatile *,LONG);
Modified: branches/jcatena-branch/include/psdk/winnt.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/psdk/win…
==============================================================================
--- branches/jcatena-branch/include/psdk/winnt.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/psdk/winnt.h [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -5007,23 +5007,7 @@
/* TODO: Other architectures than X86 */
#if defined(_M_IX86)
-#if defined(_MSC_VER)
-FORCEINLINE
-VOID
-MemoryBarrier (VOID)
-{
- LONG Barrier;
- __asm { xchg Barrier, eax }
-}
-#else
-FORCEINLINE
-VOID
-MemoryBarrier(VOID)
-{
- LONG Barrier;
- __asm__ __volatile__("xchgl %%eax, %[Barrier]" : : [Barrier] "m"
(Barrier) : "memory");
-}
-#endif
+#define MemoryBarrier _MemoryBarrier
#elif defined (_M_AMD64)
#define MemoryBarrier __faststorefence
#elif defined(_M_PPC)
Modified: branches/jcatena-branch/include/reactos/msc/i386/cpu_c.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/reactos/…
==============================================================================
--- branches/jcatena-branch/include/reactos/msc/i386/cpu_c.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/reactos/msc/i386/cpu_c.h [iso-8859-1] Thu Feb 4
13:05:14 2010
@@ -7,8 +7,9 @@
// not recognized by inline assembler:
// mov eax, cr4
#define CpuMovEaxCr4 _ASM _emit 0x0f _ASM _emit 0x20 _ASM _emit 0xe0
+#define CpuMovCr4Eax _ASM _emit 0x0f _ASM _emit 0x22 _ASM _emit 0xe0
// sysexit
-#define CpuSysExit() _ASM _emit 0x0f _ASM _emit 0x35
+#define CpuSysExit _ASM _emit 0x0f _ASM _emit 0x35
// enable / disable int flag
#ifndef CPU_PREFER_NOINTRIN
@@ -89,6 +90,16 @@
#define CpuSetTr_m(x) _ASM ltr x
// get/set crx reg
+_INLINEF void CpuGetCr0(i32u x) {_ASM_BEGIN
+ mov eax, cr0
+ _ASM_END}
+
+_INLINEF void CpuSetCr0(i32u x) {_ASM_BEGIN
+ mov eax, x
+ mov cr0, eax
+ _ASM_END}
+#define CpuSetCr0_m(x) _ASM mov cr0, x
+
_INLINEF void CpuGetCr2(i32u x) {_ASM_BEGIN
mov eax, cr2
_ASM_END}
@@ -98,6 +109,27 @@
mov cr2, eax
_ASM_END}
#define CpuSetCr2_m(x) _ASM mov cr2, x
+
+_INLINEF void CpuGetCr3(i32u x) {_ASM_BEGIN
+ mov eax, cr3
+ _ASM_END}
+
+_INLINEF void CpuSetCr3(i32u x) {_ASM_BEGIN
+ mov eax, x
+ mov cr3, eax
+ _ASM_END}
+#define CpuSetCr3_m(x) _ASM mov cr3, x
+
+_INLINEF void CpuGetCr4(i32u x) {_ASM_BEGIN
+ // mov eax, cr4
+ CpuMovEaxCr4
+ _ASM_END}
+
+_INLINEF void CpuSetCr4(i32u x) {_ASM_BEGIN
+ mov eax, x
+ // mov cr4, eax
+ CpuMovCr4Eax
+ _ASM_END}
// get/set segment registers
_INLINEF i16u CpuGetCs(void) {_ASM_BEGIN
Modified: branches/jcatena-branch/include/reactos/msc/i386/platf.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/reactos/…
==============================================================================
--- branches/jcatena-branch/include/reactos/msc/i386/platf.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/reactos/msc/i386/platf.h [iso-8859-1] Thu Feb 4
13:05:14 2010
@@ -59,9 +59,9 @@
#define _SECTION_CONST(x) __pragma(const_seg(push, x))
#define _SECTION_CONST_END __pragma(const_seg(pop))
+#define _ASM __asm
#define _ASM_BEGIN __asm {
#define _ASM_END }
-#define _ASM __asm
#define IN
#define OUT
@@ -69,6 +69,9 @@
/*************************************************************************
utility macros
*************************************************************************/
+
+// note: double definitions necessary because preprocessor behavior
+
// token paste
#define tokenpaste_(a1, a2) a1##a2
#define tokenpaste(a1, a2) tokenpaste_(a1, a2)
@@ -78,7 +81,6 @@
#define sfy(x) sfy_(x)
// string literal macros
-// double definitions here are necessary because preprocessor behavior
#define T16(x) tokenpaste(L, x)
#define T8(x) x
#ifdef _UNICODE
Modified: branches/jcatena-branch/include/reactos/msc/intrin2.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/include/reactos/…
==============================================================================
--- branches/jcatena-branch/include/reactos/msc/intrin2.h [iso-8859-1] (original)
+++ branches/jcatena-branch/include/reactos/msc/intrin2.h [iso-8859-1] Thu Feb 4 13:05:14
2010
@@ -21,7 +21,7 @@
_INLINEF void _MemoryBarrier(void)
{
i32 Barrier;
- __asm xchg Barrier, eax
+ _ASM xchg Barrier, eax
}
i8u _interlockedbittestandset(long volatile *dest, long bit);
@@ -52,7 +52,6 @@
return (void *)_InterlockedCompareExchange((long volatile *)dest, (long)exch,
(long)comperand);
}
#endif
-#define InterlockedCompareExchangePointer _InterlockedCompareExchange
long _InterlockedExchange(volatile long * const Target, const long Value);
void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value);
Modified: branches/jcatena-branch/lib/cpu/i386/RegSave.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/lib/cpu/i386/Reg…
==============================================================================
--- branches/jcatena-branch/lib/cpu/i386/RegSave.c [iso-8859-1] (original)
+++ branches/jcatena-branch/lib/cpu/i386/RegSave.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -37,7 +37,7 @@
mov eax, cr3
mov CPUR_ALL.c.cr3[ebx], eax
// mov eax, cr4 // legal instruction not recognized, msc bug
- mov_eax_cr4
+ CpuMovEaxCr4
mov CPUR_ALL.c.cr4[ebx], eax
sgdt CPUR_ALL.c.gdtr.limit[ebx]
sidt CPUR_ALL.c.idtr.limit[ebx]
Modified: branches/jcatena-branch/lib/rtl/critical.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/lib/rtl/critical…
==============================================================================
--- branches/jcatena-branch/lib/rtl/critical.c [iso-8859-1] (original)
+++ branches/jcatena-branch/lib/rtl/critical.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -65,7 +65,7 @@
}
DPRINT("Created Event: %p \n", hNewEvent);
- if ((hEvent =
(HANDLE)_InterlockedCompareExchangePointer((PVOID*)&CriticalSection->LockSemaphore,
+ if ((hEvent =
(HANDLE)InterlockedCompareExchangePointer((PVOID*)&CriticalSection->LockSemaphore,
(PVOID)hNewEvent,
0))) {
@@ -604,7 +604,7 @@
RtlLeaveCriticalSection(PRTL_CRITICAL_SECTION CriticalSection)
{
#ifndef NDEBUG
- HANDLE Thread = (HANDLE)NtCurrentTeb()->Cid.UniqueThread;
+ HANDLE Thread = (HANDLE)NtCurrentTeb()->ClientId.UniqueThread;
/* In win this case isn't checked. However it's a valid check so it should
only
be performed in debug builds! */
Modified: branches/jcatena-branch/lib/rtl/timerqueue.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/lib/rtl/timerque…
==============================================================================
--- branches/jcatena-branch/lib/rtl/timerqueue.c [iso-8859-1] (original)
+++ branches/jcatena-branch/lib/rtl/timerqueue.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -372,7 +372,7 @@
NTSTATUS status = RtlCreateTimerQueue(&q);
if (status == STATUS_SUCCESS)
{
- PVOID p = _InterlockedCompareExchangePointer(
+ PVOID p = InterlockedCompareExchangePointer(
(void **) &default_timer_queue, q, NULL);
if (p)
/* Got beat to the punch. */
Modified: branches/jcatena-branch/ntoskrnl/ex/sysinfo.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ex/sysi…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ex/sysinfo.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -2023,19 +2023,8 @@
{
PAGED_CODE();
-#if defined(_M_IX86) || defined(_M_AMD64)
- __wbinvd();
-#elif defined(_M_PPC)
- __asm__ __volatile__("tlbsync");
-#elif defined(_M_MIPS)
- DPRINT1("NtFlushInstructionCache() is not implemented\n");
- for (;;);
-#elif defined(_M_ARM)
- __asm__ __volatile__("mov r1, #0; mcr p15, 0, r1, c7, c5, 0");
-#else
-#error Unknown architecture
-#endif
- return STATUS_SUCCESS;
+ CpuWbinvd();
+ return TRUE;
}
ULONG
Modified: branches/jcatena-branch/ntoskrnl/include/internal/i386/asmmacro.S
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/include…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1]
(original)
+++ branches/jcatena-branch/ntoskrnl/include/internal/i386/asmmacro.S [iso-8859-1] Thu Feb
4 13:05:14 2010
@@ -67,7 +67,7 @@
.macro idt Handler, Bits
.long \Handler
.short \Bits
- .short KGDT_R0_CODE
+// .short KGDT_R0_CODE
.endm
//
Modified: branches/jcatena-branch/ntoskrnl/include/internal/i386/ke.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/include…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/include/internal/i386/ke.h [iso-8859-1] Thu Feb 4
13:05:14 2010
@@ -461,9 +461,9 @@
// extern VOID __cdecl KiTrap02(VOID);
VOID DECLSPEC_NORETURN KiTrap02(VOID);
-extern VOID __cdecl KiTrap08(VOID);
-extern VOID __cdecl KiTrap13(VOID);
-extern VOID __cdecl KiFastCallEntry(VOID);
+// extern VOID __cdecl KiTrap08(VOID);
+// extern VOID __cdecl KiTrap13(VOID);
+// extern VOID __cdecl KiFastCallEntry(VOID);
extern VOID NTAPI ExpInterlockedPopEntrySListFault(VOID);
extern VOID __cdecl CopyParams(VOID);
extern VOID __cdecl ReadBatch(VOID);
@@ -475,7 +475,7 @@
//
// Trap Macros
//
-// #include "trap_x.h"
+#include "trap_x.h"
//
// Returns a thread's FPU save area
@@ -666,6 +666,40 @@
return Result;
}
+VOID
+FORCEINLINE
+KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame)
+{
+ PKTHREAD Thread;
+ KIRQL OldIrql;
+
+ /* Check for V8086 or user-mode trap */
+ if ((TrapFrame->EFlags & EFLAGS_V86_MASK) || (KiUserTrap(TrapFrame)))
+ {
+ /* Get the thread */
+ Thread = KeGetCurrentThread();
+ while (TRUE)
+ {
+ /* Turn off the alerted state for kernel mode */
+ Thread->Alerted[KernelMode] = FALSE;
+
+ /* Are there pending user APCs? */
+ if (!Thread->ApcState.UserApcPending) break;
+
+ /* Raise to APC level and enable interrupts */
+ OldIrql = KfRaiseIrql(APC_LEVEL);
+ _enable();
+
+ /* Deliver APCs */
+ KiDeliverApc(UserMode, NULL, TrapFrame);
+
+ /* Restore IRQL and disable interrupts once again */
+ KfLowerIrql(OldIrql);
+ _disable();
+ }
+ }
+}
+
NTSTATUS NTAPI PsConvertToGuiThread(VOID);
//
Modified: branches/jcatena-branch/ntoskrnl/include/internal/ke.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/include…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/include/internal/ke.h [iso-8859-1] Thu Feb 4
13:05:14 2010
@@ -140,7 +140,6 @@
extern PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch;
extern ULONGLONG BootCycles, BootCyclesEnd;
extern ULONG ProcessCount;
-extern VOID __cdecl KiInterruptTemplate(VOID);
/* MACROS *************************************************************************/
Modified: branches/jcatena-branch/ntoskrnl/include/internal/trap_x.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/include…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/include/internal/trap_x.h [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Thu Feb 4
13:05:14 2010
@@ -4,9 +4,48 @@
* FILE: ntoskrnl/include/trap_x.h
* PURPOSE: Internal Inlined Functions for the Trap Handling Code
* PROGRAMMERS: ReactOS Portable Systems Group
+ !!! this is horrible. Portable? LOL
+ TODO:
+ - use macros whenever possible instead of inline assembly
+ - create needed asm macros in <arch>\<include>, not here
+ - avoid unnecessary conditional jumps by generating the right prolog
+ and epilogs for each trap type
+ - fix dependency of stack frame optimization
*/
+
#ifndef _TRAP_X_
#define _TRAP_X_
+
+#include <debug.h>
+
+// !!! temp for testing
+extern KINTERRUPT *TrapStubInterrupt;
+
+VOID KiFastCallEntry(VOID);
+VOID KiTrap08(VOID);
+VOID KiTrap13(VOID);
+
+
+VOID
+// DECLSPEC_NORETURN
+FASTCALL
+KiServiceExit(IN PKTRAP_FRAME TrapFrame,
+ IN NTSTATUS Status);
+
+VOID
+// DECLSPEC_NORETURN
+FASTCALL
+KiServiceExit2(IN PKTRAP_FRAME TrapFrame);
+
+VOID
+_NORETURN
+_FASTCALL
+KiSystemServiceHandler(IN PKTRAP_FRAME TrapFrame);
+
+VOID
+_NORETURN
+_FASTCALL
+KiFastCallEntryHandler(IN PKTRAP_FRAME TrapFrame);
//
// Debug Macros
@@ -68,7 +107,7 @@
VOID
FORCEINLINE
KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame,
- IN KTRAP_STATE_BITS SkipBits)
+ IN KTRAP_EXIT_SKIP_BITS SkipBits)
{
/* Make sure interrupts are disabled */
if (__readeflags() & EFLAGS_INTERRUPT_MASK)
@@ -122,14 +161,14 @@
KIRQL OldIrql;
/* Check if this was a user call */
- if (KiUserMode(TrapFrame))
+ if (TrapFrame->SegCs & MODE_MASK)
{
/* Make sure we are not returning with elevated IRQL */
OldIrql = KeGetCurrentIrql();
if (OldIrql != PASSIVE_LEVEL)
{
/* Forcibly put us in a sane state */
- KeGetPcr()->CurrentIrql = PASSIVE_LEVEL;
+ KeGetPcr()->Irql = PASSIVE_LEVEL;
_disable();
/* Fail */
@@ -175,7 +214,7 @@
//
VOID
FORCEINLINE
-DECLSPEC_NORETURN
+// DECLSPEC_NORETURN /* Do not mark this as DECLSPEC_NORETURN because possibly executing
code follows it! */
KiSystemCallReturn(IN PKTRAP_FRAME TrapFrame)
{
/* Restore nonvolatiles, EAX, and do a "jump" back to the kernel caller */
@@ -203,6 +242,7 @@
"movl %c[e](%%esp), %%edx\n"
"addl $%c[v],%%esp\n" /* A WHOLE *KERNEL* frame since we're not
IRET'ing */
"jmp *%%edx\n"
+ ".globl _KiSystemCallExit2\n_KiSystemCallExit2:\n"
:
: "r"(TrapFrame),
[b] "i"(KTRAP_FRAME_EBX),
@@ -221,8 +261,8 @@
}
VOID
-FORCEINLINE
DECLSPEC_NORETURN
+FORCEINLINE
KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame)
{
/* Regular interrupt exit, but we only restore EAX as a volatile */
@@ -235,12 +275,13 @@
mov ebp, [esp+KTRAP_FRAME_EBP]
mov eax, [esp+KTRAP_FRAME_EAX]
add esp, KTRAP_FRAME_EIP
- iret
+ iretd
_ASM_END
#elif defined(__GNUC__)
__asm__ __volatile__
(
- "movl %0, %%esp\n"
+ ".globl _KiSystemCallExit\n_KiSystemCallExit:\n"
+ "movl %0, %%esp\n"
"movl %c[b](%%esp), %%ebx\n"
"movl %c[s](%%esp), %%esi\n"
"movl %c[i](%%esp), %%edi\n"
@@ -282,7 +323,7 @@
mov ecx, [esp+KTRAP_FRAME_ESP]
add esp, KTRAP_FRAME_V86_ES
sti
- sysexit
+ CpuSysExit
_ASM_END
#elif defined(__GNUC__)
__asm__ __volatile__
@@ -332,7 +373,7 @@
mov edi, [esp+KTRAP_FRAME_EDI]
mov ebp, [esp+KTRAP_FRAME_EBP]
add esp, KTRAP_FRAME_EIP
- iret
+ iretd
_ASM_END
#elif defined(__GNUC__)
__asm__ __volatile__
@@ -368,6 +409,76 @@
VOID
FORCEINLINE
DECLSPEC_NORETURN
+KiDirectTrapReturn(IN PKTRAP_FRAME TrapFrame)
+{
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ mov esp, TrapFrame
+ add esp, KTRAP_FRAME_EIP
+ iretd
+ _ASM_END
+#elif defined(__GNUC__)
+ /* Regular interrupt exit but we're not restoring any registers */
+ __asm__ __volatile__
+ (
+ "movl %0, %%esp\n"
+ "addl $%c[e],%%esp\n"
+ "iret\n"
+ :
+ : "r"(TrapFrame),
+ [e] "i"(KTRAP_FRAME_EIP)
+ : "%esp"
+ );
+#elif
+#error unsupported compiler
+#endif
+ UNREACHABLE;
+}
+
+VOID
+FORCEINLINE
+DECLSPEC_NORETURN
+KiCallReturn(IN PKTRAP_FRAME TrapFrame)
+{
+ /* Pops a trap frame out of the stack but returns with RET instead of IRET */
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ mov esp, TrapFrame
+ mov ebx, [esp+KTRAP_FRAME_EBX]
+ mov esi, [esp+KTRAP_FRAME_ESI]
+ mov edi, [esp+KTRAP_FRAME_EDI]
+ mov ebp, [esp+KTRAP_FRAME_EBP]
+ add esp, KTRAP_FRAME_EIP
+ ret
+ _ASM_END
+#elif defined(__GNUC__)
+ __asm__ __volatile__
+ (
+ "movl %0, %%esp\n"
+ "movl %c[b](%%esp), %%ebx\n"
+ "movl %c[s](%%esp), %%esi\n"
+ "movl %c[i](%%esp), %%edi\n"
+ "movl %c[p](%%esp), %%ebp\n"
+ "addl $%c[e],%%esp\n"
+ "ret\n"
+ :
+ : "r"(TrapFrame),
+ [b] "i"(KTRAP_FRAME_EBX),
+ [s] "i"(KTRAP_FRAME_ESI),
+ [i] "i"(KTRAP_FRAME_EDI),
+ [p] "i"(KTRAP_FRAME_EBP),
+ [e] "i"(KTRAP_FRAME_EIP)
+ : "%esp"
+ );
+#elif
+#error unsupported compiler
+#endif
+ UNREACHABLE;
+}
+
+VOID
+FORCEINLINE
+DECLSPEC_NORETURN
KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame)
{
/* Regular interrupt exit */
@@ -382,7 +493,7 @@
mov edi, [esp+KTRAP_FRAME_EDI]
mov ebp, [esp+KTRAP_FRAME_EBP]
add esp, KTRAP_FRAME_ERROR_CODE /* We *WANT* the error code since ESP is there! */
- iret
+ iretd
_ASM_END
#elif defined(__GNUC__)
__asm__ __volatile__
@@ -417,14 +528,135 @@
}
//
+// "BOP" code used by VDM and V8086 Mode
+//
+VOID
+FORCEINLINE
+KiIssueBop(VOID)
+{
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ _emit 0xc4
+ _emit 0xc4
+ _ASM_END
+#elif defined(__GNUC__)
+ /* Invalid instruction that an invalid opcode handler must trap and handle */
+ asm volatile(".byte 0xC4\n.byte 0xC4\n");
+#elif
+#error unsupported compiler
+#endif
+}
+
+//
+// Returns whether or not this is a V86 trap by checking the EFLAGS field.
+//
+// FIXME: GCC 4.5 Can Improve this with "goto labels"
+//
+BOOLEAN
+FORCEINLINE
+KiIsV8086TrapSafe(IN PKTRAP_FRAME TrapFrame)
+{
+ BOOLEAN Result;
+
+ /*
+ * The check MUST be done this way, as we guarantee that no DS/ES/FS segment
+ * is used (since it might be garbage).
+ *
+ * Instead, we use the SS segment which is guaranteed to be correct. Because
+ * operate in 32-bit flat mode, this works just fine.
+ */
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ test ss:[TrapFrame+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
+ setnz Result
+ _ASM_END
+#elif defined(__GNUC__)
+ asm volatile
+ (
+ "testl $%c[f], %%ss:%1\n"
+ "setnz %0\n"
+ : "=a"(Result)
+ : "m"(TrapFrame->EFlags),
+ [f] "i"(EFLAGS_V86_MASK)
+ );
+#elif
+#error unsupported compiler
+#endif
+
+ /* If V86 flag was set */
+ return Result;
+}
+
+//
+// Returns whether or not this is a user-mode trap by checking the SegCs field.
+//
+// FIXME: GCC 4.5 Can Improve this with "goto labels"
+//
+BOOLEAN
+FORCEINLINE
+KiIsUserTrapSafe(IN PKTRAP_FRAME TrapFrame)
+{
+ BOOLEAN Result;
+
+ /*
+ * The check MUST be done this way, as we guarantee that no DS/ES/FS segment
+ * is used (since it might be garbage).
+ *
+ * Instead, we use the SS segment which is guaranteed to be correct. Because
+ * operate in 32-bit flat mode, this works just fine.
+ */
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ cmp ss:[TrapFrame+KTRAP_FRAME_CS], KGDT_R0_CODE
+ setnz Result
+ _ASM_END
+#elif defined(__GNUC__)
+ asm volatile
+ (
+ "cmp $%c[f], %%ss:%1\n"
+ "setnz %0\n"
+ : "=a"(Result)
+ : "m"(TrapFrame->SegCs),
+ [f] "i"(KGDT_R0_CODE)
+ );
+#elif
+#error unsupported compiler
+#endif
+
+ /* If V86 flag was set */
+ return Result;
+}
+
+VOID
+FORCEINLINE
+KiUserSystemCall(IN PKTRAP_FRAME TrapFrame)
+{
+ /*
+ * Kernel call or user call?
+ *
+ * This decision is made in inlined assembly because we need to patch
+ * the relative offset of the user-mode jump to point to the SYSEXIT
+ * routine if the CPU supports it. The only way to guarantee that a
+ * relative jnz/jz instruction is generated is to force it with the
+ * inline assembler.
+ */
+ // !!!
+ DPRINT1("!!!FIX\n");
+#if 0
+ if (TrapFrame->SegCs & 1)
+ KiSystemCallExit(TrapFrame);
+#endif
+}
+
+//
// Generic Exit Routine
//
VOID
FORCEINLINE
-DECLSPEC_NORETURN
KiExitTrap(IN PKTRAP_FRAME TrapFrame,
IN UCHAR Skip)
{
+ // KTRAP_EXIT_SKIP_BITS SkipBits = { .Bits = Skip };
KTRAP_EXIT_SKIP_BITS SkipBits;
PULONG ReturnStack;
@@ -440,7 +672,7 @@
if (__builtin_expect(!SkipBits.SkipPreviousMode, 0)) /* More INTS than SYSCALLs */
{
/* Restore it */
- KeGetCurrentThread()->PreviousMode = TrapFrame->PreviousPreviousMode;
+ KeGetCurrentThread()->PreviousMode =
(CCHAR)TrapFrame->PreviousPreviousMode;
}
/* Check if there are active debug registers */
@@ -515,19 +747,19 @@
/* Check for system call -- a system call skips volatiles! */
if (__builtin_expect(SkipBits.SkipVolatiles, 0)) /* More INTs than SYSCALLs */
{
- /* Kernel call or user call? */
- if (__builtin_expect(KiUserTrap(TrapFrame), 1)) /* More Ring 3 than 0 */
+ /* User or kernel call? */
+ KiUserSystemCall(TrapFrame);
+
+ /* Restore EFLags */
+ __writeeflags(TrapFrame->EFlags);
+
+ /* Call is kernel, so do a jump back since this wasn't a real INT */
+ KiSystemCallReturn(TrapFrame);
+
+ /* If we got here, this is SYSEXIT: are we stepping code? */
+ if (!(TrapFrame->EFlags & EFLAGS_TF))
{
- /* Is SYSENTER supported and/or enabled, or are we stepping code? */
- if (__builtin_expect((KiFastSystemCallDisable) ||
- (TrapFrame->EFlags & EFLAGS_TF), 0))
- {
- /* Exit normally */
- KiSystemCallTrapReturn(TrapFrame);
- }
- else
- {
- /* Restore user FS */
+ /* Restore user FS */
Ke386SetFs(KGDT_R3_TEB | RPL_MASK);
/* Remove interrupt flag */
@@ -537,21 +769,13 @@
/* Exit through SYSEXIT */
KiSystemCallSysExitReturn(TrapFrame);
}
- }
- else
- {
- /* Restore EFLags */
- __writeeflags(TrapFrame->EFlags);
- /* Call is kernel, so do a jump back since this wasn't a real INT */
- KiSystemCallReturn(TrapFrame);
- }
- }
- else
- {
- /* Return from interrupt */
- KiTrapReturn(TrapFrame);
- }
+ /* Exit through IRETD, either due to debugging or due to lack of SYSEXIT */
+ KiSystemCallTrapReturn(TrapFrame);
+ }
+
+ /* Return from interrupt */
+ KiTrapReturn(TrapFrame);
}
//
@@ -613,8 +837,7 @@
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
- /* Save exception list and bogus previous mode */
- TrapFrame->PreviousPreviousMode = -1;
+ /* Save exception list */
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
/* Clear direction flag */
@@ -636,36 +859,44 @@
FORCEINLINE
KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame)
{
- /* Set bogus previous mode */
- TrapFrame->PreviousPreviousMode = -1;
-
- /* Check for V86 mode */
- if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
- {
- DbgPrint("Need V8086 Interrupt Support!\n");
- while (TRUE);
- }
-
- /* Check if this wasn't kernel code */
- if (__builtin_expect(TrapFrame->SegCs != KGDT_R0_CODE, 1)) /* Ring 3 is more
common */
- {
- /* Save segments and then switch to correct ones */
+ ULONG Ds, Es;
+
+ /* Check for V86 mode, otherwise check for ring 3 code */
+ if (__builtin_expect(KiIsV8086TrapSafe(TrapFrame), 0))
+ {
+ /* Set correct segments */
+ Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
+ Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
+ Ke386SetFs(KGDT_R0_PCR);
+
+ /* Restore V8086 segments into Protected Mode segments */
+ TrapFrame->SegFs = TrapFrame->V86Fs;
+ TrapFrame->SegGs = TrapFrame->V86Gs;
+ TrapFrame->SegDs = TrapFrame->V86Ds;
+ TrapFrame->SegEs = TrapFrame->V86Es;
+ }
+ else if (__builtin_expect(KiIsUserTrapSafe(TrapFrame), 1)) /* Ring 3 is more common
*/
+ {
+ /* Save DS/ES and load correct values */
+ Es = Ke386GetEs();
+ Ds = Ke386GetDs();
+ TrapFrame->SegDs = Ds;
+ TrapFrame->SegEs = Es;
+ Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
+ Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
+
+ /* Save FS/GS */
TrapFrame->SegFs = Ke386GetFs();
TrapFrame->SegGs = Ke386GetGs();
- TrapFrame->SegDs = Ke386GetDs();
- TrapFrame->SegEs = Ke386GetEs();
+
+ /* Set correct FS */
Ke386SetFs(KGDT_R0_PCR);
- Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
- Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
- }
+ }
/* Save exception list and terminate it */
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
KeGetPcr()->Tib.ExceptionList = EXCEPTION_CHAIN_END;
-
- /* No error code */
- TrapFrame->ErrCode = 0;
-
+
/* Clear direction flag */
Ke386ClearDirectionFlag();
@@ -688,7 +919,7 @@
FORCEINLINE
KiEnterTrap(IN PKTRAP_FRAME TrapFrame)
{
- ULONG Ds, Es;
+ USHORT Ds, Es;
/*
* We really have to get a good DS/ES first before touching any data.
@@ -700,7 +931,8 @@
* as-is, otherwise the optimizer could simply get rid of our DS/ES.
*
*/
- Ds = Ke386GetDs();
+ // !!!
+ Ds = Ke386GetDs();
Es = Ke386GetEs();
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
@@ -712,8 +944,7 @@
TrapFrame->SegGs = Ke386GetGs();
Ke386SetFs(KGDT_R0_PCR);
- /* Save exception list and bogus previous mode */
- TrapFrame->PreviousPreviousMode = -1;
+ /* Save exception list */
TrapFrame->ExceptionList = KeGetPcr()->Tib.ExceptionList;
/* Check for V86 mode */
@@ -740,4 +971,198 @@
/* Set debug header */
KiFillTrapFrameDebug(TrapFrame);
}
-#endif
+
+//
+// Generates a Trap Prolog Stub for the given name
+//
+#define KI_PUSH_FAKE_ERROR_CODE 0x1
+#define KI_UNUSED 0x2
+#define KI_NONVOLATILES_ONLY 0x4
+#define KI_FAST_SYSTEM_CALL 0x8
+#define KI_SOFTWARE_TRAP 0x10
+#define KI_HARDWARE_INT 0x20
+#define KiTrap(x, y) VOID x(VOID) { KiTrapStub(y, (PVOID)x##Handler);
UNREACHABLE; }
+#define KiTrampoline(x, y) VOID x(VOID) { KiTrapStub(y, x##Handler); }
+
+//
+// Trap Prolog Stub
+// !!! ultrahorrible
+//
+VOID
+FORCEINLINE
+KiTrapStub(IN ULONG Flags,
+ IN PVOID Handler)
+{
+ ULONG FrameSize;
+
+ /* Is this a fast system call? They don't have a stack! */
+ if (Flags & KI_FAST_SYSTEM_CALL)
+ {
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ mov esp, ss:[KIP0PCRADDRESS + offset KPCR.TSS]
+ mov esp, KTSS.Esp0[esp]
+ _ASM_END
+#elif defined(__GNUC__)
+ __asm__ __volatile__
+ (
+ "movl %%ss:%c[t], %%esp\n"
+ "movl %c[e](%%esp), %%esp\n"
+ :
+ : [e] "i"(FIELD_OFFSET(KTSS, Esp0)),
+ [t] "i"(&PCR->TSS)
+ : "%esp"
+ );
+#elif
+#error unsupported compiler
+#endif
+ }
+
+ /* Check what kind of trap frame this trap requires */
+ if (Flags & KI_SOFTWARE_TRAP)
+ {
+ /* Software traps need a complete non-ring transition trap frame */
+ FrameSize = FIELD_OFFSET(KTRAP_FRAME, HardwareEsp);
+ }
+ else if (Flags & KI_FAST_SYSTEM_CALL)
+ {
+ /* SYSENTER requires us to build a complete ring transition trap frame */
+ FrameSize = FIELD_OFFSET(KTRAP_FRAME, V86Es);
+
+ /* And it only preserves nonvolatile registers */
+ Flags |= KI_NONVOLATILES_ONLY;
+ }
+ else if (Flags & KI_PUSH_FAKE_ERROR_CODE)
+ {
+ /* If the trap doesn't have an error code, we'll make space for it */
+ FrameSize = FIELD_OFFSET(KTRAP_FRAME, Eip);
+ }
+ else
+ {
+ /* The trap already has an error code, so just make space for the rest */
+ FrameSize = FIELD_OFFSET(KTRAP_FRAME, ErrCode);
+ }
+
+ /* Software traps need to get their EIP from the caller's frame */
+ if (Flags & KI_SOFTWARE_TRAP)
+ {
+#if defined(_MSC_VER)
+ _ASM pop eax
+#elif defined(__GNUC)
+ __asm__ __volatile__ ("popl %%eax\n":::"%esp");
+#elif
+#error unsupported compiler
+#endif
+ }
+ /* Save nonvolatile registers */
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ mov KTRAP_FRAME.Ebp[esp], ebp
+ mov KTRAP_FRAME.Ebx[esp], ebx
+ mov KTRAP_FRAME.Esi[esp], esi
+ mov KTRAP_FRAME.Edi[esp], edi
+ _ASM_END
+#elif defined(__GNUC)
+ __asm__ __volatile__
+ (
+ /* EBX, ESI, EDI and EBP are saved */
+ "movl %%ebp, %c[p](%%esp)\n"
+ "movl %%ebx, %c[b](%%esp)\n"
+ "movl %%esi, %c[s](%%esp)\n"
+ "movl %%edi, %c[i](%%esp)\n"
+ :
+ : [b] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Ebx)),
+ [s] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Esi)),
+ [i] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Edi)),
+ [p] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Ebp))
+ : "%esp"
+ );
+#elif
+#error unsupported compiler
+#endif
+
+ /* Does the caller want nonvolatiles only? */
+ if (!(Flags & KI_NONVOLATILES_ONLY))
+ {
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ mov KTRAP_FRAME.Eax[esp], eax
+ mov KTRAP_FRAME.Ecx[esp], ecx
+ mov KTRAP_FRAME.Edx[esp], eax
+ _ASM_END
+#elif defined(__GNUC)
+ __asm__ __volatile__
+ (
+ /* Otherwise, save the volatiles as well */
+ "movl %%eax, %c[a](%%esp)\n"
+ "movl %%ecx, %c[c](%%esp)\n"
+ "movl %%edx, %c[d](%%esp)\n"
+ :
+ : [a] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Eax)),
+ [c] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Ecx)),
+ [d] "i"(- FrameSize + FIELD_OFFSET(KTRAP_FRAME, Edx))
+ : "%esp"
+ );
+#elif
+#error unsupported compiler
+#endif
+ }
+ /* Now set parameter 1 (ECX) to point to the frame */
+ /* make space for this frame */
+#if defined(_MSC_VER)
+ _ASM_BEGIN
+ sub esp, FrameSize
+ mov ecx, esp
+ _ASM_END
+ // !!! this is horrible and won't work after stkf optimization
+#elif defined(__GNUC)
+ __asm__ __volatile__ ("movl %%esp, %%ecx\n":::"%esp");
+ __asm__ __volatile__ ("subl $%c[e],%%esp\n":: [e] "i"(FrameSize)
: "%esp");
+ __asm__ __volatile__ ("subl $%c[e],%%ecx\n":: [e] "i"(FrameSize)
: "%ecx");
+#elif
+#error unsupported compiler
+#endif
+
+ /* Now jump to the C handler */
+
+ /*
+ * For hardware interrupts, set parameter 2 (EDX) to hold KINTERRUPT.
+ * This code will be dynamically patched when an interrupt is registered!
+ !!! ultrahorrible
+ */
+ if (Flags & KI_HARDWARE_INT)
+ {
+#if defined(_MSC_VER)
+ // !!! temp hack
+ _ASM_BEGIN
+ mov edx, [TrapStubInterrupt]
+ jmp [Handler]
+ _ASM_END
+#elif defined(__GNUC)
+ __asm__ __volatile__
+ (
+ ".globl
_KiInterruptTemplate2ndDispatch\n_KiInterruptTemplate2ndDispatch:\n"
+ "movl $0, %%edx\n"
+ ".globl _KiInterruptTemplateObject\n_KiInterruptTemplateObject:\n"
+ ::: "%edx"
+ "jmp *%0\n"
+ ".globl _KiInterruptTemplateDispatch\n_KiInterruptTemplateDispatch:\n"
+ :
+ : "a"(Handler)
+
+ );
+#elif
+#error unsupported compiler
+#endif
+ }
+
+#if defined(_MSC_VER)
+ _ASM jmp [Handler]
+#elif defined(__GNUC)
+ else __asm__ __volatile__ ("jmp %c[x]\n":: [x] "i"(Handler));
+#elif
+#error unsupported compiler
+#endif
+}
+
+#endif
Modified: branches/jcatena-branch/ntoskrnl/include/ntoskrnl_bld.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/include…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/include/ntoskrnl_bld.h [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/include/ntoskrnl_bld.h [iso-8859-1] Thu Feb 4
13:05:14 2010
@@ -42,6 +42,11 @@
#include <reactos_cfg.h>
#include <cpu.h>
+// !!! temp disable some warnings
+_NOWARN_MSC(4244) // ULONG to USHORT
+_NOWARN_MSC(4018) // ULONG to USHORT
+
+
#include <ntverp.h>
/* DDK/IFS/NDK Headers */
@@ -70,6 +75,7 @@
#include <ctype.h>
#include <malloc.h>
#include <wchar.h>
+#include <intrin2.h>
/* SEH support with PSEH */
#include <pseh/pseh2.h>
Modified: branches/jcatena-branch/ntoskrnl/kdbg/kdb.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/kdbg/kd…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/kdbg/kdb.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/kdbg/kdb.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -140,42 +140,15 @@
PKTRAP_FRAME TrapFrame,
PKDB_KTRAP_FRAME KdbTrapFrame)
{
- ULONG TrapCr0, TrapCr2, TrapCr3, TrapCr4;
-
/* Copy the TrapFrame only up to Eflags and zero the rest*/
RtlCopyMemory(&KdbTrapFrame->Tf, TrapFrame, FIELD_OFFSET(KTRAP_FRAME,
HardwareEsp));
RtlZeroMemory((PVOID)((ULONG_PTR)&KdbTrapFrame->Tf + FIELD_OFFSET(KTRAP_FRAME,
HardwareEsp)),
sizeof(KTRAP_FRAME) - FIELD_OFFSET(KTRAP_FRAME, HardwareEsp));
-#ifndef _MSC_VER
- asm volatile(
- "movl %%cr0, %0" "\n\t"
- "movl %%cr2, %1" "\n\t"
- "movl %%cr3, %2" "\n\t"
- "movl %%cr4, %3" "\n\t"
- : "=r"(TrapCr0), "=r"(TrapCr2),
- "=r"(TrapCr3), "=r"(TrapCr4));
-#else
- __asm
- {
- mov eax, cr0;
- mov TrapCr0, eax;
-
- mov eax, cr2;
- mov TrapCr2, eax;
-
- mov eax, cr3;
- mov TrapCr3, eax;
-/* FIXME: What's the problem with cr4? */
- //mov eax, cr4;
- //mov TrapCr4, eax;
- }
-#endif
-
- KdbTrapFrame->Cr0 = TrapCr0;
- KdbTrapFrame->Cr2 = TrapCr2;
- KdbTrapFrame->Cr3 = TrapCr3;
- KdbTrapFrame->Cr4 = TrapCr4;
+ KdbTrapFrame->Cr0 = CpuGetCr0();
+ KdbTrapFrame->Cr2 = CpuGetCr2();
+ KdbTrapFrame->Cr3 = CpuGetCr3();
+ KdbTrapFrame->Cr4 = CpuGetCr4();
KdbTrapFrame->Tf.HardwareEsp = KiEspFromTrapFrame(TrapFrame);
KdbTrapFrame->Tf.HardwareSegSs = (USHORT)(KiSsFromTrapFrame(TrapFrame) &
0xFFFF);
Modified: branches/jcatena-branch/ntoskrnl/ke/i386/cpu.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ke/i386…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ke/i386/cpu.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ke/i386/cpu.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -999,6 +999,7 @@
NTAPI
KiDisableFastSyscallReturn(VOID)
{
+#if 0
/* Was it applied? */
if (KiSystemCallExitAdjusted)
{
@@ -1008,13 +1009,15 @@
/* It's not adjusted anymore */
KiSystemCallExitAdjusted = FALSE;
}
+#endif
}
VOID
NTAPI
KiEnableFastSyscallReturn(VOID)
{
- /* Check if the patch has already been done */
+#if 0
+ /* Check if the patch has already been done */
if ((KiSystemCallExitAdjusted == KiSystemCallExitAdjust) &&
(KiFastCallCopyDoneOnce))
{
@@ -1043,13 +1046,15 @@
DPRINT1("Your compiled kernel is broken!\n");
DbgBreakPoint();
}
+#endif
}
VOID
NTAPI
KiRestoreFastSyscallReturnState(VOID)
{
- /* Check if the CPU Supports fast system call */
+#if 0
+ /* Check if the CPU Supports fast system call */
if (KeFeatureBits & KF_FAST_SYSCALL)
{
/* Check if it has been disabled */
@@ -1077,6 +1082,7 @@
/* Perform the code patch that is required */
KiEnableFastSyscallReturn();
+#endif
}
ULONG_PTR
@@ -1224,8 +1230,9 @@
Cr0 = __readcr0() & ~(CR0_MP | CR0_TS | CR0_EM | CR0_ET);
/* Store on FPU stack */
- asm volatile ("fninit;" "fnstsw %0" : "+m"(Magic));
-
+ CpuFninit();
+ CpuFnGetSw_m(Magic);
+
/* Magic should now be cleared */
if (Magic & 0xFF)
{
@@ -1261,7 +1268,7 @@
__writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
/* Initialize FPU state */
- asm volatile ("fninit");
+ CpuFninit();
/* Multiply the magic values and divide, we should get the result back */
Value1 = 4195835.0;
@@ -1278,8 +1285,8 @@
return ErrataPresent;
}
-NTAPI
-VOID
+VOID
+NTAPI
KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
{
ULONG EFlags, Cr0;
@@ -1396,14 +1403,7 @@
if (!FpState) return STATUS_INSUFFICIENT_RESOURCES;
*((PVOID *) Save) = FpState;
-#ifdef __GNUC__
- asm volatile("fnsave %0\n\t" : "=m" (*FpState));
-#else
- __asm
- {
- fnsave [FpState]
- };
-#endif
+ CpuFnsave(FpState);
KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql();
return STATUS_SUCCESS;
@@ -1420,16 +1420,8 @@
ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql());
DPRINT1("%s is not really implemented\n", __FUNCTION__);
-#ifdef __GNUC__
- asm volatile("fnclex\n\t");
- asm volatile("frstor %0\n\t" : "=m" (*FpState));
-#else
- __asm
- {
- fnclex
- frstor [FpState]
- };
-#endif
+ CpuFnclex();
+ CpuFrstor(FpState);
ExFreePool(FpState);
return STATUS_SUCCESS;
Modified: branches/jcatena-branch/ntoskrnl/ke/i386/exp.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ke/i386…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ke/i386/exp.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ke/i386/exp.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -1107,7 +1107,6 @@
VOID
NTAPI
-DECLSPEC_NORETURN
KiDispatchExceptionFromTrapFrame(IN NTSTATUS Code,
IN ULONG_PTR Address,
IN ULONG ParameterCount,
@@ -1145,8 +1144,8 @@
}
VOID
+_NORETURN
FASTCALL
-DECLSPEC_NORETURN
KiSystemFatalException(IN ULONG ExceptionCode,
IN PKTRAP_FRAME TrapFrame)
{
Modified: branches/jcatena-branch/ntoskrnl/ke/i386/irqobj.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ke/i386…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ke/i386/irqobj.c [iso-8859-1] Thu Feb 4 13:05:14
2010
@@ -368,13 +368,16 @@
*DispatchCode++ = ((PULONG)KiInterruptTemplate)[i];
}
- /* Jump to the last 4 bytes */
+#if 0
+ /* Jump to the last 4 bytes */
Patch = (PULONG)((ULONG_PTR)Patch +
((ULONG_PTR)&KiInterruptTemplateObject -
(ULONG_PTR)KiInterruptTemplate) - 4);
/* Apply the patch */
*Patch = PtrToUlong(Interrupt);
+#endif
+ TrapStubInterrupt = Interrupt;
/* Disconnect it at first */
Interrupt->Connected = FALSE;
Modified: branches/jcatena-branch/ntoskrnl/ke/i386/kiinit.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ke/i386…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ke/i386/kiinit.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ke/i386/kiinit.c [iso-8859-1] Thu Feb 4 13:05:14
2010
@@ -11,7 +11,7 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <debug.h>
-#include "trap_x.h"
+// #include "trap_x.h"
/* GLOBALS *******************************************************************/
@@ -271,12 +271,9 @@
FxSaveArea->U.FxArea.MXCsrMask = 0;
/* Save the current NPX State */
-#ifdef __GNUC__
- asm volatile("fxsave %0\n\t" : "=m" (*FxSaveArea));
-#else
- __asm fxsave [FxSaveArea]
-#endif
- /* Check if the current mask doesn't match the reserved bits */
+ CpuFxsave(FxSaveArea);
+
+ /* Check if the current mask doesn't match the reserved bits */
if (FxSaveArea->U.FxArea.MXCsrMask != 0)
{
/* Then use whatever it's holding */
Modified: branches/jcatena-branch/ntoskrnl/ke/i386/traphdlr.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ke/i386…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Thu Feb 4 13:05:14
2010
@@ -13,6 +13,9 @@
#include <debug.h>
/* GLOBALS ********************************************************************/
+
+// !!! temp for testing
+KINTERRUPT *TrapStubInterrupt;
UCHAR KiTrapPrefixTable[] =
{
@@ -57,7 +60,7 @@
/* TRAP EXIT CODE *************************************************************/
VOID
-DECLSPEC_NORETURN
+// DECLSPEC_NORETURN
FASTCALL
KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
{
@@ -72,10 +75,9 @@
}
VOID
-DECLSPEC_NORETURN
-FASTCALL
-KiServiceExit(IN PKTRAP_FRAME TrapFrame,
- IN NTSTATUS Status)
+// DECLSPEC_NORETURN7
+FASTCALL
+KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status)
{
/* Disable interrupts until we return */
_disable();
@@ -91,7 +93,7 @@
}
VOID
-DECLSPEC_NORETURN
+// DECLSPEC_NORETURN
FASTCALL
KiServiceExit2(IN PKTRAP_FRAME TrapFrame)
{
@@ -1039,8 +1041,8 @@
/* So since we're not dealing with the above case, check for RDMSR/WRMSR */
if ((Instructions[0] == 0xF) && // 2-byte opcode
- (((Instructions[1] >> 8) == 0x30) || // RDMSR
- ((Instructions[2] >> 8) == 0x32))) // WRMSR
+ (((Instructions[1]) == 0x30) || // RDMSR
+ ((Instructions[2]) == 0x32))) // WRMSR
{
/* Unknown CPU MSR, so raise an access violation */
KiDispatchException0Args(STATUS_ACCESS_VIOLATION,
@@ -1501,7 +1503,6 @@
KiSystemCall(ServiceNumber, Arguments);
}
-#if 0
// was __attribute__((regparm(3)))
VOID
_NORETURN
@@ -1540,9 +1541,7 @@
Thread->PreviousMode,
KGDT_R3_TEB | RPL_MASK);
}
-#endif
-
-#if 0
+
// was __attribute__((regparm(3)))
VOID
_NORETURN
@@ -1576,7 +1575,6 @@
Thread->PreviousMode,
SegFs);
}
-#endif
/* CPU AND SOFTWARE TRAPS *****************************************************/
Modified: branches/jcatena-branch/ntoskrnl/ke/ke.vcproj
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ke/ke.v…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ke/ke.vcproj [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ke/ke.vcproj [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -195,6 +195,10 @@
</File>
<File
+ RelativePath=".\except.c"
+ >
+ </File>
+ <File
RelativePath="freeldr.c"
</File>
@@ -248,6 +252,10 @@
</File>
<File
RelativePath="thrdschd.c"
+ >
+ </File>
+ <File
+ RelativePath=".\time.c"
</File>
<File
@@ -278,6 +286,10 @@
</File>
<File
+ RelativePath=".\i386\exp.c"
+ >
+ </File>
+ <File
RelativePath=".\i386\irqobj.c"
</File>
@@ -302,7 +314,23 @@
</File>
<File
+ RelativePath=".\i386\trap.s"
+ >
+ </File>
+ <File
+ RelativePath=".\i386\traphdlr.c"
+ >
+ </File>
+ <File
RelativePath=".\i386\usercall.c"
+ >
+ </File>
+ <File
+ RelativePath=".\i386\usercall_asm.S"
+ >
+ </File>
+ <File
+ RelativePath=".\i386\v86vdm.c"
</File>
</Filter>
Modified: branches/jcatena-branch/ntoskrnl/ntoskrnl.sln
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ntoskrn…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ntoskrnl.sln [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ntoskrnl.sln [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -64,8 +64,6 @@
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cpu-i386",
"..\lib\cpu\i386\cpu-i386.vcproj",
"{3D9AC5B7-C29C-46F5-B3D8-C4388F37DB5C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "kdw",
"kdw\kdw.vcproj", "{97021AF5-ED87-4AA8-B116-2D53E5D6D528}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trap2",
"trap2\trap2.vcproj", "{F9560D7C-D799-4A21-9827-6DDB6564E8C9}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trap",
"trap\trap.vcproj", "{E2A7291E-515F-4BAD-8E82-F77AA0815B47}"
EndProject
@@ -245,18 +243,9 @@
{97021AF5-ED87-4AA8-B116-2D53E5D6D528}.r|Win32.Build.0 = r|Win32
{97021AF5-ED87-4AA8-B116-2D53E5D6D528}.Release|Win32.ActiveCfg = r|Win32
{97021AF5-ED87-4AA8-B116-2D53E5D6D528}.Release|Win32.Build.0 = r|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.d|Win32.ActiveCfg = d|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.d|Win32.Build.0 = d|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.Debug|Win32.ActiveCfg = d|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.Debug|Win32.Build.0 = d|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.r|Win32.ActiveCfg = r|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.r|Win32.Build.0 = r|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.Release|Win32.ActiveCfg = r|Win32
- {F9560D7C-D799-4A21-9827-6DDB6564E8C9}.Release|Win32.Build.0 = r|Win32
{E2A7291E-515F-4BAD-8E82-F77AA0815B47}.d|Win32.ActiveCfg = d|Win32
{E2A7291E-515F-4BAD-8E82-F77AA0815B47}.d|Win32.Build.0 = d|Win32
{E2A7291E-515F-4BAD-8E82-F77AA0815B47}.Debug|Win32.ActiveCfg = d|Win32
- {E2A7291E-515F-4BAD-8E82-F77AA0815B47}.Debug|Win32.Build.0 = d|Win32
{E2A7291E-515F-4BAD-8E82-F77AA0815B47}.r|Win32.ActiveCfg = r|Win32
{E2A7291E-515F-4BAD-8E82-F77AA0815B47}.r|Win32.Build.0 = r|Win32
{E2A7291E-515F-4BAD-8E82-F77AA0815B47}.Release|Win32.ActiveCfg = r|Win32
Modified: branches/jcatena-branch/ntoskrnl/ntoskrnl.vcproj
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/ntoskrn…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/ntoskrnl.vcproj [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/ntoskrnl.vcproj [iso-8859-1] Thu Feb 4 13:05:14
2010
@@ -63,7 +63,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="mma3.lib mm.lib ke.lib ex.lib se.lib ob.lib ps.lib
cm.lib io.lib pnp.lib cc.lib csq.lib pseh.lib cmlib.lib fs.lib rossym.lib wdmguid.lib
rt.lib rtl.lib crtnt.lib cpu-i386.lib dbgp.lib kdw.lib hal.lib bootvid.lib
kdcom.lib"
+ AdditionalDependencies="mma3.lib mm.lib ke.lib ex.lib se.lib ob.lib ps.lib
cm.lib io.lib pnp.lib cc.lib csq.lib cmlib.lib fs.lib rossym.lib wdmguid.lib rt.lib
rtl.lib crtnt.lib cpu-i386.lib dbgp.lib kdw.lib hal.lib bootvid.lib kdcom.lib"
OutputFile="$(OutDir)/ntoskrnl.exe"
AdditionalLibraryDirectories=""
IgnoreAllDefaultLibraries="true"
@@ -139,7 +139,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="mma3.lib mm.lib ke.lib ex.lib se.lib ob.lib ps.lib
cm.lib io.lib pnp.lib cc.lib csq.lib pseh.lib cmlib.lib fs.lib rossym.lib wdmguid.lib
rt.lib rtl.lib crtnt.lib cpu-i386.lib dbgp.lib kdw.lib hal.lib bootvid.lib
kdcom.lib"
+ AdditionalDependencies="mma3.lib mm.lib ke.lib ex.lib se.lib ob.lib ps.lib
cm.lib io.lib pnp.lib cc.lib csq.lib cmlib.lib fs.lib rossym.lib wdmguid.lib rt.lib
rtl.lib crtnt.lib cpu-i386.lib dbgp.lib kdw.lib hal.lib bootvid.lib kdcom.lib"
OutputFile="$(OutDir)/ntoskrnl.exe"
AdditionalLibraryDirectories=""
IgnoreAllDefaultLibraries="true"
@@ -319,6 +319,10 @@
Filter="h;hpp;hxx;hm;inl"
<File
+ RelativePath="..\include\reactos\msc\intrin2.h"
+ >
+ </File>
+ <File
RelativePath=".\include\internal\ntoskrnl.h"
</File>
Modified: branches/jcatena-branch/ntoskrnl/trap/i386/TrapStub.h
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/trap/i3…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/trap/i386/TrapStub.h [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/trap/i386/TrapStub.h [iso-8859-1] Thu Feb 4 13:05:14
2010
@@ -6,13 +6,21 @@
#error
#endif
+#ifndef TRAP_STUB_DS
+#define TRAP_STUB_DS KGDT_R3_DATA | RPL_MASK
+#endif
+
+#ifndef TRAP_STUB_FS
+#define TRAP_STUB_FS KGDT_R0_PCR
+#endif
+
#define TRAP_STUB_NAMEH tokenpaste(TRAP_STUB_NAME, Handler)
#if (TRAP_STUB_FLAGS & TRAPF_INTERRUPT)
#define TRAP_STUB_PARAM2 tokenpaste(TRAP_STUB_NAME, Interrupt)
PKINTERRUPT TRAP_STUB_PARAM2;
#else
-VOID _FASTCALL TRAP_STUB_NAMEH(KTRAP_FRAME *TrapFrame);
+VOID _FASTCALL tokenpaste(TRAP_STUB_NAME, Handler)(KTRAP_FRAME *TrapFrame);
#endif
_NAKED VOID TRAP_STUB_NAME(VOID)
@@ -22,7 +30,6 @@
#if (TRAP_STUB_FLAGS & TRAPF_FASTSYSCALL)
mov esp, ss:[KIP0PCRADDRESS + offset KPCR.TSS]
mov esp, KTSS.Esp0[esp]
- // sub esp, dword ptr offset KTRAP_FRAME.V86Es
sub esp, dword ptr offset KTRAP_FRAME.V86Es
#elif (TRAP_STUB_FLAGS & TRAPF_ERRORCODE)
sub esp, offset KTRAP_FRAME.ErrCode
@@ -61,12 +68,13 @@
#endif
// call handler
- mov ecx, esp
#if (TRAP_STUB_FLAGS & TRAPF_INTERRUPT)
mov edx, TRAP_STUB_PARAM2
+ mov ecx, esp
call PKINTERRUPT.DispatchAddress[edx]
#else
- call TRAP_STUB_NAMEH
+ mov ecx, esp
+ call tokenpaste(TRAP_STUB_NAME, Handler)
#endif
// restore regs
Modified: branches/jcatena-branch/ntoskrnl/trap/trap.c
URL:
http://svn.reactos.org/svn/reactos/branches/jcatena-branch/ntoskrnl/trap/tr…
==============================================================================
--- branches/jcatena-branch/ntoskrnl/trap/trap.c [iso-8859-1] (original)
+++ branches/jcatena-branch/ntoskrnl/trap/trap.c [iso-8859-1] Thu Feb 4 13:05:14 2010
@@ -115,7 +115,7 @@
#define TRAP_STUB_FLAGS 0
#include <TrapStub.h>
-#define TRAP_STUB_NAME KiDebugService
+#define TRAP_STUB_NAME KiDebugServiceVOID
#define TRAP_STUB_FLAGS 0
#include <TrapStub.h>
@@ -134,7 +134,176 @@
_NOWARN_POP
-VOID _FASTCALL init(void)
+/* TRAP EXIT CODE *************************************************************/
+//
+// Generic Exit Routine
+//
+
+VOID
+FASTCALL
+KiExitTrap(IN PKTRAP_FRAME TrapFrame, IN UCHAR Skip)
{
+ KTRAP_EXIT_SKIP_BITS SkipBits;
+ PULONG ReturnStack;
+
+ SkipBits.Bits = Skip;
+
+ /* Debugging checks */
+ // DPRINTT("DebugChecks\n");
+ // KiExitTrapDebugChecks(TrapFrame, SkipBits);
+
+ /* Restore the SEH handler chain */
+ KeGetPcr()->Tib.ExceptionList = TrapFrame->ExceptionList;
+
+ /* Check if the previous mode must be restored */
+ if (__builtin_expect(!SkipBits.SkipPreviousMode, 0)) /* More INTS than SYSCALLs */
+ {
+ /* Restore it */
+ KeGetCurrentThread()->PreviousMode = TrapFrame->PreviousPreviousMode;
+ }
+
+ /* Check if there are active debug registers */
+ if (__builtin_expect(TrapFrame->Dr7 & ~DR7_RESERVED_MASK, 0))
+ {
+ /* Not handled yet */
+ DbgPrint("Need Hardware Breakpoint Support!\n");
+ DbgBreakPoint();
+ while (TRUE);
+ }
+
+ /* Check if this was a V8086 trap */
+ // DPRINTT("V8086\n");
+ if (__builtin_expect(TrapFrame->EFlags & EFLAGS_V86_MASK, 0))
+ {
+ // DPRINTT("V8086 r\n");
+ // KiTrapReturn(TrapFrame);
+ return;
+ }
+
+ /* Check if the trap frame was edited */
+ if (__builtin_expect(!(TrapFrame->SegCs & FRAME_EDITED), 0))
+ {
+ /*
+ * An edited trap frame happens when we need to modify CS and/or ESP but
+ * don't actually have a ring transition. This happens when a kernelmode
+ * caller wants to perform an NtContinue to another kernel address, such
+ * as in the case of SEH (basically, a longjmp), or to a user address.
+ *
+ * Therefore, the CPU never saved CS/ESP on the stack because we did not
+ * get a trap frame due to a ring transition (there was no interrupt).
+ * Even if we didn't want to restore CS to a new value, a problem occurs
+ * due to the fact a normal RET would not work if we restored ESP since
+ * RET would then try to read the result off the stack.
+ *
+ * The NT kernel solves this by adding 12 bytes of stack to the exiting
+ * trap frame, in which EFLAGS, CS, and EIP are stored, and then saving
+ * the ESP that's being requested into the ErrorCode field. It will then
+ * exit with an IRET. This fixes both issues, because it gives the stack
+ * some space where to hold the return address and then end up with the
+ * wanted stack, and it uses IRET which allows a new CS to be inputted.
+ *
+ */
+ // DPRINTT("edited\n");
+ /* Set CS that is requested */
+ TrapFrame->SegCs = TrapFrame->TempSegCs;
+
+ /* First make space on requested stack */
+ ReturnStack = (PULONG)(TrapFrame->TempEsp - 12);
+ TrapFrame->ErrCode = (ULONG_PTR)ReturnStack;
+
+ /* Now copy IRET frame */
+ ReturnStack[0] = TrapFrame->Eip;
+ ReturnStack[1] = TrapFrame->SegCs;
+ ReturnStack[2] = TrapFrame->EFlags;
+
+ /* Do special edited return */
+ // DPRINTT("KiEditedTrapReturn\n");
+ // KiEditedTrapReturn(TrapFrame);
+ return;
+ }
+
+ /* Check if this is a user trap */
+ if (__builtin_expect(KiUserTrap(TrapFrame), 1)) /* Ring 3 is where we spend time */
+ {
+ // DPRINTT("user\n");
+ /* Check if segments should be restored */
+ if (!SkipBits.SkipSegments)
+ {
+ /* Restore segments */
+ CpuSetGs(TrapFrame->SegGs);
+ CpuSetEs(TrapFrame->SegEs);
+ CpuSetDs(TrapFrame->SegDs);
+ CpuSetFs(TrapFrame->SegFs);
+ }
+
+ /* Always restore FS since it goes from KPCR to TEB */
+ CpuSetFs(TrapFrame->SegFs);
+ }
+
+ /* Check for system call -- a system call skips volatiles! */
+ if (__builtin_expect(SkipBits.SkipVolatiles, 0)) /* More INTs than SYSCALLs */
+ {
+ // DPRINTT("syscall\n");
+ /* Kernel call or user call? */
+ if (__builtin_expect(KiUserTrap(TrapFrame), 1)) /* More Ring 3 than 0 */
+ {
+ /* Is SYSENTER supported and/or enabled, or are we stepping code? */
+ if (__builtin_expect((KiFastSystemCallDisable) ||
+ (TrapFrame->EFlags & EFLAGS_TF), 0))
+ {
+ /* Exit normally */
+ // DPRINTT("normally KiSystemCallTrapReturn\n");
+ KiSystemCallTrapReturn(TrapFrame);
+ }
+ else
+ {
+ /* Restore user FS */
+ CpuSetFs(KGDT_R3_TEB | RPL_MASK);
+
+ /* Remove interrupt flag */
+ TrapFrame->EFlags &= ~EFLAGS_INTERRUPT_MASK;
+ __writeeflags(TrapFrame->EFlags);
+
+ /* Exit through SYSEXIT */
+ // DPRINTT("sysexit KiSystemCallSysExitReturn\n");
+ // KiSystemCallSysExitReturn(TrapFrame);
+ }
+ }
+ else
+ {
+ /* Restore EFLags */
+ __writeeflags(TrapFrame->EFlags);
+
+ /* Call is kernel, so do a jump back since this wasn't a real INT */
+ // DPRINTT("kernel KiSystemCallReturn\n");
+ // KiSystemCallReturn(TrapFrame);
+ }
+ }
+ else
+ {
+ // DPRINTT("int KiTrapReturn\n");
+ /* Return from interrupt */
+ // KiTrapReturn(TrapFrame);
+ }
}
+
+
+VOID _FASTCALL
+KiEoiHelper(IN PKTRAP_FRAME TrapFrame)
+{
+ // DPRINTT("\n");
+ /* Disable interrupts until we return */
+ CpuIntDisable();
+
+ /* Check for APC delivery */
+ KiCheckForApcDelivery(TrapFrame);
+
+ /* Now exit the trap for real */
+ // DPRINTT("KiExitTrap\n");
+ KiExitTrap(TrapFrame, KTE_SKIP_PM_BIT);
+ UNREACHABLE;
+}
+
+
+