- Write the first of 3 shared trap prolog macros. Does not fully support V86 entry...
authorAlex Ionescu <aionescu@gmail.com>
Mon, 16 Jan 2006 21:14:32 +0000 (21:14 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Mon, 16 Jan 2006 21:14:32 +0000 (21:14 +0000)
- Update asm.h with more stuff from ks386.inc.
- Use only documented constants in syscall.S through asm.h.

svn path=/trunk/; revision=20921

reactos/include/ndk/asm.h
reactos/ntoskrnl/include/internal/i386/asmmacro.S
reactos/ntoskrnl/ke/i386/syscall.S
reactos/ntoskrnl/ke/i386/trap.s

index 241a9dc..0d0c662 100644 (file)
@@ -9,6 +9,7 @@ Header Name:
 Abstract:
 
     ASM Offsets for dealing with de-referencing structures in registers.
+    C-compatible version of the file ks386.inc present in the newest WDK.
 
 Author:
 
@@ -19,6 +20,12 @@ Author:
 #ifndef _ASM_H
 #define _ASM_H
 
+//
+// CPU Modes
+//
+#define KernelMode                              0x0
+#define UserMode                                0x1
+
 //
 // Selector Names
 //
@@ -200,6 +207,7 @@ Author:
 #define KTRAP_FRAME_SIZE                        0x8C
 #define KTRAP_FRAME_LENGTH                      0x8C
 #define KTRAP_FRAME_ALIGN                       0x04
+#define FRAME_EDITED                            0xFFF8
 
 //
 // KUSER_SHARED_DATA Offsets
@@ -345,6 +353,11 @@ Author:
 #define CBSTACK_RESULT                          0x20
 #define CBSTACK_RESULT_LENGTH                   0x24
 
+//
+// NTSTATUS Codes
+//
+#define STATUS_INVALID_SYSTEM_SERVICE           0xC000001C
+
 //
 // Generic Definitions
 //
index 45c7a9c..b7d8818 100644 (file)
 #define RELEASE_SPINLOCK(x) \r
 #endif\r
 \r
+//\r
+// SET_TF_DEBUG_HEADER\r
+// This macro sets up the debug header in the trap frame.\r
+// Assumptions:\r
+// ebp = PKTRAP_FRAME\r
+// edi/ebx = Have been saved and can be used\r
+//\r
+#define SET_TF_DEBUG_HEADER \\r
+    /* Get the Debug Trap Frame EBP/EIP */ \\r
+    mov ebx, [ebp+KTRAP_FRAME_EBP]; \\r
+    mov edi, [ebp+KTRAP_FRAME_EIP]; \\r
+\\r
+    /* Write the debug data */ \\r
+    mov [ebp+KTRAP_FRAME_DEBUGPOINTER], edx; \\r
+    mov dword ptr [ebp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00; \\r
+    mov [ebp+KTRAP_FRAME_DEBUGEBP], ebx; \\r
+    mov [ebp+KTRAP_FRAME_DEBUGEIP], edi;\r
+\r
 //\r
 // These macros control common execution paths for Traps and System Call Code\r
-// TODO\r
 //\r
+// TRAP_PROLOG\r
+// This macro creates a standard trap entry prologue.\r
+// It should be used for entry into any kernel trap (KiTrapXx), but not for\r
+// system calls, which require special handling.\r
+//\r
+// Use as follows:\r
+// _KiTrap00:\r
+// /* Push fake error code */\r
+// push 0\r
+//\r
+// /* Enter common prologue */\r
+// TRAP_PROLOG(0)\r
+//\r
+// /* Handle trap */\r
+// <Your Trap Code Here>\r
+//\r
+#define TRAP_PROLOG(Label) \\r
+    /* Just to be safe, clear out the HIWORD, since it's reserved */ \\r
+    mov word ptr [esp+2], 0; \\r
+\\r
+    /* Save the non-volatiles */ \\r
+    push ebp; \\r
+    push ebx; \\r
+    push esi; \\r
+    push edi; \\r
+\\r
+    /* Save FS and set it to PCR */ \\r
+    push fs; \\r
+    mov ebx, KGDT_R0_PCR; \\r
+    mov fs, bx; \\r
+\\r
+    /* Save exception list and bogus previous mode */ \\r
+    push fs:[KPCR_EXCEPTION_LIST]; \\r
+    push -1; \\r
+\\r
+    /* Save volatiles and segment registers */ \\r
+    push eax; \\r
+    push ecx; \\r
+    push edx; \\r
+    push ds; \\r
+    push es; \\r
+    push gs; \\r
+\\r
+    /* Set the R3 data segment */ \\r
+    mov ax, KGDT_R3_DATA + RPL_MASK; \\r
+\\r
+    /* Skip debug registers and debug stuff */ \\r
+    sub esp, 0x30; \\r
+\\r
+    /* Load the segment registers */ \\r
+    mov ds, ax; \\r
+    mov es, ax; \\r
+\\r
+    /* Set up frame */ \\r
+    mov ebp, esp; \\r
+\\r
+    /* Check if this was from V86 Mode */ \\r
+    /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK; */ \\r
+    /* jnz V86_Label; */ \\r
+\\r
+    /* Get current thread */ \\r
+    mov ecx, [fs:KPCR_CURRENT_THREAD]; \\r
+    cld; \\r
+\\r
+    /* Flush DR7 */ \\r
+    and dword ptr [ebp+KTRAP_FRAME_DR7], 0; \\r
+\\r
+    /* Check if the thread was being debugged */ \\r
+    /* test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF; */ \\r
+    /* jnz Dr_Label; */ \\r
+\\r
+    /* Set the Trap Frame Debug Header */ \\r
+    SET_TF_DEBUG_HEADER\r
+\r
+\r
 \r
index b27d08e..462f786 100644 (file)
@@ -5,12 +5,8 @@
  * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)
  */
 
-#include <roscfg.h>
-#include <internal/i386/ke.h>
-#include <ndk/asm.h>
-
-#define UserMode  (1)
-#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
+#include <asm.h>
+#include <internal/i386/asmmacro.S>
 
 .globl _KiServiceExit
 .globl _KiServiceExit2
 .intel_syntax noprefix
 
 /*
- * NOTE: I will create some macros for trap entry and exit,
- * DR* register restoration, modified frame exit, etc, if GAS
- * allows it/I find a way how. This would remove a lot of
- * duplicated code in this file plus the other irq/trap asm files.
- * I think this is similar to what NT does, if you look at teh
- * Dr_kit*_a functions which look auto-generated.
+ * There are 3 main types of Trap Entries:
+ *
+ * - System Calls
+ *     - TODO
+ *
+ * - Exceptions
+ *     - TODO
+ *
+ * - Interrupts
+ *     - TODO
  */
-
 /*
  * There are 3 main types of Trap Exits:
  *
   *         - Use macros and merge with trap.s nicely
   */
 
-/*
- * Entries will be discussed later.
- */
  /*** 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
@@ -132,7 +128,7 @@ _KiFastCallEntry:
     push 2                              /* Ring 0 EFLAGS */
     add edx, 8                          /* Skip user parameter list */
     popf                                /* Set our EFLAGS */
-    or dword ptr [esp], X86_EFLAGS_IF   /* Re-enable IRQs in EFLAGS, to fake INT */
+    or dword ptr [esp], EFLAGS_INTERRUPT_MASK   /* Re-enable IRQs in EFLAGS, to fake INT */
     push KGDT_R3_CODE + RPL_MASK
     push KUSER_SHARED_SYSCALL_RET
 
@@ -386,7 +382,7 @@ _KiServiceExit:
 
 // ================= COMMON USER-MODE APC DELIVERY CHECK ============//
     /* Check for V86 mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
+    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz ApcLoop
 
     /* Deliver APCs only if we were called from user mode */
@@ -454,7 +450,7 @@ KiRosTrapReturn:
 // ==================== END IF PREVIOUS MODE NEEDED ===================//
 
     /* Check for V86 */
-    test dword ptr [esp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
+    test dword ptr [esp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz V86_Exit
 
     /* Check if the frame was edited */
@@ -467,6 +463,8 @@ KiRosTrapReturn:
     bt word ptr [esp+KTRAP_FRAME_CS], 0
     cmc
     ja RestoreAll
+    cmp dword ptr [ebp+KTRAP_FRAME_CS], KGDT_R0_CODE
+    jz CommonStackClean
 // ==================== END IF FULL RESTORE NEEDED ====================//
 
 //badbadbad     
@@ -518,7 +516,7 @@ FastRet:
     /* Is SYSEXIT Supported/Wanted? */
     cmp dword ptr ss:[_KiFastSystemCallDisable], 0
     jnz IntRet
-    test dword ptr [esp+8], X86_EFLAGS_TF
+    test dword ptr [esp+8], EFLAGS_TF
     jnz IntRet
 
     /* Restore FS to TIB */
@@ -528,7 +526,7 @@ FastRet:
     /* We will be cleaning up the stack ourselves */
     pop edx                                 /* New Ring 3 EIP */
     add esp, 4                              /* Skip Ring 3 DS */
-/*  and dword ptr [esp], ~X86_EFLAGS_IF        Line below is equivalent to this,
+/*  and dword ptr [esp], ~EFLAGS_INTERRUPT_MASK        Line below is equivalent to this,
                                                but older binutils versions don't understand ~ */
     and dword ptr [esp], 0xfffffdff         /* Remove IRQ hack from EFLAGS */
     popf                                    /* Restore old EFLAGS */
@@ -647,7 +645,7 @@ _KiServiceExit2:
     cli
 
     /* Check for V86 mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
+    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz ApcLoop2
 
     /* Deliver APCs only if we were called from user mode */
@@ -700,7 +698,7 @@ KiRosTrapReturn2:
     mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], cl
 
     /* Check for V86 */
-    test dword ptr [esp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
+    test dword ptr [esp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz V86_Exit
 
     /* Check if the frame was edited */
@@ -779,65 +777,11 @@ EditedFrame2:
 
 _KiDebugService:
 
-    /* Create the Trap Frame */
+    /* Push error code */
     push 0
-    push ebp
-    push ebx
-    push esi
-    push edi
-    push fs
-
-    /* Switch to correct FS */
-    mov bx, KGDT_R0_PCR
-    mov fs, bx
-
-    /* Save Exception List */
-    push fs:[KPCR_EXCEPTION_LIST]
-
-    /* Traps don't need the previous mode */
-    sub esp, 4
-
-    /* Continue building the Trap Frame */
-    push eax
-    push ecx
-    push edx
-    push ds
-    push es
-    push gs
-    sub esp, 0x30
 
-    /* Switch Segments to Kernel */
-    mov ax, KGDT_R0_DATA
-    mov ds, ax
-    mov es, ax
-
-    /* Set up frame */
-    mov ebp, esp
-
-    /* Check if this was from V86 Mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
-    //jnz V86_kids
-
-    /* Get current thread */
-    mov ecx, [fs:KPCR_CURRENT_THREAD]
-    cld
-
-    /* Flush DR7 */
-    and dword ptr [ebp+KTRAP_FRAME_DR7], 0
-
-    /* Check if the thread was being debugged */
-    test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF
-    //jnz Dr_kids
-
-    /* Get the Debug Trap Frame EBP/EIP */
-    mov ebx, [ebp+KTRAP_FRAME_EBP]
-    mov edi, [ebp+KTRAP_FRAME_EIP]
-
-    /* Write the debug data */
-    mov [ebp+KTRAP_FRAME_DEBUGPOINTER], edx
-    mov dword ptr [ebp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00
-    mov [ebp+KTRAP_FRAME_DEBUGEBP], ebx
-    mov [ebp+KTRAP_FRAME_DEBUGEIP], edi
+    /* Enter trap */
+    TRAP_PROLOG(kids)
 
     /* Increase EIP so we skip the INT3 */
     //inc dword ptr [ebp+KTRAP_FRAME_EIP]
@@ -848,7 +792,7 @@ _KiDebugService:
     mov edx, [ebp+KTRAP_FRAME_EAX]
 
     /* Check for V86 mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
+    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz NotUserMode
 
     /* Check if this is kernel or user-mode */
@@ -892,7 +836,7 @@ Kei386EoiHelper@0:
     cli
 
     /* Check for V86 mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
+    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz ApcLoop3
 
     /* Deliver APCs only if we were called from user mode */
@@ -940,7 +884,7 @@ KiRosTrapReturn3:
     mov [fs:KPCR_EXCEPTION_LIST], edx
 
     /* Check for V86 */
-    test dword ptr [esp+KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
+    test dword ptr [esp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
     jnz V86_Exit
 
     /* Check if the frame was edited */
index 4668cd6..d70875c 100644 (file)
  * FILE:            ntoskrnl/ke/i386/trap.s
  * PURPOSE:         Exception handlers
  * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
- *                  David Welch <welch@cwcom.net>
  */
 
 /* INCLUDES ******************************************************************/
 
-#include <ndk/asm.h>
+#include <asm.h>
+#include <internal/i386/asmmacro.S>
 
 /* NOTES:
- * The prologue is currently a duplication of the trap enter code in KiDebugService.
- * It will be made a macro and shared later.
+ * Why not share the epilogue?
+ * 1) An extra jmp is expensive (jmps are very costly)
+ * 2) Eventually V86 exit should be handled through ABIOS, and we
+ *    handle ABIOS exit in the shared trap exit code already.
+ * Why not share the KiTrapHandler call?
+ * 1) Would make using the trap-prolog macro much harder.
+ * 2) Eventually some of these traps might be re-implemented in assembly
+ *    to improve speed and depend less on the compiler and/or use features
+ *    not present as C keywords. When that happens, less traps will use the
+ *    shared C handler, so the shared-code would need to be un-shared.
  */
 
 /* FUNCTIONS *****************************************************************/
 
-/*
- * Epilog for exception handlers
- */
-_KiTrapEpilog:
-       cmpl    $1, %eax       /* Check for v86 recovery */
-       jne     Kei386EoiHelper@0
-       jmp     _KiV86Complete
-
-.globl _KiTrapProlog
-_KiTrapProlog: 
-       movl    $_KiTrapHandler, %ebx
-       
-.global _KiTrapProlog2
-_KiTrapProlog2:
-       pushl   %edi
-       pushl   %fs
-
-.intel_syntax noprefix
-    /* Load the PCR selector into fs */
-    mov edi, KGDT_R0_PCR
-    mov fs, di
-
-    /* Push exception list and previous mode (invalid) */
-    push fs:[KPCR_EXCEPTION_LIST]
-    push -1
-
-    /* Push volatiles and segments */
-    push eax
-    push ecx
-    push edx
-    push ds
-    push es
-    push gs
-
-    /* Set the R3 data segment */
-    mov ax, KGDT_R3_DATA + RPL_MASK
-
-    /* Skip debug registers and debug stuff */
-    sub esp, 0x30
-
-    /* Load the segment registers */
-    mov ds, ax
-    mov es, ax
-
-    /* Set up frame */
-    mov ebp, esp
-
-    /* Check if this was from V86 Mode */
-    test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
-    //jnz V86_kids
-
-    /* Get current thread */
-    mov ecx, [fs:KPCR_CURRENT_THREAD]
-    cld
-
-    /* Flush DR7 */
-    and dword ptr [ebp+KTRAP_FRAME_DR7], 0
-
-    /* Check if the thread was being debugged */
-    //test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF
-    //jnz Dr_kids
-
-    /* Get the Debug Trap Frame EBP/EIP */
-    mov ecx, [ebp+KTRAP_FRAME_EBP]
-    mov edi, [ebp+KTRAP_FRAME_EIP]
-
-    /* Write the debug data */
-    mov [ebp+KTRAP_FRAME_DEBUGPOINTER], edx
-    mov dword ptr [ebp+KTRAP_FRAME_DEBUGARGMARK], 0xBADB0D00
-    mov [ebp+KTRAP_FRAME_DEBUGEBP], ecx
-    mov [ebp+KTRAP_FRAME_DEBUGEIP], edi
-.att_syntax
-
-.L6:   
-       
-       /* Call the C exception handler */
-       pushl   %esi
-       pushl   %ebp
-       call    *%ebx
-       addl    $8, %esp
-
-       /* Return to the caller */
-       jmp     _KiTrapEpilog
-
 .globl _KiTrap0
 _KiTrap0:
-       /* No error code */
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $0, %esi
-       jmp     _KiTrapProlog
-                               
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(0)
+
+    /* Call the C exception handler */
+    push 0
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
+
 .globl _KiTrap1
 _KiTrap1:
-       /* No error code */
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $1, %esi
-       jmp     _KiTrapProlog
-       
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(1)
+
+    /* Call the C exception handler */
+    push 1
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
+
 .globl _KiTrap2
 _KiTrap2:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $2, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(2)
+
+    /* Call the C exception handler */
+    push 2
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap3
 _KiTrap3:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $3, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(3)
+
+    /* Call the C exception handler */
+    push 3
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap4
 _KiTrap4:
-        pushl  $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $4, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(4)
+
+    /* Call the C exception handler */
+    push 4
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap5
 _KiTrap5:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $5, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(5)
+
+    /* Call the C exception handler */
+    push 5
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap6
 _KiTrap6:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $6, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(6)
+
+    /* Call the C exception handler */
+    push 6
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap7
 _KiTrap7:
-        pushl  $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $7, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(7)
+
+    /* Call the C exception handler */
+    push 7
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap8
 _KiTrap8:
-       call    _KiDoubleFaultHandler
-       iret
+    call _KiDoubleFaultHandler
+    iret
 
 .globl _KiTrap9
 _KiTrap9:
-        pushl  $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $9, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(9)
+
+    /* Call the C exception handler */
+    push 9
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap10
 _KiTrap10:
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $10, %esi
-       jmp     _KiTrapProlog
+    /* Enter trap */
+    TRAP_PROLOG(10)
+
+    /* Call the C exception handler */
+    push 10
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap11
 _KiTrap11:
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $11, %esi
-       jmp     _KiTrapProlog
+    /* Enter trap */
+    TRAP_PROLOG(11)
+
+    /* Call the C exception handler */
+    push 11
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap12
 _KiTrap12:
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $12, %esi
-       jmp     _KiTrapProlog
+    /* Enter trap */
+    TRAP_PROLOG(12)
+
+    /* Call the C exception handler */
+    push 12
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap13
 _KiTrap13:
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $13, %esi
-       jmp     _KiTrapProlog
+    /* Enter trap */
+    TRAP_PROLOG(13)
+
+    /* Call the C exception handler */
+    push 13
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+    
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap14
 _KiTrap14:
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $14, %esi
-       movl    $_KiPageFaultHandler, %ebx
-       jmp     _KiTrapProlog2
+    /* Enter trap */
+    TRAP_PROLOG(14)
+
+    /* Call the C exception handler */
+    push 14
+    push ebp
+    call _KiPageFaultHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap15
 _KiTrap15:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $15, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(15)
+
+    /* Call the C exception handler */
+    push 15
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap16
 _KiTrap16:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $16, %esi
-       jmp     _KiTrapProlog
-        
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(16)
+
+    /* Call the C exception handler */
+    push 16
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
+
 .globl _KiTrap17
 _KiTrap17:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $17, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(17)
+
+    /* Call the C exception handler */
+    push 17
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap18
 _KiTrap18:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $18, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(18)
+
+    /* Call the C exception handler */
+    push 18
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrap19
 _KiTrap19:
-       pushl   $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $19, %esi
-       jmp     _KiTrapProlog
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(19)
+
+    /* Call the C exception handler */
+    push 19
+    push ebp
+    call _KiTrapHandler
+    add esp, 8
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
 
 .globl _KiTrapUnknown
 _KiTrapUnknown:
-        pushl  $0
-       pushl   %ebp
-       pushl   %ebx
-       pushl   %esi
-       movl    $255, %esi
-       jmp     _KiTrapProlog
-
-.intel_syntax noprefix
+    /* Push error code */
+    push 0
+
+    /* Enter trap */
+    TRAP_PROLOG(255)
+
+    /* Check for v86 recovery */
+    cmp eax, 1
+
+    /* Return to caller */
+    jne Kei386EoiHelper@0
+    jmp _KiV86Complete
+
 .globl _KiCoprocessorError@0
 _KiCoprocessorError@0: