--- 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
--- 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! */