- Implement SYSCALL_PROLOG for the main handler and the three fast-system calls (ints 2b, 2c, 2d) which are not yet implemented.
- Document the macros.
Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S

Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S
--- trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S	2006-01-17 05:22:00 UTC (rev 20934)
+++ trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S	2006-01-17 05:54:35 UTC (rev 20935)
@@ -234,16 +234,124 @@
     SET_TF_DEBUG_HEADER
 
 //
-// @name TRAP_EPILOG
+// @name SYSCALL_PROLOG
 // 
-// This macro creates a standard trap entry prologue.
-// It should be used for entry into any kernel trap (KiTrapXx), but not for
-// system calls, which require special handling.
+// This macro creates a system call entry prologue.
+// It should be used for entry into any fast-system call (KiGetTickCount,
+// KiCallbackReturn, KiRaiseAssertion) and the generic system call handler
+// (KiSystemService)
 //
 // @param Label
-//        Identifying name of the caller function; will be used to append
-//        to the name V86 and DR helper functions, which must already exist.
+//        Unique label identifying the name of the caller function; will be
+//        used to append to the name of the DR helper function, which must
+//        already exist.
 //
+// @remark None.
+//
+.macro SYSCALL_PROLOG
+    /* Create a trap frame */
+    push 0
+    push ebp
+    push ebx
+    push esi
+    push edi
+    push fs
+
+    /* Load PCR Selector into fs */
+    mov ebx, KGDT_R0_PCR
+    mov fs, bx
+
+    /* Get a pointer to the current thread */
+    mov esi, [fs:KPCR_CURRENT_THREAD]
+
+    /* Save the previous exception list */
+    push [fs:KPCR_EXCEPTION_LIST]
+
+    /* Set the exception handler chain terminator */
+    mov dword ptr [fs:KPCR_EXCEPTION_LIST], -1
+
+    /* Save the old previous mode */
+    push ss:[esi+KTHREAD_PREVIOUS_MODE]
+
+    /* Skip the other registers */
+    sub esp, 0x48
+
+    /* Hack: it seems that on VMWare someone damages ES/DS on exit. Investigate! */
+    mov [esp+KTRAP_FRAME_DS], ds
+    mov [esp+KTRAP_FRAME_ES], es
+
+    /* Set the new previous mode based on the saved CS selector */
+    mov ebx, [esp+0x6C]
+    and ebx, 1
+    mov byte ptr ss:[esi+KTHREAD_PREVIOUS_MODE], bl
+
+    /* Go on the Kernel stack frame */
+    mov ebp, esp
+
+    /* Save the old trap frame pointer where EDX would be saved */
+    mov ebx, [esi+KTHREAD_TRAP_FRAME]
+    mov [ebp+KTRAP_FRAME_EDX], ebx
+
+    /* Flush DR7 */
+    and dword ptr [ebp+KTRAP_FRAME_DR7], 0
+
+    /* Check if the thread was being debugged */
+    test byte ptr [esi+KTHREAD_DEBUG_ACTIVE], 0xFF
+
+    /* Set the thread's trap frame and clear direction flag */
+    mov [esi+KTHREAD_TRAP_FRAME], ebp
+    cld
+
+    /* Save DR registers if needed */
+    //jnz Dr_kss_&Label
+
+    /* Set the trap frame debug header */
+    SET_TF_DEBUG_HEADER
+
+#ifdef DBG // FIXME: Is this for GDB? Can it be moved in the stub?
+    /*
+     * We want to know the address from where the syscall stub was called.
+     * If PrevMode is KernelMode, that address is stored in our own (kernel)
+     * stack, at location KTRAP_FRAME_ESP.
+     * If we're coming from UserMode, we load the usermode stack pointer
+     * and go back two frames (first frame is the syscall stub, second call
+     * is the caller of the stub).
+     */
+    mov edi, [ebp+KTRAP_FRAME_ESP]
+    test byte ptr [esi+KTHREAD_PREVIOUS_MODE], 0x01
+    jz 0f
+    mov edi, [edi+4]
+0:
+    mov [ebp+KTRAP_FRAME_DEBUGEIP], edi
+#endif
+
+    /* Enable interrupts */
+    sti
+.endm
+
+//
+// @name TRAP_EPILOG
+// 
+// This macro creates an epilogue for leaving any system trap.
+// It is used for exiting system calls, exceptions, interrupts and generic
+// traps.
+//
+// @param SystemCall
+//        Specifies whether this trap will exit a system call. If so, special
+//        code will be assembled to potentially use SYSEXIT instead of IRETD.
+//
+// @param RestorePreviousMode
+//        Specifies if the previous mode should be restored.
+//
+// @param RestoreSegments
+//        Specifies if the segment registers should be restored.
+//
+// @param RestoreVolatiles
+//        Specifies if the volatile registers should be restored.
+//
+// @param RestoreAllRegs
+//        Specifies if volatiles and segments should both be restored.
+//
 // @remark
 //
 .macro TRAP_EPILOG SystemCall, RestorePreviousMode, RestoreSegments, RestoreVolatiles, RestoreAllRegs

Modified: trunk/reactos/ntoskrnl/ke/i386/syscall.S
--- trunk/reactos/ntoskrnl/ke/i386/syscall.S	2006-01-17 05:22:00 UTC (rev 20934)
+++ trunk/reactos/ntoskrnl/ke/i386/syscall.S	2006-01-17 05:54:35 UTC (rev 20935)
@@ -13,22 +13,33 @@
 .globl _KiFastCallEntry
 .globl _KiSystemService
 .globl _KiDebugService
+.globl _Kei386EoiHelper@0
+.globl _NtRaiseException@12
+.globl _NtContinue@8
 .intel_syntax noprefix
 
 /*
   * FIXMEs:
   *         - Figure out why ES/DS gets messed up in VMWare, when doing KiServiceExit only,
   *           and only when called from user-mode, and returning to user-mode.
-  *         - Implement SYSCALL_PROLOG macro.
+  *         - Merge with trap.S and document all traps.
+  *         - Use MmProbe when copying arguments to syscall.
+  *         - Add DR macro/save and VM macro/save.
+  *         - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion
   */
 
- /*** This file is a mess; it is being worked on. Please contact Alex:
-  *** alex@relsoft.net if you want to make any changes to it before this
-  *** message goes away
-  */
-
 /* FUNCTIONS ***************************************************************/
 
+.func KiSystemService
+_KiSystemService:
+
+    /* Enter the shared system call prolog */
+    SYSCALL_PROLOG
+
+    /* Jump to the actual handler */
+    jmp SharedCode
+.endfunc
+
 BadStack:
 
     /* Restore ESP0 stack */
@@ -123,68 +134,12 @@
     /* Check if the thread was being debugged */
     test byte ptr [esi+KTHREAD_DEBUG_ACTIVE], 0xFF
 
-    /* Jump to shared code or DR Save */
-    //jnz Dr_FastCallDrSave
-    jmp SharedCode
-.endfunc
-
-.func KiSystemService
-_KiSystemService:
-
-// ==================== COMMON SYSTEM CALL CODE ============//
-    /* Create a trap frame */
-    push 0
-    push ebp
-    push ebx
-    push esi
-    push edi
-    push fs
-
-    /* Load PCR Selector into fs */
-    mov ebx, KGDT_R0_PCR
-    mov fs, bx
-
-    /* Get a pointer to the current thread */
-    mov esi, [fs:KPCR_CURRENT_THREAD]
-
-    /* Save the previous exception list */
-    push [fs:KPCR_EXCEPTION_LIST]
-
-    /* Set the exception handler chain terminator */
-    mov dword ptr [fs:KPCR_EXCEPTION_LIST], -1
-
-    /* Save the old previous mode */
-    push ss:[esi+KTHREAD_PREVIOUS_MODE]
-    
-    /* Skip the other registers */
-    sub esp, 0x48
-
-    /* Hack: it seems that on VMWare someone damages ES/DS on exit. Investigate! */
-    mov [esp+KTRAP_FRAME_DS], ds
-    mov [esp+KTRAP_FRAME_ES], es
-
-    /* Set the new previous mode based on the saved CS selector */
-    mov ebx, [esp+0x6C]
-    and ebx, 1
-    mov byte ptr ss:[esi+KTHREAD_PREVIOUS_MODE], bl
-
-    /* Go on the Kernel stack frame */
-    mov ebp, esp
-
-    /* Save the old trap frame pointer where EDX would be saved */
-    mov ebx, [esi+KTHREAD_TRAP_FRAME]
-    mov [ebp+KTRAP_FRAME_EDX], ebx
-
-    /* Flush DR7 */
-    and dword ptr [ebp+KTRAP_FRAME_DR7], 0
-
-    /* Check if the thread was being debugged */
-    test byte ptr [esi+KTHREAD_DEBUG_ACTIVE], 0xFF
-    //jnz Dr_kss_a
-
-SharedCode:
+    /* Set the thread's trap frame */
     mov [esi+KTHREAD_TRAP_FRAME], ebp
 
+    /* Save DR registers if needed */
+    //jnz Dr_FastCallDrSave
+
     /* Set the trap frame debug header */
     SET_TF_DEBUG_HEADER
 
@@ -208,7 +163,7 @@
     /* Enable interrupts */
     sti
 
-CheckValidCall:
+SharedCode:
 
     /*
      * Find out which table offset to use. Converts 0x1124 into 0x10.
@@ -389,14 +344,14 @@
     mov [esi+KTHREAD_TRAP_FRAME], ebp
 
     /* Try the Call again */
-    jmp CheckValidCall
+    jmp SharedCode
 
 InvalidCall:
 
     /* Invalid System Call */
     mov eax, STATUS_INVALID_SYSTEM_SERVICE
     jmp KeReturnFromSystemCall
-    
+
 #ifdef DBG
 InvalidIrql:
     /* Save current IRQL */
@@ -443,7 +398,6 @@
     TRAP_EPILOG NotFromSystemCall, DoRestorePreviousMode, DoRestoreSegments, DoRestoreVolatiles, DoNotRestoreEverything
 .endfunc
 
-.globl _Kei386EoiHelper@0
 .func Kei386EoiHelper@0
 _Kei386EoiHelper@0:
 
@@ -535,7 +489,6 @@
     /* Exit through common routine */
     jmp _Kei386EoiHelper@0
 
-.globl _NtRaiseException@12
 _NtRaiseException@12:
 
     /* NOTE: We -must- be called by Zw* to have the right frame! */
@@ -581,7 +534,6 @@
     /* Restore debug registers too */
     jmp _KiServiceExit
 
-.globl _NtContinue@8
 _NtContinue@8:
 
     /* NOTE: We -must- be called by Zw* to have the right frame! */