#define DoRestoreSegments 1
#define DoRestoreVolatiles 1
#define DoPushFakeErrorCode 1
+#define DoFixupV86 1
+#define DoFixupAbios 1
#define NotFromSystemCall 0
#define DoNotRestorePreviousMode 0
#define DoNotRestoreEverything 0
#define DoNotRestoreSegments 0
#define DoNotRestoreVolatiles 0
#define DoNotPushFakeErrorCode 0
+#define DoNotFixupV86 0
+#define DoNotFixupAbios 0
// Arguments for idt
#define INT_32_DPL0 0x8E00
.endm
//
-// @name V86_TRAP_FIXUP
+// @name TRAP_FIXUPS
//
-// This macro sets up the debug header in the trap frame.
+// This macro contains out-of-line code for various Trap Frame Fixups, such as:
//
-// @param None.
-//
-// @remark ebp = PKTRAP_FRAME
-//
-.macro V86_TRAP_FIXUP
- /* Get V86 segment registers */
- mov eax, [ebp+KTRAP_FRAME_V86_FS]
- mov ebx, [ebp+KTRAP_FRAME_V86_GS]
- mov ecx, [ebp+KTRAP_FRAME_V86_ES]
- mov edx, [ebp+KTRAP_FRAME_V86_DS]
-
- /* Restore them into Protected Mode trap frame */
- mov [ebp+KTRAP_FRAME_FS], ax
- mov [ebp+KTRAP_FRAME_GS], bx
- mov [ebp+KTRAP_FRAME_ES], cx
- mov [ebp+KTRAP_FRAME_DS], dx
-
- /* Go back to mainline code */
- jmp 1f
-.endm
-
-//
-// @name DR_TRAP_FIXUP
-//
-// This macro sets up the debug header in the trap frame.
+// - DR Fixup: Loads and restores DR registers.
+// - V86 Fixup: Loads and restores V86 segments.
+// - ABIOS Fixup: Loads and restores the ABIOS state and stack.
//
// @param None.
//
// @remark ebp = PKTRAP_FRAME
//
-.macro DR_TRAP_FIXUP
+.macro TRAP_FIXUPS Label, EndLabel, V86Fix, AbiosFix
+Dr_&Label:
+
/* Check if this was V86 mode */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz 2f
/* Check if it was user mode */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
- jz 3f
+ jz Dr_&EndLabel
2:
/* Get DR0, 1, 2 */
/* Set them */
mov dr6, ebx
mov dr7, ecx
- jmp 3f
+ jmp Dr_&EndLabel
+
+.if \AbiosFix
+Abios_&Label:
+ UNHANDLED_PATH
+.endif
+
+.if \V86Fix
+V86_&Label:
+
+ /* Get V86 segment registers */
+ mov eax, [ebp+KTRAP_FRAME_V86_FS]
+ mov ebx, [ebp+KTRAP_FRAME_V86_GS]
+ mov ecx, [ebp+KTRAP_FRAME_V86_ES]
+ mov edx, [ebp+KTRAP_FRAME_V86_DS]
+
+ /* Restore them into Protected Mode trap frame */
+ mov [ebp+KTRAP_FRAME_FS], ax
+ mov [ebp+KTRAP_FRAME_GS], bx
+ mov [ebp+KTRAP_FRAME_ES], cx
+ mov [ebp+KTRAP_FRAME_DS], dx
+
+ /* Go back to mainline code */
+ jmp V86_&EndLabel
+.endif
.endm
//
// /* Handle trap */
// <Your Trap Code Here>
//
-.macro TRAP_PROLOG Label
+.macro TRAP_PROLOG Label EndLabel
/* Just to be safe, clear out the HIWORD, since it's reserved */
mov word ptr [esp+2], 0
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
jnz V86_&Label
-1:
+V86_&EndLabel:
/* Get current thread */
mov ecx, PCR[KPCR_CURRENT_THREAD]
cld
jnz Dr_&Label
/* Set the Trap Frame Debug Header */
-3:
+Dr_&EndLabel:
SET_TF_DEBUG_HEADER
.endm
//
// @remark For software interrupts, make sure that a fake INT stack is created.
//
-.macro INT_PROLOG Label FakeErrorCode
+.macro INT_PROLOG Label EndLabel FakeErrorCode
.if \FakeErrorCode
/* Save fake error code */
jnz V86_&Label
/* Check if this was kernel mode */
-1:
+V86_&EndLabel:
cmp word ptr [esp+KTRAP_FRAME_CS], KGDT_R0_CODE
jz 1f
jnz Dr_&Label
/* Set the trap frame debug header */
-3:
+Dr_&EndLabel:
SET_TF_DEBUG_HEADER
.endm
//
// @remark None.
//
-.macro SYSCALL_PROLOG Label
+.macro SYSCALL_PROLOG Label EndLabel
/* Create a trap frame */
push 0
push ebp
jnz Dr_&Label
/* Set the trap frame debug header */
-3:
+Dr_&EndLabel:
SET_TF_DEBUG_HEADER
/* Enable interrupts */
//
// @remark None.
//
-.macro FASTCALL_PROLOG Label
+.macro FASTCALL_PROLOG Label EndLabel
/* Set FS to PCR */
mov ecx, KGDT_R0_PCR
mov fs, cx
jnz Dr_&Label
/* Set the trap frame debug header */
-3:
+Dr_&EndLabel:
SET_TF_DEBUG_HEADER
/* Enable interrupts */
//
// @remark None.
//
-.macro V86_TRAP_PROLOG Label
+.macro V86_TRAP_PROLOG Label EndLabel
/* Skip everything to the error code */
sub esp, KTRAP_FRAME_ERROR_CODE
mov eax, dr7
test eax, ~DR7_RESERVED_MASK
mov [esp+KTRAP_FRAME_DR7], eax
- // jnz Dr_&Label
+ jnz Dr_&Label
+
+Dr_&EndLabel:
.endm
//
/* Check if DR registers should be restored */
test dword ptr [ebp+KTRAP_FRAME_DR7], ~DR7_RESERVED_MASK
- //jnz V86DebugRestore
+ jnz V86DebugRestore
/* Finish popping the rest of the frame, and return to P-mode */
+V86DebugContinue:
add esp, 12
pop edi
pop esi
add esp, 4
iretd
+V86DebugRestore:
+
+ /* Get DR0, 1 */
+ xor ebx, ebx
+ mov esi, [ebp+KTRAP_FRAME_DR0]
+ mov edi, [ebp+KTRAP_FRAME_DR1]
+
+ /* Clear DR 7 */
+ mov dr7, ebx
+
+ /* Get DR2 and load DR0-2 */
+ mov ebx, [ebp+KTRAP_FRAME_DR2]
+ mov dr0, esi
+ mov dr1, edi
+ mov dr2, ebx
+
+ /* Get DR3-7 */
+ mov esi, [ebp+KTRAP_FRAME_DR0]
+ mov edi, [ebp+KTRAP_FRAME_DR1]
+ mov ebx, [ebp+KTRAP_FRAME_DR7]
+
+ /* Load them */
+ mov dr3, esi
+ mov dr6, edi
+ mov dr7, ebx
+ jmp V86DebugContinue
+
PendingUserApc:
/* Raise to APC level */
/* Check for debug registers */
test dword ptr [esp+KTRAP_FRAME_DR7], ~DR7_RESERVED_MASK
- //jnz 2f
+ jnz 2f
/* Check for V86 */
4:
UNHANDLED_PATH
.func KiSystemService
-Dr_kss: DR_TRAP_FIXUP
+TRAP_FIXUPS kss_a, kss_t, DoNotFixupV86, DoNotFixupAbios
_KiSystemService:
/* Enter the shared system call prolog */
- SYSCALL_PROLOG kss
+ SYSCALL_PROLOG kss_a, kss_t
/* Jump to the actual handler */
jmp SharedCode
.endfunc
.func KiFastCallEntry
-Dr_FastCallDrSave: DR_TRAP_FIXUP
+TRAP_FIXUPS FastCallDrSave, FastCallDrReturn, DoNotFixupV86, DoNotFixupAbios
_KiFastCallEntry:
/* Enter the fast system call prolog */
- FASTCALL_PROLOG FastCallDrSave
+ FASTCALL_PROLOG FastCallDrSave, FastCallDrReturn
SharedCode:
UNHANDLED_PATH
.func KiDebugService
-Dr_kids: DR_TRAP_FIXUP
-V86_kids: V86_TRAP_FIXUP
+TRAP_FIXUPS kids_a, kids_t, DoFixupV86, DoFixupAbios
_KiDebugService:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kids
+ TRAP_PROLOG kids_a, kids_t
/* Increase EIP so we skip the INT3 */
inc dword ptr [ebp+KTRAP_FRAME_EIP]
.endfunc
.func KiTrap0
-Dr_kit0: DR_TRAP_FIXUP
-V86_kit0: V86_TRAP_FIXUP
+TRAP_FIXUPS kit0_a, kit0_t, DoFixupV86, DoNotFixupAbios
_KiTrap0:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit0
+ TRAP_PROLOG kit0_a, kit0_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
.endfunc
.func KiTrap1
-Dr_kit1: DR_TRAP_FIXUP
-V86_kit1: V86_TRAP_FIXUP
+TRAP_FIXUPS kit1_a, kit1_t, DoFixupV86, DoNotFixupAbios
_KiTrap1:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit1
+ TRAP_PROLOG kit1_a, kit1_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
.endfunc
.func KiTrap3
-Dr_kit3: DR_TRAP_FIXUP
-V86_kit3: V86_TRAP_FIXUP
+TRAP_FIXUPS kit3_a, kit3_t, DoFixupV86, DoNotFixupAbios
_KiTrap3:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit3
+ TRAP_PROLOG kit3_a, kit3_t
/* Set status code */
mov eax, 0 //STATUS_SUCCESS
.endfunc
.func KiTrap4
-Dr_kit4: DR_TRAP_FIXUP
-V86_kit4: V86_TRAP_FIXUP
+TRAP_FIXUPS kit4_a, kit4_t, DoFixupV86, DoNotFixupAbios
_KiTrap4:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit4
+ TRAP_PROLOG kit4_a, kit4_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
.endfunc
.func KiTrap5
-Dr_kit5: DR_TRAP_FIXUP
-V86_kit5: V86_TRAP_FIXUP
+TRAP_FIXUPS kit5_a, kit5_t, DoFixupV86, DoNotFixupAbios
_KiTrap5:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit5
+ TRAP_PROLOG kit5_a, kit5_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
.endfunc
.func KiTrap6
-Dr_kit6: DR_TRAP_FIXUP
-V86_kit6: V86_TRAP_FIXUP
+TRAP_FIXUPS kit6_a, kit6_t, DoFixupV86, DoNotFixupAbios
_KiTrap6:
/* It this a V86 GPF? */
jz NotV86UD
/* Enter V86 Trap */
- V86_TRAP_PROLOG kit6
+ V86_TRAP_PROLOG kit6_a, kit6_v
/* Not yet supported (Invalid OPCODE from V86) */
UNHANDLED_PATH
push 0
/* Enter trap */
- TRAP_PROLOG kit6
+ TRAP_PROLOG kit6_a, kit6_t
/* Check if this happened in kernel mode */
test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
.endfunc
.func KiTrap7
-Dr_kit7: DR_TRAP_FIXUP
-V86_kit7: V86_TRAP_FIXUP
+TRAP_FIXUPS kit7_a, kit7_t, DoFixupV86, DoNotFixupAbios
_KiTrap7:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit7
+ TRAP_PROLOG kit7_a, kit7_t
/* Get the current thread and stack */
StartTrapHandle:
.endfunc
.func KiTrap9
-Dr_kit9: DR_TRAP_FIXUP
-V86_kit9: V86_TRAP_FIXUP
+TRAP_FIXUPS kit9_a, kit9_t, DoFixupV86, DoNotFixupAbios
_KiTrap9:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit9
+ TRAP_PROLOG kit9_a, kit9_t
/* Enable interrupts and bugcheck */
sti
.endfunc
.func KiTrap10
-Dr_kit10: DR_TRAP_FIXUP
-V86_kit10: V86_TRAP_FIXUP
+TRAP_FIXUPS kita_a, kita_t, DoFixupV86, DoNotFixupAbios
_KiTrap10:
/* Enter trap */
- TRAP_PROLOG kit10
+ TRAP_PROLOG kita_a, kita_t
/* Check for V86 */
test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
.endfunc
.func KiTrap11
-Dr_kit11: DR_TRAP_FIXUP
-V86_kit11: V86_TRAP_FIXUP
+TRAP_FIXUPS kitb_a, kitb_t, DoFixupV86, DoNotFixupAbios
_KiTrap11:
/* Enter trap */
- TRAP_PROLOG kit11
+ TRAP_PROLOG kitb_a, kitb_t
/* FIXME: ROS Doesn't handle segment faults yet */
mov eax, 11
.endfunc
.func KiTrap12
-Dr_kit12: DR_TRAP_FIXUP
-V86_kit12: V86_TRAP_FIXUP
+TRAP_FIXUPS kitc_a, kitc_t, DoFixupV86, DoNotFixupAbios
_KiTrap12:
/* Enter trap */
- TRAP_PROLOG kit12
+ TRAP_PROLOG kitc_a, kitc_t
/* FIXME: ROS Doesn't handle stack faults yet */
mov eax, 12
.endfunc
.func KiTrap13
-Dr_kitd: DR_TRAP_FIXUP
-V86_kitd: V86_TRAP_FIXUP
+TRAP_FIXUPS kitd_a, kitd_t, DoFixupV86, DoNotFixupAbios
_KiTrap13:
/* It this a V86 GPF? */
jz NotV86
/* Enter V86 Trap */
- V86_TRAP_PROLOG kitd
+ V86_TRAP_PROLOG kitd_a, kitd_v
/* Make sure that this is a V86 process */
mov ecx, PCR[KPCR_CURRENT_THREAD]
NotV86:
/* Enter trap */
- TRAP_PROLOG kitd
+ TRAP_PROLOG kitd_a, kitd_t
/* Check if this was from kernel-mode */
test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK
.endfunc
.func KiTrap14
-Dr_kit14: DR_TRAP_FIXUP
-V86_kit14: V86_TRAP_FIXUP
+TRAP_FIXUPS kite_a, kite_t, DoFixupV86, DoNotFixupAbios
_KiTrap14:
/* Enter trap */
- TRAP_PROLOG kit14
+ TRAP_PROLOG kite_a, kite_t
/* Check if we have a VDM alert */
cmp dword ptr PCR[KPCR_VDM_ALERT], 0
.endfunc
.func KiTrap0F
-Dr_kit15: DR_TRAP_FIXUP
-V86_kit15: V86_TRAP_FIXUP
+TRAP_FIXUPS kitf_a, kitf_t, DoFixupV86, DoNotFixupAbios
_KiTrap0F:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit15
+ TRAP_PROLOG kitf_a, kitf_t
sti
/* Raise a fatal exception */
.endfunc
.func KiTrap16
-Dr_kit16: DR_TRAP_FIXUP
-V86_kit16: V86_TRAP_FIXUP
+TRAP_FIXUPS kit10_a, kit10_t, DoFixupV86, DoNotFixupAbios
_KiTrap16:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit16
+ TRAP_PROLOG kit10_a, kit10_t
/* Check if this is the NPX Thread */
mov eax, PCR[KPCR_CURRENT_THREAD]
.endfunc
.func KiTrap17
-Dr_kit17: DR_TRAP_FIXUP
-V86_kit17: V86_TRAP_FIXUP
+TRAP_FIXUPS kit11_a, kit11_t, DoFixupV86, DoNotFixupAbios
_KiTrap17:
/* Push error code */
push 0
/* Enter trap */
- TRAP_PROLOG kit17
+ TRAP_PROLOG kit11_a, kit11_t
/* FIXME: ROS Doesn't handle alignment faults yet */
mov eax, 17
jmp _KiUnexpectedInterruptTail
.func KiUnexpectedInterruptTail
-V86_kui: V86_TRAP_FIXUP
-Dr_kui: DR_TRAP_FIXUP
+TRAP_FIXUPS kui_a, kui_t, DoFixupV86, DoFixupAbios
_KiUnexpectedInterruptTail:
/* Enter interrupt trap */
- INT_PROLOG kui, DoNotPushFakeErrorCode
+ INT_PROLOG kui_a, kui_t, DoNotPushFakeErrorCode
/* Increase interrupt count */
inc dword ptr PCR[KPCR_PRCB_INTERRUPT_COUNT]
.endfunc
.func KiInterruptTemplate
-V86_kit: V86_TRAP_FIXUP
-Dr_kit: DR_TRAP_FIXUP
_KiInterruptTemplate:
/* Enter interrupt trap */
- INT_PROLOG kit, DoPushFakeErrorCode
-.endfunc
+ INT_PROLOG kit_a, kit_t, DoPushFakeErrorCode
_KiInterruptTemplate2ndDispatch:
/* Dummy code, will be replaced by the address of the KINTERRUPT */
_KiInterruptTemplateDispatch:
/* Marks the end of the template so that the jump above can be edited */
+TRAP_FIXUPS kit_a, kit_t, DoFixupV86, DoFixupAbios
+.endfunc
+
.func KiChainedDispatch2ndLvl@0
_KiChainedDispatch2ndLvl@0: