Author: ion Date: Sat Dec 2 23:49:56 2006 New Revision: 25020
URL: http://svn.reactos.org/svn/reactos?rev=25020&view=rev Log: - Implement V86 trap fixup during traps and interrupts. - Implement DR register save/restore during traps, interrupts and system calls. - Remove respective entry from krnlfun.c.
Modified: trunk/reactos/include/ndk/asm.h trunk/reactos/ntoskrnl/KrnlFun.c trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S trunk/reactos/ntoskrnl/ke/i386/trap.s
Modified: trunk/reactos/include/ndk/asm.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=25020... ============================================================================== --- trunk/reactos/include/ndk/asm.h (original) +++ trunk/reactos/include/ndk/asm.h Sat Dec 2 23:49:56 2006 @@ -135,6 +135,16 @@ #define KPROCESS_IOPM_OFFSET 0x30 #define KPROCESS_ACTIVE_PROCESSORS 0x34 #define EPROCESS_VDM_OBJECTS 0x144 + +// +// KPRCB Offsets +// +#define KPRCB_DR0 0x2F8 +#define KPRCB_DR1 0x2FC +#define KPRCB_DR2 0x300 +#define KPRCB_DR3 0x304 +#define KPRCB_DR6 0x308 +#define KPRCB_DR7 0x20C
// // KPCR Offsets
Modified: trunk/reactos/ntoskrnl/KrnlFun.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=2502... ============================================================================== --- trunk/reactos/ntoskrnl/KrnlFun.c (original) +++ trunk/reactos/ntoskrnl/KrnlFun.c Sat Dec 2 23:49:56 2006 @@ -28,7 +28,6 @@ // // Ke: // - Figure out why the DPC stack doesn't really work. -// - Add DR macro/save and VM macro/save. // - New optimized table-based tick-hashed timer implementation. // - New Thread Scheduler based on 2003. // - Implement KiCallbackReturn, KiGetTickCount, KiRaiseAssertion.
Modified: trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/asmmacro.S Sat Dec 2 23:49:56 2006 @@ -187,6 +187,104 @@ .endm
// +// @name V86_TRAP_FIXUP +// +// This macro sets up the debug header in the trap frame. +// +// @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. +// +// @param None. +// +// @remark ebp = PKTRAP_FRAME +// +.macro DR_TRAP_FIXUP + /* 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 + +2: + /* Get DR0, 1, 2 */ + mov ebx, dr0 + mov ecx, dr1 + mov edi, dr2 + + /* Save them */ + mov [ebp+KTRAP_FRAME_DR0], ebx + mov [ebp+KTRAP_FRAME_DR1], ecx + mov [ebp+KTRAP_FRAME_DR2], edi + + /* Get DR3, 6, 7 */ + mov ebx, dr0 + mov ecx, dr1 + mov edi, dr2 + + /* Save them */ + mov [ebp+KTRAP_FRAME_DR3], ebx + mov [ebp+KTRAP_FRAME_DR6], ecx + mov [ebp+KTRAP_FRAME_DR7], edi + + /* Clear DR7 */ + xor ebx, ebx + mov dr7, ebx + + /* Get the PRCB */ + mov edi, PCR[KPCR_PRCB] + + /* Get DR0, 1 */ + mov ebx, [edi+KPRCB_DR0] + mov ecx, [edi+KPRCB_DR1] + + /* Set them */ + mov dr0, ebx + mov dr1, ecx + + /* Get DR2, 3 */ + mov ebx, [edi+KPRCB_DR2] + mov ecx, [edi+KPRCB_DR3] + + /* Set them */ + mov dr2, ebx + mov dr3, ecx + + /* Get DR6, 7 */ + mov ebx, [edi+KPRCB_DR6] + mov ecx, [edi+KPRCB_DR7] + + /* Set them */ + mov dr6, ebx + mov dr7, ecx + jz 3f +.endm + +// // @name SET_TF_DEBUG_HEADER // // This macro sets up the debug header in the trap frame. @@ -315,6 +413,7 @@ /* Save FS and set it to PCR */ push fs mov ebx, KGDT_R0_PCR + .byte 0x66 mov fs, bx
/* Save exception list and bogus previous mode */ @@ -336,16 +435,23 @@ sub esp, 0x30
/* Load the segment registers */ + .byte 0x66 mov ds, ax + .byte 0x66 mov es, ax + + /* Check if this interrupt happened in 16-bit mode */ + cmp esp, 0x10000 + jb _Ki16BitStackException
/* 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_Label; */ - + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jnz V86_&Label + +1: /* Get current thread */ mov ecx, [fs:KPCR_CURRENT_THREAD] cld @@ -353,9 +459,10 @@ /* Flush DR7 */ and dword ptr [ebp+KTRAP_FRAME_DR7], 0
+3: /* Check if the thread was being debugged */ - /* test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF; */ - /* jnz Dr_Label; */ + test byte ptr [ecx+KTHREAD_DEBUG_ACTIVE], 0xFF + jnz Dr_&Label
/* Set the Trap Frame Debug Header */ SET_TF_DEBUG_HEADER @@ -399,10 +506,11 @@ mov dword ptr [esp+KTRAP_FRAME_PREVIOUS_MODE], -1
/* Check if this was from V86 Mode */ - /* test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK */ - /* jnz V86_&Label*/ + test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK + jnz V86_&Label
/* Check if this was kernel mode */ +1: cmp dword ptr [esp+KTRAP_FRAME_CS], KGDT_R0_CODE jz 1f
@@ -463,9 +571,10 @@ .endif
/* Save DR registers if needed */ - //jnz Dr_&Label + jnz Dr_&Label
/* Set the trap frame debug header */ +3: SET_TF_DEBUG_HEADER .endm
@@ -484,7 +593,7 @@ // // @remark None. // -.macro SYSCALL_PROLOG +.macro SYSCALL_PROLOG Label /* Create a trap frame */ push 0 push ebp @@ -495,6 +604,7 @@
/* Load PCR Selector into fs */ mov ebx, KGDT_R0_PCR + .byte 0x66 mov fs, bx
/* Get a pointer to the current thread */ @@ -507,19 +617,15 @@ mov dword ptr [fs:KPCR_EXCEPTION_LIST], -1
/* Save the old previous mode */ - push ss:[esi+KTHREAD_PREVIOUS_MODE] + push [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 + mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], bl
/* Go on the Kernel stack frame */ mov ebp, esp @@ -539,9 +645,108 @@ cld
/* Save DR registers if needed */ - //jnz Dr_kss_&Label + jnz Dr_&Label
/* Set the trap frame debug header */ +3: + SET_TF_DEBUG_HEADER + + /* Enable interrupts */ + sti +.endm + +// +// @name FASTCALL_PROLOG +// +// TODO +// +// @param Label +// 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 FASTCALL_PROLOG Label + /* Set FS to PCR */ + mov ecx, KGDT_R0_PCR + mov fs, cx + //push KGDT_R0_PCR + //pop fs + + /* Set user selector */ + mov ecx, KGDT_R3_DATA | RPL_MASK + + /* Set DS/ES to User Selector */ + mov ds, cx + mov es, cx + + /* Set the current stack to Kernel Stack */ + mov ecx, [fs:KPCR_TSS] + mov esp, [ecx+KTSS_ESP0] + + /* Set up a fake INT Stack. */ + push KGDT_R3_DATA + RPL_MASK + push edx /* Ring 3 SS:ESP */ + pushf /* Ring 3 EFLAGS */ + push 2 /* Ring 0 EFLAGS */ + add edx, 8 /* Skip user parameter list */ + popf /* Set our EFLAGS */ + or dword ptr [esp], EFLAGS_INTERRUPT_MASK /* Re-enable IRQs in EFLAGS, to fake INT */ + push KGDT_R3_CODE + RPL_MASK + push dword ptr ds:KUSER_SHARED_SYSCALL_RET + + /* Setup the Trap Frame stack */ + push 0 + push ebp + push ebx + push esi + push edi + push KGDT_R3_TEB + RPL_MASK + + /* Save pointer to our PCR */ + mov ebx, [fs:KPCR_SELF] + + /* Get a pointer to the current thread */ + mov esi, [ebx+KPCR_CURRENT_THREAD] + + /* Set the exception handler chain terminator */ + push [ebx+KPCR_EXCEPTION_LIST] + mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1 + + /* Use the thread's stack */ + mov ebp, [esi+KTHREAD_INITIAL_STACK] + + /* Push previous mode */ + push UserMode + + /* Skip the other registers */ + sub esp, 0x48 + + /* Make space for us on the stack */ + sub ebp, 0x29C + + /* Write the previous mode */ + mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], UserMode + + /* Sanity check */ + cmp ebp, esp + jnz BadStack + + /* 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 */ + mov [esi+KTHREAD_TRAP_FRAME], ebp + + /* Save DR registers if needed */ + jnz Dr_&Label + + /* Set the trap frame debug header */ +3: SET_TF_DEBUG_HEADER
/* Enable interrupts */ @@ -966,6 +1171,13 @@ mov esi, [esp+KTRAP_FRAME_EIP] mov [ebx], esi
+.if \RestoreVolatiles + /* Restore volatiles */ + mov eax, [esp+KTRAP_FRAME_EAX] + mov edx, [esp+KTRAP_FRAME_EDX] + mov ecx, [esp+KTRAP_FRAME_ECX] +.endif + /* Return */ add esp, KTRAP_FRAME_EDI pop edi
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?rev... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/trap.s (original) +++ trunk/reactos/ntoskrnl/ke/i386/trap.s Sat Dec 2 23:49:56 2006 @@ -96,100 +96,22 @@ int 3
.func KiSystemService +Dr_kss: DR_TRAP_FIXUP _KiSystemService:
/* Enter the shared system call prolog */ - SYSCALL_PROLOG + SYSCALL_PROLOG kss
/* Jump to the actual handler */ jmp SharedCode .endfunc
.func KiFastCallEntry +Dr_FastCallDrSave: DR_TRAP_FIXUP _KiFastCallEntry:
- /* Set FS to PCR */ - mov ecx, KGDT_R0_PCR - mov fs, cx - //push KGDT_R0_PCR - //pop fs - - /* Set user selector */ - mov ecx, KGDT_R3_DATA | RPL_MASK - - /* Set DS/ES to User Selector */ - mov ds, cx - mov es, cx - - /* Set the current stack to Kernel Stack */ - mov ecx, [fs:KPCR_TSS] - mov esp, ss:[ecx+KTSS_ESP0] - - /* Set up a fake INT Stack. */ - push KGDT_R3_DATA + RPL_MASK - push edx /* Ring 3 SS:ESP */ - pushf /* Ring 3 EFLAGS */ - push 2 /* Ring 0 EFLAGS */ - add edx, 8 /* Skip user parameter list */ - popf /* Set our EFLAGS */ - or dword ptr [esp], EFLAGS_INTERRUPT_MASK /* Re-enable IRQs in EFLAGS, to fake INT */ - push KGDT_R3_CODE + RPL_MASK - push dword ptr ds:KUSER_SHARED_SYSCALL_RET - - /* Setup the Trap Frame stack */ - push 0 - push ebp - push ebx - push esi - push edi - push KGDT_R3_TEB + RPL_MASK - - /* Save pointer to our PCR */ - mov ebx, [fs:KPCR_SELF] - - /* Get a pointer to the current thread */ - mov esi, [ebx+KPCR_CURRENT_THREAD] - - /* Set the exception handler chain terminator */ - push [ebx+KPCR_EXCEPTION_LIST] - mov dword ptr [ebx+KPCR_EXCEPTION_LIST], -1 - - /* Use the thread's stack */ - mov ebp, [esi+KTHREAD_INITIAL_STACK] - - /* Push previous mode */ - push UserMode - - /* Skip the other registers */ - sub esp, 0x48 - - /* Make space for us on the stack */ - sub ebp, 0x29C - - /* Write the previous mode */ - mov byte ptr [esi+KTHREAD_PREVIOUS_MODE], UserMode - - /* Sanity check */ - cmp ebp, esp - jnz BadStack - - /* 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 */ - mov [esi+KTHREAD_TRAP_FRAME], ebp - - /* Save DR registers if needed */ - //jnz Dr_FastCallDrSave - - /* Set the trap frame debug header */ - SET_TF_DEBUG_HEADER - - /* Enable interrupts */ - sti + /* Enter the fast system call prolog */ + FASTCALL_PROLOG FastCallDrSave
SharedCode:
@@ -514,13 +436,15 @@ int 3
.func KiDebugService +Dr_kids: DR_TRAP_FIXUP +V86_kids: V86_TRAP_FIXUP _KiDebugService:
/* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(kids) + TRAP_PROLOG kids
/* Increase EIP so we skip the INT3 */ //inc dword ptr [ebp+KTRAP_FRAME_EIP] @@ -749,12 +673,14 @@ /* HARDWARE TRAP HANDLERS ****************************************************/
.func KiTrap0 +Dr_kit0: DR_TRAP_FIXUP +V86_kit0: V86_TRAP_FIXUP _KiTrap0: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(0) + TRAP_PROLOG kit0
/* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -788,12 +714,14 @@ .endfunc
.func KiTrap1 +Dr_kit1: DR_TRAP_FIXUP +V86_kit1: V86_TRAP_FIXUP _KiTrap1: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(1) + TRAP_PROLOG kit1
/* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -839,12 +767,14 @@ .endfunc
.func KiTrap3 +Dr_kit3: DR_TRAP_FIXUP +V86_kit3: V86_TRAP_FIXUP _KiTrap3: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(3) + TRAP_PROLOG kit3
/* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -887,12 +817,14 @@ .endfunc
.func KiTrap4 +Dr_kit4: DR_TRAP_FIXUP +V86_kit4: V86_TRAP_FIXUP _KiTrap4: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(4) + TRAP_PROLOG kit4
/* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -927,12 +859,14 @@ .endfunc
.func KiTrap5 +Dr_kit5: DR_TRAP_FIXUP +V86_kit5: V86_TRAP_FIXUP _KiTrap5: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(5) + TRAP_PROLOG kit5
/* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -971,6 +905,8 @@ .endfunc
.func KiTrap6 +Dr_kit6: DR_TRAP_FIXUP +V86_kit6: V86_TRAP_FIXUP _KiTrap6:
/* It this a V86 GPF? */ @@ -989,7 +925,7 @@ push 0
/* Enter trap */ - TRAP_PROLOG(6) + TRAP_PROLOG kit6
/* Check if this happened in kernel mode */ test byte ptr [ebp+KTRAP_FRAME_CS], MODE_MASK @@ -1086,12 +1022,14 @@ .endfunc
.func KiTrap7 +Dr_kit7: DR_TRAP_FIXUP +V86_kit7: V86_TRAP_FIXUP _KiTrap7: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(7) + TRAP_PROLOG kit7
/* Get the current thread and stack */ StartTrapHandle: @@ -1405,12 +1343,14 @@ .endfunc
.func KiTrap9 +Dr_kit9: DR_TRAP_FIXUP +V86_kit9: V86_TRAP_FIXUP _KiTrap9: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(9) + TRAP_PROLOG kit9
/* Enable interrupts and bugcheck */ sti @@ -1419,9 +1359,11 @@ .endfunc
.func KiTrap10 +Dr_kit10: DR_TRAP_FIXUP +V86_kit10: V86_TRAP_FIXUP _KiTrap10: /* Enter trap */ - TRAP_PROLOG(10) + TRAP_PROLOG kit10
/* Check for V86 */ test dword ptr [ebp+KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK @@ -1448,9 +1390,11 @@ .endfunc
.func KiTrap11 +Dr_kit11: DR_TRAP_FIXUP +V86_kit11: V86_TRAP_FIXUP _KiTrap11: /* Enter trap */ - TRAP_PROLOG(11) + TRAP_PROLOG kit11
/* FIXME: ROS Doesn't handle segment faults yet */ mov eax, 11 @@ -1458,9 +1402,11 @@ .endfunc
.func KiTrap12 +Dr_kit12: DR_TRAP_FIXUP +V86_kit12: V86_TRAP_FIXUP _KiTrap12: /* Enter trap */ - TRAP_PROLOG(12) + TRAP_PROLOG kit12
/* FIXME: ROS Doesn't handle stack faults yet */ mov eax, 12 @@ -1468,6 +1414,8 @@ .endfunc
.func KiTrap13 +Dr_kitd: DR_TRAP_FIXUP +V86_kitd: V86_TRAP_FIXUP _KiTrap13:
/* It this a V86 GPF? */ @@ -1531,7 +1479,7 @@
NotV86: /* Enter trap */ - TRAP_PROLOG(13) + TRAP_PROLOG kitd
/* Check if this was from kernel-mode */ test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK @@ -1678,9 +1626,11 @@ .endfunc
.func KiTrap14 +Dr_kit14: DR_TRAP_FIXUP +V86_kit14: V86_TRAP_FIXUP _KiTrap14: /* Enter trap */ - TRAP_PROLOG(14) + TRAP_PROLOG kit14
/* Call the C exception handler */ push 14 @@ -1693,12 +1643,14 @@ .endfunc
.func KiTrap0F +Dr_kit15: DR_TRAP_FIXUP +V86_kit15: V86_TRAP_FIXUP _KiTrap0F: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(15) + TRAP_PROLOG kit15 sti
/* Raise a fatal exception */ @@ -1707,12 +1659,14 @@ .endfunc
.func KiTrap16 +Dr_kit16: DR_TRAP_FIXUP +V86_kit16: V86_TRAP_FIXUP _KiTrap16: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(16) + TRAP_PROLOG kit16
/* Check if this is the NPX Thread */ mov eax, fs:[KPCR_CURRENT_THREAD] @@ -1732,12 +1686,14 @@ .endfunc
.func KiTrap17 +Dr_kit17: DR_TRAP_FIXUP +V86_kit17: V86_TRAP_FIXUP _KiTrap17: /* Push error code */ push 0
/* Enter trap */ - TRAP_PROLOG(17) + TRAP_PROLOG kit17
/* FIXME: ROS Doesn't handle alignment faults yet */ mov eax, 17 @@ -1784,6 +1740,22 @@ ret .endfunc
+.func Ki16BitStackException +_Ki16BitStackException: + + /* Save stack */ + push ss + push esp + + /* Go to kernel mode thread stack */ + mov eax, fs:[KPCR_CURRENT_THREAD] + add esp, [eax+KTHREAD_INITIAL_STACK] + + /* Switch to good stack segment */ + /* TODO */ + int 3 +.endfunc + /* UNEXPECTED INTERRUPT HANDLERS **********************************************/
.globl _KiStartUnexpectedRange@0 @@ -1796,6 +1768,8 @@ jmp _KiUnexpectedInterruptTail
.func KiUnexpectedInterruptTail +V86_kui: V86_TRAP_FIXUP +Dr_kui: DR_TRAP_FIXUP _KiUnexpectedInterruptTail:
/* Enter interrupt trap */ @@ -1907,6 +1881,8 @@ .endfunc
.func KiInterruptTemplate +V86_kit: V86_TRAP_FIXUP +Dr_kit: DR_TRAP_FIXUP _KiInterruptTemplate:
/* Enter interrupt trap */