Author: sir_richard
Date: Tue Jan 26 16:43:13 2010
New Revision: 45266

URL: http://svn.reactos.org/svn/reactos?rev=45266&view=rev
Log:
[NTOS]: Implement a C/Extended ASM macro for generating trap stubs, removing 
the need to do this in ASM. The macro covers all possible entries, from 
SYSENTER to a fake sotware interrupt (needed for HAL changes later). By being 
somewhat in C, it makes the code cleaner to read and uses C expressions to make 
its decisions, making the code more maintanable as well. It also removes the 
need for separate assembly files.
[NTOS]: Modify the semantics of how a fast system call (SYSENTER) is processed 
in the stub, by moving more work in the C handler, such as setting up FS and 
getting the correct argument stack. Saves us some cycles too (and allows the 
trap stub macro to be more generic).

Modified:
    trunk/reactos/ntoskrnl/include/internal/ke.h
    trunk/reactos/ntoskrnl/include/internal/trap_x.h
    trunk/reactos/ntoskrnl/ke/i386/trap.s
    trunk/reactos/ntoskrnl/ke/i386/traphdlr.c

Modified: trunk/reactos/ntoskrnl/include/internal/ke.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/ke.h?rev=45266&r1=45265&r2=45266&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ke.h [iso-8859-1] Tue Jan 26 
16:43:13 2010
@@ -1100,13 +1100,6 @@
 );
 
 VOID
-KiSystemService(
-    IN PKTHREAD Thread,
-    IN PKTRAP_FRAME TrapFrame,
-    IN ULONG Instruction
-);
-
-VOID
 FASTCALL
 KiIdleLoop(
     VOID

Modified: trunk/reactos/ntoskrnl/include/internal/trap_x.h
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/trap_x.h?rev=45266&r1=45265&r2=45266&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/trap_x.h [iso-8859-1] Tue Jan 26 
16:43:13 2010
@@ -670,4 +670,120 @@
     /* Set debug header */
     KiFillTrapFrameDebug(TrapFrame);
 }
+
+//
+// Generates a Trap Prolog Stub for the given name
+//
+#define KI_PUSH_FAKE_ERROR_CODE 0x1
+#define KI_FAST_V86_TRAP        0x2
+#define KI_NONVOLATILES_ONLY    0x4
+#define KI_FAST_SYSTEM_CALL     0x8
+#define KI_SOFTWARE_TRAP        0x10
+#define KiTrap(x, y) VOID DECLSPEC_NORETURN x(VOID) { KiTrapStub(y, 
x##Handler); }
+
+//
+// Trap Prolog Stub
+//
+VOID
+DECLSPEC_NORETURN
+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) __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"
+    );
+    
+    /* 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) __asm__ __volatile__ ("popl 
%%eax\n":::"%esp");
+    
+    /* Now go ahead and make space for this frame */
+    __asm__ __volatile__ ("subl $%c[e],%%esp\n":: [e] "i"(FrameSize) : "%esp");
+        
+    /* Does the caller want volatiles only? */
+    if (Flags & KI_NONVOLATILES_ONLY) __asm__ __volatile__
+    (
+        /* Then only EBX, ESI, EDI and EBP are saved */
+        "movl %%ebx, %c[b](%%esp)\n"
+        "movl %%esi, %c[s](%%esp)\n"
+        "movl %%edi, %c[i](%%esp)\n"
+        "movl %%ebp, %c[p](%%esp)\n"
+        :
+        : [b] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebx)),
+          [s] "i"(FIELD_OFFSET(KTRAP_FRAME, Esi)),
+          [i] "i"(FIELD_OFFSET(KTRAP_FRAME, Edi)),
+          [p] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebp))
+        : "%esp"
+    );
+    else __asm__ __volatile__
+    (
+        /* Otherwise, we save all the registers (except ESP) */
+        "movl %%eax, %c[a](%%esp)\n"
+        "movl %%ebx, %c[b](%%esp)\n"
+        "movl %%ecx, %c[c](%%esp)\n"
+        "movl %%edx, %c[d](%%esp)\n"
+        "movl %%esi, %c[s](%%esp)\n"
+        "movl %%edi, %c[i](%%esp)\n"
+        "movl %%ebp, %c[p](%%esp)\n"
+        :
+        : [a] "i"(FIELD_OFFSET(KTRAP_FRAME, Eax)),
+          [b] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebx)),
+          [c] "i"(FIELD_OFFSET(KTRAP_FRAME, Ecx)),
+          [d] "i"(FIELD_OFFSET(KTRAP_FRAME, Edx)),
+          [s] "i"(FIELD_OFFSET(KTRAP_FRAME, Esi)),
+          [i] "i"(FIELD_OFFSET(KTRAP_FRAME, Edi)),
+          [p] "i"(FIELD_OFFSET(KTRAP_FRAME, Ebp))
+        : "%esp"
+    );
+
+    /* Now set parameter 1 (ECX) to point to the frame */
+    __asm__ __volatile__ ("movl %%esp, %%ecx\n":::"%esp");
+       
+    /* For Fast-V86 traps, move set parameter 2 (EDX) to hold EFlags */   
+    if (Flags & KI_FAST_V86_TRAP) __asm__ __volatile__
+    (
+        "movl %c[f](%%esp), %%edx\n"
+        :
+        : [f] "i"(FIELD_OFFSET(KTRAP_FRAME, EFlags))
+    );
+    
+    /* Now jump to the C handler */
+    __asm__ __volatile__ ("jmp %c[x]\n":: [x] "i"(Handler));
+    UNREACHABLE;
+}
+
 #endif

Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev=45266&r1=45265&r2=45266&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s [iso-8859-1] Tue Jan 26 16:43:13 2010
@@ -53,14 +53,6 @@
 idt _KiTrap0F,         INT_32_DPL0  /* INT 2F: RESERVED                     */
 GENERATE_IDT_STUBS                  /* INT 30-FF: UNEXPECTED INTERRUPTS     */
 
