Author: tkreuzer
Date: Wed Dec 3 11:45:50 2008
New Revision: 37837
URL:
http://svn.reactos.org/svn/reactos?rev=37837&view=rev
Log:
Some assembly code to save restore registers on traps
Modified:
branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntosk…
==============================================================================
--- branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S [iso-8859-1] (original)
+++ branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S [iso-8859-1] Wed Dec 3
11:45:50 2008
@@ -3,12 +3,11 @@
* COPYRIGHT: See COPYING in the top level directory
* PURPOSE: System Traps, Entrypoints and Exitpoints
* PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
- * NOTE: See asmmacro.S for the shared entry/exit code.
*/
/* INCLUDES ******************************************************************/
-//#include <asm.h>
+#include <ndk/amd64/asm.h>
#include <ndk/amd64/asmmacro.S>
/* GLOBALS *******************************************************************/
@@ -31,6 +30,180 @@
_MsgUnexpectedInterrupt:
.ascii "UnexpectedInterrupt\n\0"
+/* Helper Macros *************************************************************/
+
+#define TRAPFLAG_SYSTEMSERVICE 1
+
+.macro ENTER_TRAP_FRAME AllocSize Flags
+.set SIZE_INITIAL_FRAME, 7 * 8
+//.set SIZE_LOCAL_DATA, SIZE_EXCEPTION_RECORD + 0x28
+.set SIZE_TRAP_FRAME_ALLOC, SIZE_KTRAP_FRAME - SIZE_INITIAL_FRAME + \AllocSize
+.set TRAPFLAGS, \Flags
+
+ /* Save rbp */
+ push rbp
+ .pushreg rbp
+
+ /* Make room for a KTRAP_FRAME and function parameters */
+ sub rsp, SIZE_TRAP_FRAME_ALLOC
+ .allocstack SIZE_TRAP_FRAME_ALLOC
+
+ /* Point rbp to the KTRAP_FRAME */
+ lea rbp, [rsp + \AllocSize]
+
+// KTRAP_FRAME_P1Home
+// KTRAP_FRAME_P2Home
+// KTRAP_FRAME_P3Home
+// KTRAP_FRAME_P4Home
+// KTRAP_FRAME_P5
+
+.if (TRAPFLAGS & TRAPFLAG_SYSTEMSERVICE)
+ /* Save non-volatile registers */
+ mov [rbp + KTRAP_FRAME_Rbx], rbx
+ mov [rbp + KTRAP_FRAME_Rdi], rdi
+ mov [rbp + KTRAP_FRAME_Rsi], rsi
+.else
+ /* Save volatile registers */
+ mov [rbp + KTRAP_FRAME_Rax], rax
+ mov [rbp + KTRAP_FRAME_Rcx], rcx
+ mov [rbp + KTRAP_FRAME_Rdx], rdx
+ mov [rbp + KTRAP_FRAME_R8], r8
+ mov [rbp + KTRAP_FRAME_R9], r9
+ mov [rbp + KTRAP_FRAME_R10], r10
+ mov [rbp + KTRAP_FRAME_R11], r11
+
+ /* Save xmm registers */
+ movdqa [rbp + KTRAP_FRAME_Xmm0], xmm0
+ movdqa [rbp + KTRAP_FRAME_Xmm1], xmm1
+ movdqa [rbp + KTRAP_FRAME_Xmm2], xmm2
+ movdqa [rbp + KTRAP_FRAME_Xmm3], xmm3
+ movdqa [rbp + KTRAP_FRAME_Xmm4], xmm4
+ movdqa [rbp + KTRAP_FRAME_Xmm5], xmm5
+.endif
+
+ /* Save segment selectors */
+ mov ax, ds
+ mov [rbp + KTRAP_FRAME_SegDs], ax
+ mov ax, es
+ mov [rbp + KTRAP_FRAME_SegEs], ax
+ mov ax, fs
+ mov [rbp + KTRAP_FRAME_SegFs], ax
+ mov ax, gs
+ mov [rbp + KTRAP_FRAME_SegGs], ax
+
+ /* Save previous mode and swap gs when it was UserMode */
+ mov ax, [rbp + KTRAP_FRAME_SegCs]
+ and ax, 1
+ mov [rbp + KTRAP_FRAME_PreviousMode], al
+ jz 1f
+ swapgs
+1:
+
+ /* Save previous irql */
+ mov rax, cr8
+ mov [rbp + KTRAP_FRAME_PreviousIrql], al
+
+// KTRAP_FRAME_FaultIndicator
+// KTRAP_FRAME_ExceptionActive
+// KTRAP_FRAME_MxCsr
+
+
+ /* Save debug registers */
+ mov rax, dr0
+ mov [rbp + KTRAP_FRAME_Dr0], rax
+ mov rax, dr1
+ mov [rbp + KTRAP_FRAME_Dr1], rax
+ mov rax, dr2
+ mov [rbp + KTRAP_FRAME_Dr2], rax
+ mov rax, dr3
+ mov [rbp + KTRAP_FRAME_Dr3], rax
+ mov rax, dr6
+ mov [rbp + KTRAP_FRAME_Dr6], rax
+ mov rax, dr7
+ mov [rbp + KTRAP_FRAME_Dr7], rax
+
+// KTRAP_FRAME_DebugControl
+// KTRAP_FRAME_LastBranchToRip
+// KTRAP_FRAME_LastBranchFromRip
+// KTRAP_FRAME_LastExceptionToRip
+// KTRAP_FRAME_LastExceptionFromRip
+// KTRAP_FRAME_TrapFrame
+
+.endm
+
+.macro LEAVE_TRAP_FRAME
+
+ /* Restore segment selectors */
+ mov ax, [rbp + KTRAP_FRAME_SegDs]
+ mov ds, ax
+ mov ax, [rbp + KTRAP_FRAME_SegEs]
+ mov es, ax
+ mov ax, [rbp + KTRAP_FRAME_SegFs]
+ mov fs, ax
+ test byte ptr [rbp + KTRAP_FRAME_PreviousMode], 1
+ jz 1f
+ swapgs
+1:
+
+.if (TRAPFLAGS & TRAPFLAG_SYSTEMSERVICE)
+ /* Restore non-volatile registers */
+ mov rbx, [rbp + KTRAP_FRAME_Rbx]
+ mov rdi, [rbp + KTRAP_FRAME_Rdi]
+ mov rsi, [rbp + KTRAP_FRAME_Rsi]
+.else
+ /* Restore volatile registers */
+ mov rax, [rbp + KTRAP_FRAME_Rax]
+ mov rcx, [rbp + KTRAP_FRAME_Rcx]
+ mov rdx, [rbp + KTRAP_FRAME_Rdx]
+ mov r8, [rbp + KTRAP_FRAME_R8]
+ mov r9, [rbp + KTRAP_FRAME_R9]
+ mov r10, [rbp + KTRAP_FRAME_R10]
+ mov r11, [rbp + KTRAP_FRAME_R11]
+
+ /* Restore xmm registers */
+ movdqa xmm0, [rbp + KTRAP_FRAME_Xmm0]
+ movdqa xmm1, [rbp + KTRAP_FRAME_Xmm1]
+ movdqa xmm2, [rbp + KTRAP_FRAME_Xmm2]
+ movdqa xmm3, [rbp + KTRAP_FRAME_Xmm3]
+ movdqa xmm4, [rbp + KTRAP_FRAME_Xmm4]
+ movdqa xmm5, [rbp + KTRAP_FRAME_Xmm5]
+.endif
+
+ /* Restore rbp */
+ mov rbp, [rbp + KTRAP_FRAME_Rbp]
+
+ /* Adjust stack pointer (plus one qword for rbp, one for error code) */
+ add rsp, SIZE_TRAP_FRAME_ALLOC + 0x10
+.endm
+
+.macro DISPATCH_EXCEPTION Code, NumParams, p1, p2, p3
+
+ /* rsp+0x28 points to EXCEPTION_RECORD, set it up */
+ mov dword ptr [rsp + 0x28 + EXCEPTION_RECORD_ExceptionCode], \Code
+ mov dword ptr [rsp + 0x28 + EXCEPTION_RECORD_ExceptionFlags], 0
+ mov qword ptr [rsp + 0x28 + EXCEPTION_RECORD_ExceptionRecord], 0
+ mov rax, [rbp + KTRAP_FRAME_Rip]
+ mov [rsp + 0x28 + EXCEPTION_RECORD_ExceptionAddress], rax
+ mov dword ptr [rsp + 0x28 + EXCEPTION_RECORD_NumberParameters], \NumParams
+
+.if \NumParams >= 1
+ mov qword ptr [rsp + 0x28 + EXCEPTION_RECORD_ExceptionInformation + 0x00], \p1
+.endif
+.if \NumParams >= 2
+ mov qword ptr [rsp + 0x28 + EXCEPTION_RECORD_ExceptionInformation + 0x08], \p2
+.endif
+.if \NumParams >= 3
+ mov qword ptr [rsp + 0x28 + EXCEPTION_RECORD_ExceptionInformation + 0x10], \p3
+.endif
+
+ mov byte ptr [rsp + 0x20], 1 // FirstChance
+ mov r9b, [rbp + KTRAP_FRAME_PreviousMode] // PreviousMode
+ mov r8, rbp // TrapFrame
+ xor rdx, rdx // ExceptionFrame
+ lea rcx, [rsp + 0x28] // ExceptionRecord
+ call _KiDispatchException
+.endm
+
/* SOFTWARE INTERRUPT SERVICES ***********************************************/
.text
@@ -75,26 +248,18 @@
push 0
.allocstack 0x8
- push rax
- .pushreg rax
- push rcx
- .pushreg rcx
- push rdx
- sub rsp, 0x10
- .allocstack 0x10
- .endprolog
+ ENTER_TRAP_FRAME (SIZE_EXCEPTION_RECORD + 0x28), 0
lea rcx, _MsgBreakpointTrap[rip]
- mov rdx, [rsp + 0x10 + 24 + 8]
+ mov rdx, [rbp + KTRAP_FRAME_Rip]
lea rax, _FrLdrDbgPrint[rip]
call [rax]
+ mov rcx, gs:[KPCR_PRCB + KPRCB_CurrentThread]
+ DISPATCH_EXCEPTION STATUS_BREAKPOINT, 3, 0, rcx, 0
+
/* Return */
- add rsp, 0x10
- pop rdx
- pop rcx
- pop rax
- add rsp, 8
+ LEAVE_TRAP_FRAME
iretq
.endproc
@@ -224,6 +389,17 @@
call [rax]
jmp $
+
+ ENTER_TRAP_FRAME (SIZE_EXCEPTION_RECORD + 0x28), 0
+
+ /* Save page fault address */
+ mov rax, cr2
+ mov [rbp + KTRAP_FRAME_FaultAddress], rax
+
+ DISPATCH_EXCEPTION STATUS_BREAKPOINT, 0, 0, 0, 0
+
+ LEAVE_TRAP_FRAME;
+ iretq
.endproc