SYSENTER support, INT2E Optimization, new Syscall Table/Stub generator and svn:ignore fixes. Please read associated Mailing List Post.
Modified: trunk/reactos/Makefile
Modified: trunk/reactos/config
Deleted: trunk/reactos/iface/
Modified: trunk/reactos/include/napi/shared_data.h
Modified: trunk/reactos/ntoskrnl/Makefile
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ps.h
Modified: trunk/reactos/ntoskrnl/ke/i386/bthread.S
Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
Modified: trunk/reactos/ntoskrnl/ke/i386/gdt.c
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
Modified: trunk/reactos/ntoskrnl/ke/i386/stkswitch.S
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
Modified: trunk/reactos/ntoskrnl/ke/i386/usercall.c
Modified: trunk/reactos/ntoskrnl/ke/kthread.c
Modified: trunk/reactos/ntoskrnl/ke/process.c
Modified: trunk/reactos/ntoskrnl/ps/i386/continue.c
Modified: trunk/reactos/subsys/system/vmwinst/vmwinst.c
Added: trunk/reactos/tools/nci/
Added: trunk/reactos/tools/nci/makefile
Added: trunk/reactos/tools/nci/ncitool.c
Added: trunk/reactos/tools/nci/sysfuncs.lst
Added: trunk/reactos/tools/nci/w32ksvc.db

Modified: trunk/reactos/Makefile
--- trunk/reactos/Makefile	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/Makefile	2005-01-17 07:10:34 UTC (rev 13090)
@@ -130,7 +130,7 @@
 all: bootstrap $(BOOT_LOADERS) $(COMPONENTS) $(REGTESTS) $(HALS) $(BUS) $(LIB_FSLIB) \
      $(DLLS) $(SUBSYS) $(KERNEL_DRIVERS) $(SYS_APPS) $(SYS_SVC) $(APPS) $(EXT_MODULES)
 
-bootstrap: dk implib iface_native iface_additional
+bootstrap: dk implib iface_native
 
 depends: $(LIB_STATIC:%=%_depends) $(LIB_FSLIB:%=%_depends) msvcrt_depends $(DLLS:%=%_depends) \
          $(SUBSYS:%=%_depends) $(SYS_SVC:%=%_depends) \
@@ -147,7 +147,7 @@
 	    $(KERNEL_DRIVERS:%=%_test) $(SUBSYS:%=%_test) \
 	    $(SYS_SVC:%=%_test) $(EXT_MODULES:%=%_test)
 
-clean: tools dk_clean iface_native_clean iface_additional_clean hallib_clean \
+clean: tools dk_clean iface_native_clean hallib_clean \
        $(BOOT_LOADERS:%=%_clean) $(HALS:%=%_clean) $(COMPONENTS:%=%_clean) \
        $(BUS:%=%_clean) $(LIB_STATIC:%=%_clean) $(LIB_FSLIB:%=%_clean) \
        msvcrt_clean $(DLLS:%=%_clean) $(KERNEL_DRIVERS:%=%_clean) \
@@ -462,37 +462,21 @@
 # Interfaces
 #
 iface_native:
-	$(MAKE) --silent -C iface/native
+	$(MAKE) --silent -C tools/nci
 
 iface_native_implib:
 	
 iface_native_test:
 	
 iface_native_clean:
-	$(MAKE) --silent -C iface/native clean
+	$(MAKE) --silent -C tools/nci clean
 
 iface_native_install:
 
 iface_native_bootcd:
 
-iface_additional:
-	$(MAKE) --silent -C iface/addsys
-
-iface_additional_implib:
-	
-iface_additional_test:
-	
-iface_additional_clean:
-	$(MAKE) --silent -C iface/addsys clean
-
-iface_additional_install:
-
-iface_additional_bootcd:
-
 .PHONY: iface_native iface_native_implib iface_native_test iface_native_clean \
-        iface_native_install iface_native_bootcd iface_additional \
-        iface_additional_implib iface_additional_test iface_additional_clean \
-        iface_additional_install iface_additional_bootcd
+        iface_native_install iface_native_bootcd
 
 
 #

Modified: trunk/reactos/config
--- trunk/reactos/config	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/config	2005-01-17 07:10:34 UTC (rev 13090)
@@ -25,7 +25,7 @@
 #
 # Whether to compile for debugging
 #
-DBG := 0 
+DBG := 0
 
 #
 # Whether to compile with optimizations

Modified: trunk/reactos/include/napi/shared_data.h
--- trunk/reactos/include/napi/shared_data.h	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/include/napi/shared_data.h	2005-01-17 07:10:34 UTC (rev 13090)
@@ -13,6 +13,8 @@
 #define PF_PAE_ENABLED                      9
 #define PF_XMMI64_INSTRUCTIONS_AVAILABLE   10
 
+#ifndef __ASM__
+
 typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
 {
    StandardDesign,
@@ -62,13 +64,15 @@
     BOOLEAN SafeBootMode;
     ULONG TraceLogging;
     ULONGLONG Fill0;
-    ULONGLONG SystemCall[4];
+    UCHAR SystemCall[16];
     union {
         volatile KSYSTEM_TIME TickCount;
         volatile ULONG64 TickCountQuad;
     };
 } KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;
 
+#endif
+
 /* Values for DosDeviceDriveType */
 #define DOSDEVICE_DRIVE_UNKNOWN		0
 #define DOSDEVICE_DRIVE_CALCULATE	1
@@ -102,5 +106,7 @@
 #define SharedUserData		((KUSER_SHARED_DATA * const)USER_SHARED_DATA)
 #endif
 
+#define KUSER_SHARED_SYSCALL     0x7FFE0300
+#define KUSER_SHARED_SYSCALL_RET 0x7FFE0304
 
 #endif /* __INCLUDE_NAPI_SHARED_DATA_H */
Property changes on: trunk/reactos/lib/gdi32/misc
___________________________________________________________________
Name: svn:ignore
   - win32k.c
*.o
.*.d
   + win32k.S
*.o
.*.d
Property changes on: trunk/reactos/lib/kbdes
___________________________________________________________________
Name: svn:ignore
   + *.sys
*.exe
*.dll
*.cpl
*.a
*.o
*.d
*.coff
*.dsp
*.dsw
*.aps
*.ncb
*.opt
*.sym
*.plg
*.bak
*.map
Property changes on: trunk/reactos/lib/ntdll
___________________________________________________________________
Name: svn:ignore
   - temp.exp
napi.asm
napi.c
*.tmp
*.lib
*.sym
*.coff
*.dll
*.o
*.a
*.map
doxy-doc
   + temp.exp
napi.asm
napi.S
*.tmp
*.lib
*.sym
*.coff
*.dll
*.o
*.a
*.map
doxy-doc
Property changes on: trunk/reactos/lib/user32/misc
___________________________________________________________________
Name: svn:ignore
   - win32k.c
*.d
*.a
*.o
*.sym
   + win32k.S
*.d
*.a
*.o
*.sym

Modified: trunk/reactos/ntoskrnl/Makefile
--- trunk/reactos/ntoskrnl/Makefile	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/Makefile	2005-01-17 07:10:34 UTC (rev 13090)
@@ -550,7 +550,7 @@
   $(PATH_TO_TOP)/include/reactos/bugcodes.h \
   $(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc 
 
-ex/napi.o: ex/napi.c $(PATH_TO_TOP)/include/ntdll/napi.h
+ex/napi.o: ex/zw.S $(PATH_TO_TOP)/include/ntdll/napi.h
 
 ke/main.o: ke/main.c $(PATH_TO_TOP)/include/reactos/buildno.h
 
Property changes on: trunk/reactos/ntoskrnl/ex
___________________________________________________________________
Name: svn:ignore
   - *.d
*.o
*.sym
   + *.d
*.o
*.sym
zw.S

Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h
--- trunk/reactos/ntoskrnl/include/internal/i386/ke.h	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h	2005-01-17 07:10:34 UTC (rev 13090)
@@ -88,6 +88,7 @@
 #define X86_FEATURE_TSC         0x00000010 /* time stamp counters are present */
 #define X86_FEATURE_PAE         0x00000040 /* physical address extension is present */
 #define X86_FEATURE_CX8         0x00000100 /* CMPXCHG8B instruction present */
+#define X86_FEATURE_SYSCALL     0x00000800 /* SYSCALL/SYSRET support present */
 #define X86_FEATURE_PGE         0x00002000 /* Page Global Enable */
 #define X86_FEATURE_MMX         0x00800000 /* MMX extension present */
 #define X86_FEATURE_FXSR        0x01000000 /* FXSAVE/FXRSTOR instructions present */

Modified: trunk/reactos/ntoskrnl/include/internal/i386/ps.h
--- trunk/reactos/ntoskrnl/include/internal/i386/ps.h	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/include/internal/i386/ps.h	2005-01-17 07:10:34 UTC (rev 13090)
@@ -27,6 +27,7 @@
 #define KTHREAD_TEB               0x20
 #define KTHREAD_KERNEL_STACK      0x28
 #define KTHREAD_NPX_STATE         0x31
+#define KTHREAD_PENDING_USER_APC  0x34 + 0x16
 #define KTHREAD_APCSTATE_PROCESS  0x44
 #define KTHREAD_SERVICE_TABLE     0xDC
 #define KTHREAD_PREVIOUS_MODE     0x137

Modified: trunk/reactos/ntoskrnl/ke/i386/bthread.S
--- trunk/reactos/ntoskrnl/ke/i386/bthread.S	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/ke/i386/bthread.S	2005-01-17 07:10:34 UTC (rev 13090)
@@ -143,4 +143,4 @@
 
 	/* Load the rest of the thread's user mode context. */
 	movl	$0, %eax
-	jmp	KeReturnFromSystemCallWithHook
+	jmp	_KiServiceExit

Modified: trunk/reactos/ntoskrnl/ke/i386/exp.c
--- trunk/reactos/ntoskrnl/ke/i386/exp.c	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/ke/i386/exp.c	2005-01-17 07:10:34 UTC (rev 13090)
@@ -45,7 +45,7 @@
 # define ARRAY_SIZE(x) (sizeof (x) / sizeof (x[0]))
 #endif
 
-extern void interrupt_handler2e(void);
+extern void KiSystemService(void);
 extern void interrupt_handler2d(void);
 
 extern VOID KiTrap0(VOID);
@@ -850,7 +850,7 @@
      }
 
    set_system_call_gate(0x2d,(int)interrupt_handler2d);