-/* Trap handlers referenced from C code                                     */
-.globl _KiTrap08
-.globl _KiTrap13
-
-/* System call code referenced from C code                                  */
-.globl _CopyParams
-.globl _ReadBatch
-
 /* System call entrypoints:                                                 */
 .globl _KiFastCallEntry
 .globl _KiSystemService
@@ -111,49 +103,6 @@
 /* SOFTWARE INTERRUPT SERVICES ***********************************************/
 .text
 
-.func KiSystemService
-_KiSystemService:
-
-    /* Make space for trap frame on the stack */
-    sub esp, KTRAP_FRAME_EIP
-
-    /* Save EBP, EBX, ESI, EDI only! */
-    mov [esp+KTRAP_FRAME_EBX], ebx
-    mov [esp+KTRAP_FRAME_ESI], esi
-    mov [esp+KTRAP_FRAME_EDI], edi
-    mov [esp+KTRAP_FRAME_EBP], ebp
-
-    /* Call C handler -- note that EDX is the caller stack, EAX is the ID */
-    mov ecx, esp
-    jmp _KiSystemServiceHandler
-.endfunc
-
-.func KiFastCallEntry
-_KiFastCallEntry:
-
-    /* Sane FS segment */
-    mov ecx, KGDT_R0_PCR
-    mov fs, cx
-    
-    /* Sane stack and frame */
-    mov esp, PCR[KPCR_TSS]
-    mov esp, [esp+KTSS_ESP0]
-    
-    /* Make space for trap frame on the stack */
-    sub esp, KTRAP_FRAME_V86_ES
-    
-    /* Save EBP, EBX, ESI, EDI only! */
-    mov [esp+KTRAP_FRAME_EBX], ebx
-    mov [esp+KTRAP_FRAME_ESI], esi
-    mov [esp+KTRAP_FRAME_EDI], edi
-    mov [esp+KTRAP_FRAME_EBP], ebp
-    
-    /* Call C handler -- note that EDX is the user stack, and EAX the syscall 
*/
-    mov ecx, esp
-    add edx, 8
-    jmp _KiFastCallEntryHandler
-.endfunc
-
 .func kei386eoihel...@0
 _kei386eoihel...@0:
 
@@ -191,32 +140,6 @@
 AbiosExit:
     /* FIXME: TODO */
     UNHANDLED_PATH
