Author: tkreuzer
Date: Thu Dec 4 09:01:02 2008
New Revision: 37847
URL:
http://svn.reactos.org/svn/reactos?rev=37847&view=rev
Log:
Implement KeContextToTrapFrame and KeTrapFrameToContext
Modified:
branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/context.c
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/context.c
URL:
http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntosk…
==============================================================================
--- branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/context.c [iso-8859-1]
(original)
+++ branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/context.c [iso-8859-1] Thu Dec 4
09:01:02 2008
@@ -22,7 +22,90 @@
IN ULONG ContextFlags,
IN KPROCESSOR_MODE PreviousMode)
{
- UNIMPLEMENTED;
+ KIRQL OldIrql;
+
+ /* Do this at APC_LEVEL */
+ OldIrql = KeGetCurrentIrql();
+ if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
+
+ /* Handle integer registers */
+ if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+ {
+ TrapFrame->Rax = Context->Rax;
+ TrapFrame->Rbx = Context->Rbx;
+ TrapFrame->Rcx = Context->Rcx;
+ TrapFrame->Rdx = Context->Rdx;
+ TrapFrame->Rsi = Context->Rsi;
+ TrapFrame->Rdi = Context->Rdi;
+ TrapFrame->Rbp = Context->Rbp;
+ TrapFrame->R8 = Context->R8;
+ TrapFrame->R9 = Context->R9;
+ TrapFrame->R10 = Context->R10;
+ TrapFrame->R11 = Context->R11;
+ }
+
+ /* Handle floating point registers */
+ if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
+ CONTEXT_FLOATING_POINT) && (Context->SegCs & MODE_MASK))
+ {
+ TrapFrame->Xmm0 = Context->Xmm0;
+ TrapFrame->Xmm1 = Context->Xmm1;
+ TrapFrame->Xmm2 = Context->Xmm2;
+ TrapFrame->Xmm3 = Context->Xmm3;
+ TrapFrame->Xmm4 = Context->Xmm4;
+ TrapFrame->Xmm5 = Context->Xmm5;
+ }
+
+ /* Handle control registers */
+ if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+ {
+ /* RIP, RSP, EFLAGS */
+ TrapFrame->Rip = Context->Rip;
+ TrapFrame->Rsp = Context->Rsp;
+ TrapFrame->EFlags = Context->EFlags;
+ }
+
+ /* Handle segment selectors */
+ if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+ {
+ /* Check if this was a Kernel Trap */
+ if (Context->SegCs == KGDT_64_R0_CODE)
+ {
+ /* Set valid selectors */
+ TrapFrame->SegCs = KGDT_64_R0_CODE;
+ TrapFrame->SegDs = KGDT_64_DATA | RPL_MASK;
+ TrapFrame->SegEs = KGDT_64_DATA | RPL_MASK;
+ TrapFrame->SegFs = KGDT_32_R3_TEB;
+ TrapFrame->SegGs = KGDT_64_DATA | RPL_MASK;
+ TrapFrame->SegSs = KGDT_64_R0_SS;
+ }
+ else
+ {
+ /* Copy selectors */
+ TrapFrame->SegCs = Context->SegCs;
+ TrapFrame->SegDs = Context->SegDs;
+ TrapFrame->SegEs = Context->SegEs;
+ TrapFrame->SegFs = Context->SegFs;
+ TrapFrame->SegGs = Context->SegGs;
+ TrapFrame->SegSs = Context->SegSs;
+ }
+ }
+
+ /* Handle debug registers */
+ if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
+ CONTEXT_DEBUG_REGISTERS)
+ {
+ /* Copy the debug registers */
+ TrapFrame->Dr0 = Context->Dr0;
+ TrapFrame->Dr1 = Context->Dr1;
+ TrapFrame->Dr2 = Context->Dr2;
+ TrapFrame->Dr3 = Context->Dr3;
+ TrapFrame->Dr6 = Context->Dr6;
+ TrapFrame->Dr7 = Context->Dr7;
+ }
+
+ /* Restore IRQL */
+ if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
}
VOID
@@ -31,6 +114,89 @@
IN PKEXCEPTION_FRAME ExceptionFrame,
IN OUT PCONTEXT Context)
{
- UNIMPLEMENTED;
+ KIRQL OldIrql;
+
+ /* Do this at APC_LEVEL */
+ OldIrql = KeGetCurrentIrql();
+ if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
+
+ /* Handle integer registers */
+ if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
+ {
+ Context->Rax = TrapFrame->Rax;
+ Context->Rbx = TrapFrame->Rbx;
+ Context->Rcx = TrapFrame->Rcx;
+ Context->Rdx = TrapFrame->Rdx;
+ Context->Rsi = TrapFrame->Rsi;
+ Context->Rdi = TrapFrame->Rdi;
+ Context->Rbp = TrapFrame->Rbp;
+ Context->R8 = TrapFrame->R8;
+ Context->R9 = TrapFrame->R9;
+ Context->R10 = TrapFrame->R10;
+ Context->R11 = TrapFrame->R11;
+ }
+
+ /* Handle floating point registers */
+ if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
+ CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
+ {
+ Context->Xmm0 = TrapFrame->Xmm0;
+ Context->Xmm1 = TrapFrame->Xmm1;
+ Context->Xmm2 = TrapFrame->Xmm2;
+ Context->Xmm3 = TrapFrame->Xmm3;
+ Context->Xmm4 = TrapFrame->Xmm4;
+ Context->Xmm5 = TrapFrame->Xmm5;
+ }
+
+ /* Handle control registers */
+ if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
+ {
+ /* RIP, RSP, EFLAGS */
+ Context->Rip = TrapFrame->Rip;
+ Context->Rsp = TrapFrame->Rsp;
+ Context->EFlags = TrapFrame->EFlags;
+ }
+
+ /* Handle segment selectors */
+ if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
+ {
+ /* Check if this was a Kernel Trap */
+ if (TrapFrame->SegCs == KGDT_64_R0_CODE)
+ {
+ /* Set valid selectors */
+ Context->SegCs = KGDT_64_R0_CODE;
+ Context->SegDs = KGDT_64_DATA | RPL_MASK;
+ Context->SegEs = KGDT_64_DATA | RPL_MASK;
+ Context->SegFs = KGDT_32_R3_TEB;
+ Context->SegGs = KGDT_64_DATA | RPL_MASK;
+ Context->SegSs = KGDT_64_R0_SS;
+ }
+ else
+ {
+ /* Copy selectors */
+ Context->SegCs = TrapFrame->SegCs;
+ Context->SegDs = TrapFrame->SegDs;
+ Context->SegEs = TrapFrame->SegEs;
+ Context->SegFs = TrapFrame->SegFs;
+ Context->SegGs = TrapFrame->SegGs;
+ Context->SegSs = TrapFrame->SegSs;
+ }
+ }
+
+ /* Handle debug registers */
+ if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
+ CONTEXT_DEBUG_REGISTERS)
+ {
+ /* Copy the debug registers */
+ Context->Dr0 = TrapFrame->Dr0;
+ Context->Dr1 = TrapFrame->Dr1;
+ Context->Dr2 = TrapFrame->Dr2;
+ Context->Dr3 = TrapFrame->Dr3;
+ Context->Dr6 = TrapFrame->Dr6;
+ Context->Dr7 = TrapFrame->Dr7;
+ }
+
+ /* Restore IRQL */
+ if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
}