-   set_system_call_gate(0x2e,(int)interrupt_handler2e);
+   set_system_call_gate(0x2e,(int)KiSystemService);
 }
 
 /*
@@ -873,30 +873,32 @@
    return((NTSTATUS)OldEip);
 }
 
-VOID
-FASTCALL
-KeRosTrapReturn ( PKTRAP_FRAME TrapFrame, PKTRAP_FRAME PrevTrapFrame );
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtRaiseException (
-	IN PEXCEPTION_RECORD ExceptionRecord,
-	IN PCONTEXT Context,
-	IN BOOLEAN SearchFrames)
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT Context,
+    IN BOOLEAN SearchFrames)
 {
-	PKTRAP_FRAME TrapFrame = KeGetCurrentThread()->TrapFrame;
-	PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
+    PKTHREAD Thread = KeGetCurrentThread();
+    PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
+    PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
 
-	KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
+    KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
 
-	KiDispatchException(ExceptionRecord,
-		Context,
-		PsGetCurrentThread()->Tcb.TrapFrame,
-		(KPROCESSOR_MODE)ExGetPreviousMode(),
-		SearchFrames);
+    KiDispatchException(ExceptionRecord,
+                        Context,
+                        TrapFrame,
+                        KeGetPreviousMode(),
+                        SearchFrames);
 
-	KeRosTrapReturn ( TrapFrame, PrevTrapFrame );
-	return(STATUS_SUCCESS);
+    /* Restore the user context */
+    Thread->TrapFrame = PrevTrapFrame;
+    __asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame));
+    
+    /* We never get here */
+    return(STATUS_SUCCESS);
 }

Modified: trunk/reactos/ntoskrnl/ke/i386/gdt.c
--- trunk/reactos/ntoskrnl/ke/i386/gdt.c	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/ke/i386/gdt.c	2005-01-17 07:10:34 UTC (rev 13090)
@@ -40,10 +40,10 @@
  0x0, 0x0, 0x0, 0x0,              /* Null */
  0xffff, 0x0, 0x9a00, 0xcf,       /* Kernel CS */
  0xffff, 0x0, 0x9200, 0xcf,       /* Kernel DS */
- 0x0, 0x0, 0xfa00, 0xcc,          /* User CS */
- 0x0, 0x0, 0xf200, 0xcc,          /* User DS */
+ 0x0, 0x0, 0xfa00, 0xcf,          /* User CS */
+ 0x0, 0x0, 0xf200, 0xcf,          /* User DS */
  0x0, 0x0, 0x0, 0x0,              /* TSS */
- 0x1000, 0x0000, 0x9200, 0xff00,  /* PCR */
+ 0x1000, 0x0000, 0x9200, 0xffc0,  /* PCR */
  0x1000, 0x0, 0xf200, 0x0,        /* TEB */
  0x0, 0x0, 0x0, 0x0,              /* Reserved */
  0x0, 0x0, 0x0, 0x0,              /* LDT */

Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c
--- trunk/reactos/ntoskrnl/ke/i386/kernel.c	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/ke/i386/kernel.c	2005-01-17 07:10:34 UTC (rev 13090)
@@ -43,6 +43,7 @@
 BOOLEAN Ke386Pae = FALSE;
 BOOLEAN Ke386PaeEnabled = FALSE;
 BOOLEAN Ke386GlobalPagesEnabled = FALSE;
+ULONG KiFastSystemCallDisable = 0;
 
 /* FUNCTIONS *****************************************************************/
 
@@ -323,6 +324,18 @@
       MiEnablePAE((PVOID*)LastKernelAddress);
       Ke386PaeEnabled = TRUE;
    }
+
+   if (KPCR->PrcbData.FeatureBits & X86_FEATURE_SYSCALL)
+   {
+      extern void KiFastCallEntry(void);
+
+      /* CS Selector of the target segment. */
+      Ke386Wrmsr(0x174, KERNEL_CS, 0);
+      /* Target ESP. */
+      Ke386Wrmsr(0x175, 0, 0);
+      /* Target EIP. */
+      Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);
+   }
 }
 
 VOID INIT_FUNCTION
@@ -391,23 +404,89 @@
 VOID INIT_FUNCTION
 Ki386SetProcessorFeatures(VOID)
 {
-  PKPCR Pcr = KeGetCurrentKPCR();
+   PKPCR Pcr = KeGetCurrentKPCR();
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   UNICODE_STRING KeyName;
+   UNICODE_STRING ValueName;
+   HANDLE KeyHandle;
+   ULONG ResultLength;
+   KEY_VALUE_PARTIAL_INFORMATION ValueData;
+   NTSTATUS Status;
 
-  SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
-  SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
-  SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
-    (Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
-  SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
-    (Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
-  SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
-  SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
-  SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = 
-    (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
-  SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
-    (Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
-  SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
-    (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
-  SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
-  SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
-    (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
+   SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_PRECISION_ERRATA] = FALSE;
+   SharedUserData->ProcessorFeatures[PF_FLOATING_POINT_EMULATED] = FALSE;
+   SharedUserData->ProcessorFeatures[PF_COMPARE_EXCHANGE_DOUBLE] =
+      (Pcr->PrcbData.FeatureBits & X86_FEATURE_CX8);
+   SharedUserData->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE] =
+      (Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
+   SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
+   SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
+   SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] = 
+      (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
+   SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
+      (Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
+   SharedUserData->ProcessorFeatures[PF_RDTSC_INSTRUCTION_AVAILABLE] =
+      (Pcr->PrcbData.FeatureBits & X86_FEATURE_TSC);
+   SharedUserData->ProcessorFeatures[PF_PAE_ENABLED] = Ke386PaeEnabled;
+   SharedUserData->ProcessorFeatures[PF_XMMI64_INSTRUCTIONS_AVAILABLE] =
+      (Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE2);
+
+   /* Does the CPU Support Fast System Call? */
+   if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) {
+   
+        /* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */
+       
+        /* Make sure it's not disabled in registry */
+        RtlRosInitUnicodeStringFromLiteral(&KeyName, 
+                                           L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel");
+        RtlRosInitUnicodeStringFromLiteral(&ValueName, 
+                                           L"FastSystemCallDisable");
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &KeyName,
+                                   OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   NULL);
+        Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
+        
+        if (NT_SUCCESS(Status)) {
+        
+            /* Read the Value then Close the Key */
+            Status = NtQueryValueKey(KeyHandle,
+                                     &ValueName,
+                                     KeyValuePartialInformation,
+                                     &ValueData,
+                                     sizeof(ValueData),
+                                     &ResultLength);
+            RtlMoveMemory(&KiFastSystemCallDisable, ValueData.Data, sizeof(ULONG));
+            
+            NtClose(KeyHandle);
+        }
+        
+    } else {
+    
+        /* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */
+        KiFastSystemCallDisable = 1;
+        
+    }
+    
+    if (!KiFastSystemCallDisable) {
+        
+        /* Use SYSENTER */
+        SharedUserData->SystemCall[0] = 0x8B;
+        SharedUserData->SystemCall[1] = 0xD4;
+        SharedUserData->SystemCall[2] = 0x0F;
+        SharedUserData->SystemCall[3] = 0x34;
+        SharedUserData->SystemCall[4] = 0xC3;    
+                  
+    } else {
+    
+        /* Use INT2E */   
+        SharedUserData->SystemCall[0] = 0x8D;
+        SharedUserData->SystemCall[1] = 0x54;
+        SharedUserData->SystemCall[2] = 0x24;
+        SharedUserData->SystemCall[3] = 0x08;
+        SharedUserData->SystemCall[4] = 0xCD;
+        SharedUserData->SystemCall[5] = 0x2E;
+        SharedUserData->SystemCall[6] = 0xC3;
+    }
 }

Modified: trunk/reactos/ntoskrnl/ke/i386/stkswitch.S
--- trunk/reactos/ntoskrnl/ke/i386/stkswitch.S	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/ke/i386/stkswitch.S	2005-01-17 07:10:34 UTC (rev 13090)
@@ -78,5 +78,5 @@
 	push	$0
 	call	_KeLowerIrql@4
 
-	jmp	KeReturnFromSystemCall
+	jmp _KiServiceExit
 

Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
--- trunk/reactos/ntoskrnl/ke/i386/syscall.S	2005-01-17 01:30:26 UTC (rev 13089)
+++ trunk/reactos/ntoskrnl/ke/i386/syscall.S	2005-01-17 07:10:34 UTC (rev 13090)
@@ -1,324 +1,317 @@
-/*
- *  ReactOS kernel
- *  Copyright (C) 2000  David Welch <welch@cwcom.net>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
 /* $Id$
  *
  * FILE:            ntoskrnl/ke/i386/syscall.S
- * PURPOSE:         2E trap handler
- * PROGRAMMER:      David Welch (david.welch@seh.ox.ac.uk)
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PURPOSE:         System Call Handler
+ * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
  * UPDATE HISTORY:
- *                  ???
+ *                  ??-??-??: Original Version - David Welch(?)
+ *                  13-01-05: Complete rewrite, added support for SYSENTER, direct kmode syscalls
+ *                            and re-wrote most of handler code. - Alex Ionescu
  */
 
 #include <ddk/status.h>
 #include <internal/i386/segment.h>
 #include <internal/ps.h>
 #include <internal/i386/ke.h>
+#include <ntos/tss.h>
+#include <napi/shared_data.h>
 #include <roscfg.h>
 
-#define KernelMode  (0)
-#define UserMode    (1)
+#define UserMode  (1)
 
-/*
- *
- */
-.globl KeReturnFromSystemCall
 .globl KeReturnFromSystemCallWithHook
-.globl _interrupt_handler2e
-_interrupt_handler2e:
+.globl _KiServiceExit
+.globl _KiFastCallEntry
+.globl _KiSystemService
 
-	/* Construct a trap frame on the stack */
+_KiFastCallEntry:
 
-	/* Error code */
-	pushl $0
-	pushl %ebp
-	pushl %ebx
-	pushl %esi
-	pushl %edi
-	pushl %fs
-	/* Load PCR selector into fs */
-	movl  $PCR_SELECTOR, %ebx
-	movl  %ebx, %fs
+    /* Set FS to PCR */
+    movl $PCR_SELECTOR, %ecx
+    movw %cx, %fs
+    
+    /* Set the current stack to Kernel Stack */
+    movl %fs:KPCR_TSS, %ecx
+    movl KTSS_ESP0(%ecx), %ecx
+    movl %ecx, %esp
+    
+    /* Set up a fake INT Stack. */
+    pushl $USER_DS
+    pushl %edx                  /* Ring 3 SS:ESP */
+    pushfl
+    orl $200, (%esp)            /* Re-enable IRQs in EFLAGS, to fake INT */
+    pushl $USER_CS
+    pushl $KUSER_SHARED_SYSCALL_RET
+    
+    /* User Parameter List */
+    add $8, %edx
+    
+_KiSystemService:
 
-	/* Save the old exception list */
-	movl  %fs:KPCR_EXCEPTION_LIST, %ebx
-	pushl %ebx
-	/* Set the exception handler chain terminator */
-	movl  $0xffffffff, %fs:KPCR_EXCEPTION_LIST
-	/* Get a pointer to the current thread */
-	movl  %fs:KPCR_CURRENT_THREAD, %esi
-	/* Save the old previous mode */
-	movl  $0, %ebx
-	movb  %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
-	pushl %ebx
-	/* Set the new previous mode based on the saved CS selector */
-	movl  0x24(%esp), %ebx
-	andl  $0x0000FFFF, %ebx
-	cmpl  $KERNEL_CS, %ebx
-	jne   L1
-	movb  $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
-	jmp   L3
-L1:
-	movb  $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
-L3:
+    /* 
+     * Construct a trap frame on the stack.
+     * The following are already on the stack.
+     */
+    // SS                                                                  + 0x0
+    // ESP                                                                 + 0x4
+    // EFLAGS                                                              + 0x8
+    // CS                                                                  + 0xC
+    // EIP                                                                 + 0x10
+    pushl $0                                                            // + 0x14
+    pushl %ebp                                                          // + 0x18
+    pushl %ebx                                                          // + 0x1C
+    pushl %esi                                                          // + 0x20
+    pushl %edi                                                          // + 0x24
+    pushl %fs                                                           // + 0x28
+    
+    /* Load PCR Selector into fs */
+    movw $PCR_SELECTOR, %bx
+    movw %bx, %fs
+    
+    /* Save the previous exception list */
+    pushl %fs:KPCR_EXCEPTION_LIST                                       // + 0x2C
 
-	/* Save other registers */
-	pushl %eax
-	pushl %ecx
-	pushl %edx
-	pushl %ds
-	pushl %es
-	pushl %gs
-	pushl $0     /* DR7 */
-	pushl $0     /* DR6 */
-	pushl $0     /* DR3 */
-	pushl $0     /* DR2 */
-	pushl $0     /* DR1 */
-	pushl $0     /* DR0 */
-	pushl $0     /* XXX: TempESP */
-	pushl $0     /* XXX: TempCS */
-	pushl $0     /* XXX: DebugPointer */
-	pushl $0     /* XXX: DebugArgMark */
+    /* Set the exception handler chain terminator */
+    movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
 
-#ifdef DBG
-	/* Trick gdb 6 into backtracing over the system call */
-	movl  4(%ebp), %ebx
-	pushl %ebx   /* DebugEIP */
-	movl  (%ebp), %ebx
-	pushl %ebx   /* DebugEBP */
-#else
-	movl  0x60(%esp), %ebx
-	pushl %ebx   /* DebugEIP */
-	pushl %ebp   /* DebugEBP */
-#endif
+    /* Get a pointer to the current thread */
+    movl %fs:KPCR_CURRENT_THREAD, %esi
 
-	/* Load the segment registers */
-	movl  $KERNEL_DS, %ebx
-	movl  %ebx, %ds
-	movl  %ebx, %es
-	movl  %ebx, %gs
+    /* Save the old previous mode */
+    pushl %ss:KTHREAD_PREVIOUS_MODE(%esi)                               // + 0x30
+    
+    /* Set the new previous mode based on the saved CS selector */
+    movl 0x24(%esp), %ebx
+    and $1, %ebx
+    movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
 
-	/*
-	 * Save the old trap frame pointer over where we would save the EDX
-	 * register.
-	 */
-	movl  KTHREAD_TRAP_FRAME(%esi), %ebx
-	movl  %ebx, KTRAP_FRAME_EDX(%esp)
+    /* Save other registers */
+    pushl %eax                                                         // + 0x34
+    pushl %ecx                                                         // + 0x38
+    pushl %edx                                                         // + 0x3C
+    pushl %ds                                                          // + 0x40
+    pushl %es                                                          // + 0x44
+    pushl %gs                                                          // + 0x48
+    sub $0x28, %esp                                                    // + 0x70
 
-	/*  Allocate new Kernel stack frame  */
-	movl  %esp,%ebp
-
-	/* Save a pointer to the trap frame in the TCB */
-	movl  %ebp, KTHREAD_TRAP_FRAME(%esi)
-
-	/*  Set ES to kernel segment  */
-	movw  $KERNEL_DS,%bx
-	movw  %bx,%es
-
-	/*  Users's current stack frame pointer is source  */
-	movl  %edx,%esi
-
-	/*  Determine system service table to use  */
-	cmpl  $0x0fff, %eax
-	ja    new_useShadowTable
-
-	/*  Check to see if EAX is valid/inrange  */
-	cmpl  %es:_KeServiceDescriptorTable + 8, %eax
-	jbe   new_serviceInRange
-	movl  $STATUS_INVALID_SYSTEM_SERVICE, %eax
-	movl  %eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
-	jmp   KeReturnFromSystemCall
-
-new_serviceInRange:
-
 #ifdef DBG
-	/* GDB thinks the function starts here and
-	   wants a standard prolog, so let's give it */
-	pushl	%ebp
-	movl	%esp,%ebp
-	popl	%ebp
+    /* Trick gdb 6 into backtracing over the system call */
+    pushl 4(%ebp)    /* DebugEIP */                                    // + 0x74
+    pushl (%ebp)     /* DebugEBP */                                    // + 0x78
+#else
+    pushl 0x60(%esp) /* DebugEIP */                                    // + 0x74
+    pushl %ebp       /* DebugEBP */                                    // + 0x78
 #endif
 
-	/*  Allocate room for argument list from kernel stack  */
-	movl	%es:_KeServiceDescriptorTable + 12, %ecx
-	movb	%es:(%ecx, %eax), %cl
-	movzx	%cl, %ecx
-	subl	%ecx, %esp
+    /* Load the segment registers */
+    movw $KERNEL_DS, %bx
+    movw %bx, %ds
+    movw %bx, %es
+    movw %bx, %gs
 
-	/*  Copy the arguments from the user stack to the kernel stack  */
-	movl	%esp,%edi
-	cld
-	rep	movsb
+    /* Save the old trap frame pointer where EDX would be saved */
+    movl KTHREAD_TRAP_FRAME(%esi), %ebx
+    movl %ebx, KTRAP_FRAME_EDX(%esp)
 
-	/*  DS is now also kernel segment  */
-	movw	%bx, %ds
+    /* Allocate new Kernel stack frame */
+    movl %esp,%ebp
 
-	/* Call system call hook */
-	pushl	%eax
-	call	_KiSystemCallHook
-	popl	%eax
+    /* Save a pointer to the trap frame in the TCB */
+    movl %ebp, KTHREAD_TRAP_FRAME(%esi)
 
-	/*  Make the system service call  */
-	movl	%es:_KeServiceDescriptorTable, %ecx
-	movl	%es:(%ecx, %eax, 4), %eax
-	call	*%eax
-	movl	%eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
+CheckValidCall:
 
-#if CHECKED
-	/*  Bump Service Counter  */
-#endif
-
-	jmp	KeDeallocateStackAndReturnFromSystemCallWithHook
-
-new_useShadowTable:
-
-	subl	$0x1000, %eax
-
-	/*  Check to see if EAX is valid/inrange  */
-	cmpl	%es:_KeServiceDescriptorTableShadow + 24, %eax
-	jbe	new_shadowServiceInRange
-	movl	$STATUS_INVALID_SYSTEM_SERVICE, %eax
-	movl	%eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
-	jmp	KeReturnFromSystemCall
-
-new_shadowServiceInRange:
-
+    /*
+     * Find out which table offset to use. Converts 0x1124 into 0x10.
+     * The offset is related to the Table Index as such: Offset = TableIndex x 10
+     */
+    movl %eax, %edi
+    shrl $8, %edi
+    andl $0x10, %edi
+    movl %edi, %ecx
+       
+    /* Now add the thread's base system table to the offset */
+    addl KTHREAD_SERVICE_TABLE(%esi), %edi
+    
+    /* Get the true syscall ID and check it */
+    movl %eax, %ebx
+    andl $0x0FFF, %eax
+    cmpl 8(%edi), %eax
+    
+    /* Invalid ID, try to load Win32K Table */
+    jnb KiBBTUnexpectedRange
+    
 #ifdef DBG
-	/*
-	 * GDB thinks the function starts here and
-	 * wants a standard prolog, so let's give it
-	 */
-	pushl	%ebp
-	movl	%esp,%ebp
-	popl	%ebp
+    /*
+     * GDB thinks the function starts here and
+     * wants a standard prolog, so let's give it
+     */
+    pushl %ebp
+    movl %esp,%ebp
+    popl %ebp
 #endif
 
-	/*  Allocate room for argument list from kernel stack  */
-	movl	%es:_KeServiceDescriptorTableShadow + 28, %ecx
-	movb	%es:(%ecx, %eax), %cl
-	movzx	%cl, %ecx
-	subl	%ecx, %esp
+    /* Users's current stack frame pointer is source */
+    movl %edx, %esi
+   
+    /* Allocate room for argument list from kernel stack */
+    movl 12(%edi), %ecx
+    movb (%ecx, %eax), %cl
+    movzx %cl, %ecx
+    
+    /* Allocate space on our stack */
+    subl %ecx, %esp
+    
+    /* Get pointer to function */
+    movl (%edi), %edi
+    movl (%edi, %eax, 4), %eax
 
-	/*  Copy the arguments from the user stack to the kernel stack  */
-	movl	%esp,%edi
-	cld
-	rep	movsb
+    /* Copy the arguments from the user stack to our stack */
+    shr $2, %ecx
+    movl %esp, %edi
+    cld
+    rep movsd
 
-	/*  DS is now also kernel segment  */
-	movw	%bx,%ds
+    /* Do the System Call */
+    call *%eax
+    movl %eax, KTRAP_FRAME_EAX(%ebp)
 
-	/* Call system call hook */
-//	pushl	%eax
-//	call	_KiSystemCallHook
-//	popl	%eax
+    /* Deallocate the kernel stack frame  */
+    movl %ebp, %esp
 
-	/* Call service check routine */
-	pushl	%eax
-	call	_KiServiceCheck
-	popl	%eax
-
-	/*  Make the system service call  */
-	movl	%es:_KeServiceDescriptorTableShadow + 16, %ecx
-	movl	%es:(%ecx, %eax, 4), %eax
-	call	*%eax
-	movl	%eax, KTRAP_FRAME_EAX(%ebp) /* save our return value in PKTRAP_FRAME->Eax */
-
-#if CHECKED
-	/* Bump Service Counter  */
-#endif
-
-KeDeallocateStackAndReturnFromSystemCallWithHook:
-	/* Deallocate the kernel stack frame  */
-	movl	%ebp,%esp
-
-KeReturnFromSystemCallWithHook:
-	/* Call the post system call hook and deliver any pending APCs */
-	pushl	%esp
-	call	_KiAfterSystemCallHook
-	addl	$4,%esp
-
 KeReturnFromSystemCall:
 
-	/* Restore the user context */
-	/* Get a pointer to the current thread */
-	movl	%fs:0x124, %esi
+    /* Get the Current Thread */
+    movl %fs:KPCR_CURRENT_THREAD, %esi
 
-	/* Restore the old trap frame pointer */
-	movl	KTRAP_FRAME_EDX(%esp), %ebx
-	movl	%ebx, KTHREAD_TRAP_FRAME(%esi)
+    /* Restore the old trap frame pointer */
+    movl KTRAP_FRAME_EDX(%esp), %ebx
+    movl %ebx, KTHREAD_TRAP_FRAME(%esi)
 
+_KiServiceExit:
+
+    /* Get the Current Thread */
+    movl %fs:KPCR_CURRENT_THREAD, %esi
+    
+    /* Deliver APCs only if we were called from user mode */
+    testb $1, KTRAP_FRAME_CS(%esp)
+    je KiRosTrapReturn
+    
+    /* And only if any are actually pending */
+    cmpb $0, KTHREAD_PENDING_USER_APC(%esi)
+    je KiRosTrapReturn
+    
+    /* Save pointer to Trap Frame */
+    movl %esp, %ebx
+    
+    /* Raise IRQL to HIGH_LEVEL */
+    movl $1, %ecx
+    call @KfRaiseIrql@4
+    
+    /* Save old IRQL */
+    pushl %eax
+    
+    /* Deliver APCs */
+    pushl %ebx
+    pushl $0
+    pushl $UserMode
+    call _KiDeliverApc@12
+    
+    /* Return to old IRQL */
+    popl %ecx
+    call @KfLowerIrql@4
+    
 KiRosTrapReturn:
+    
+    /* Skip debug information and unsaved registers */
+    addl $0x30, %esp                                                   // + 0x48
+    popl %gs                                                           // + 0x44
+    popl %es                                                           // + 0x40
+    popl %ds                                                           // + 0x3C
+    popl %edx                                                          // + 0x38
+    popl %ecx                                                          // + 0x34
+    popl %eax                                                          // + 0x30
 
-#if 0
-	mov	KTRAP_FRAME_RESERVED1(%ebp), %ax
-	cmp	%ax, SSIDX_NTCONTINUE
-	jnz	KeNoEpilogPrint
-	movl	KTRAP_FRAME_ESP(%ebp), %ecx
-	movl	KTRAP_FRAME_EBP(%ebp), %edx
-	call	@KeRosPrintEspEbp@8
-KeNoEpilogPrint:
-#endif
+    /* Restore the old previous mode */
+    popl %ebx                                                          // + 0x2C
+    movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
 
-	/* Skip debug information and unsaved registers */
-	addl	$0x30, %esp
-	popl	%gs
-	popl	%es
-	popl	%ds
-	popl	%edx
-	popl	%ecx
-	popl	%eax
+    /* Restore the old exception handler list */
+    popl %fs:KPCR_EXCEPTION_LIST                                       // + 0x28
 
-	/* Restore the old previous mode */
-	popl	%ebx
-	movb	%bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
+    /* Restore final registers from trap frame */
+    popl %fs                                                           // + 0x24
+    popl %edi                                                          // + 0x20
+    popl %esi                                                          // + 0x1C
+    popl %ebx                                                          // + 0x18
+    popl %ebp                                                          // + 0x14
+    add $4, %esp                                                       // + 0x10
 
-	/* Restore the old exception handler list */
-	popl	%ebx
-	movl	%ebx, %fs:KPCR_EXCEPTION_LIST
+    /* Check if previous CS is from user-mode */
+    testl $1, 4(%esp)
+    
+    /* It is, so use Fast Exit */
+    jnz FastRet
+    
+    /* 
+     * Restore what the stub pushed, and return back to it.
+     * Note that we were CALLed, so the first thing on our stack is the ret EIP!
+     */
+    pop %edx                                                           // + 0x0C
+    pop %ecx                                                           // + 0x08
+    popf                                                               // + 0x04
+    jmp *%edx
+          
+IntRet:
+    
+    iret
[truncated at 1000 lines; 1911 more skipped]