-
-GENERATE_TRAP_HANDLER KiGetTickCount, 1
-GENERATE_TRAP_HANDLER KiCallbackReturn, 1        
-GENERATE_TRAP_HANDLER KiRaiseAssertion, 1
-GENERATE_TRAP_HANDLER KiDebugService, 1
-
-/* HARDWARE TRAP HANDLERS ****************************************************/
-
-GENERATE_TRAP_HANDLER KiTrap00
-GENERATE_TRAP_HANDLER KiTrap01
-GENERATE_TRAP_HANDLER KiTrap03
-GENERATE_TRAP_HANDLER KiTrap04
-GENERATE_TRAP_HANDLER KiTrap05
-GENERATE_TRAP_HANDLER KiTrap06
-GENERATE_TRAP_HANDLER KiTrap07
-GENERATE_TRAP_HANDLER KiTrap08, 0
-GENERATE_TRAP_HANDLER KiTrap09
-GENERATE_TRAP_HANDLER KiTrap0A, 0
-GENERATE_TRAP_HANDLER KiTrap0B, 0
-GENERATE_TRAP_HANDLER KiTrap0C, 0
-GENERATE_TRAP_HANDLER KiTrap0D, 0, 1
-GENERATE_TRAP_HANDLER KiTrap0E, 0
-GENERATE_TRAP_HANDLER KiTrap0F
-GENERATE_TRAP_HANDLER KiTrap10
-GENERATE_TRAP_HANDLER KiTrap11
-GENERATE_TRAP_HANDLER KiTrap13
 
 /* UNEXPECTED INTERRUPT HANDLERS 
**********************************************/
 

Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.c?rev=45266&r1=45265&r2=45266&view=diff
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Tue Jan 26 16:43:13 
2010
@@ -1489,12 +1489,13 @@
     PKTHREAD Thread;
         
     /* Fixup segments */
+    Ke386SetFs(KGDT_R0_PCR);
     Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
     Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
     
     /* Set up a fake INT Stack and enable interrupts */
     TrapFrame->HardwareSegSs = KGDT_R3_DATA | RPL_MASK;
-    TrapFrame->HardwareEsp = (ULONG_PTR)Arguments - 8; // Stack is 2 frames 
down
+    TrapFrame->HardwareEsp = (ULONG_PTR)Arguments;
     TrapFrame->EFlags = __readeflags() | EFLAGS_INTERRUPT_MASK;
     TrapFrame->SegCs = KGDT_R3_CODE | RPL_MASK;
     TrapFrame->Eip = SharedUserData->SystemCallReturn;
@@ -1502,6 +1503,9 @@
     
     /* Get the current thread */
     Thread = KeGetCurrentThread();
+    
+    /* Arguments are actually 2 frames down (because of the double 
indirection) */
+    Arguments = (PVOID)(TrapFrame->HardwareEsp + 8);
 
     /* Call the shared handler (inline) */
     KiSystemCallHandler(TrapFrame,
@@ -1545,6 +1549,33 @@
                         Thread->PreviousMode,
                         SegFs);
 }
+
+/* CPU AND SOFTWARE TRAPS 
*****************************************************/
+
+KiTrap(KiTrap00,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap01,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap03,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap04,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap05,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap06,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap07,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap08,         0);
+KiTrap(KiTrap09,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap0A,         0);
+KiTrap(KiTrap0B,         0);
+KiTrap(KiTrap0C,         0);
+KiTrap(KiTrap0D,         KI_FAST_V86_TRAP);
+KiTrap(KiTrap0E,         0);
+KiTrap(KiTrap0F,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap10,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap11,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiTrap13,         KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiGetTickCount,   KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiCallbackReturn, KI_PUSH_FAKE_ERROR_CODE);       
+KiTrap(KiRaiseAssertion, KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiDebugService,   KI_PUSH_FAKE_ERROR_CODE);
+KiTrap(KiSystemService,  KI_PUSH_FAKE_ERROR_CODE | KI_NONVOLATILES_ONLY);
+KiTrap(KiFastCallEntry,  KI_FAST_SYSTEM_CALL);
 
 /* HARDWARE INTERRUPTS 
********************************************************/
 


Reply via email to