Sync to trunk head(r38096)
[reactos.git] / reactos / ntoskrnl / ke / amd64 / context.c
1 /*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: CONTEXT related functions
5 * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
6 */
7
8 /* INCLUDES ******************************************************************/
9
10 #include <ntoskrnl.h>
11
12 #define NDEBUG
13 #include <debug.h>
14
15 /* FUNCTIONS *****************************************************************/
16
17 VOID
18 NTAPI
19 KeContextToTrapFrame(IN PCONTEXT Context,
20 IN OUT PKEXCEPTION_FRAME ExceptionFrame,
21 IN OUT PKTRAP_FRAME TrapFrame,
22 IN ULONG ContextFlags,
23 IN KPROCESSOR_MODE PreviousMode)
24 {
25 KIRQL OldIrql;
26
27 /* Do this at APC_LEVEL */
28 OldIrql = KeGetCurrentIrql();
29 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
30
31 /* Handle integer registers */
32 if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
33 {
34 TrapFrame->Rax = Context->Rax;
35 TrapFrame->Rbx = Context->Rbx;
36 TrapFrame->Rcx = Context->Rcx;
37 TrapFrame->Rdx = Context->Rdx;
38 TrapFrame->Rsi = Context->Rsi;
39 TrapFrame->Rdi = Context->Rdi;
40 TrapFrame->Rbp = Context->Rbp;
41 TrapFrame->R8 = Context->R8;
42 TrapFrame->R9 = Context->R9;
43 TrapFrame->R10 = Context->R10;
44 TrapFrame->R11 = Context->R11;
45 }
46
47 /* Handle floating point registers */
48 if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
49 CONTEXT_FLOATING_POINT) && (Context->SegCs & MODE_MASK))
50 {
51 TrapFrame->Xmm0 = Context->Xmm0;
52 TrapFrame->Xmm1 = Context->Xmm1;
53 TrapFrame->Xmm2 = Context->Xmm2;
54 TrapFrame->Xmm3 = Context->Xmm3;
55 TrapFrame->Xmm4 = Context->Xmm4;
56 TrapFrame->Xmm5 = Context->Xmm5;
57 }
58
59 /* Handle control registers */
60 if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
61 {
62 /* RIP, RSP, EFLAGS */
63 TrapFrame->Rip = Context->Rip;
64 TrapFrame->Rsp = Context->Rsp;
65 TrapFrame->EFlags = Context->EFlags;
66 }
67
68 /* Handle segment selectors */
69 if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
70 {
71 /* Check if this was a Kernel Trap */
72 if (Context->SegCs == KGDT_64_R0_CODE)
73 {
74 /* Set valid selectors */
75 TrapFrame->SegCs = KGDT_64_R0_CODE;
76 TrapFrame->SegDs = KGDT_64_DATA | RPL_MASK;
77 TrapFrame->SegEs = KGDT_64_DATA | RPL_MASK;
78 TrapFrame->SegFs = KGDT_32_R3_TEB;
79 TrapFrame->SegGs = KGDT_64_DATA | RPL_MASK;
80 TrapFrame->SegSs = KGDT_64_R0_SS;
81 }
82 else
83 {
84 /* Copy selectors */
85 TrapFrame->SegCs = Context->SegCs;
86 TrapFrame->SegDs = Context->SegDs;
87 TrapFrame->SegEs = Context->SegEs;
88 TrapFrame->SegFs = Context->SegFs;
89 TrapFrame->SegGs = Context->SegGs;
90 TrapFrame->SegSs = Context->SegSs;
91 }
92 }
93
94 /* Handle debug registers */
95 if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
96 CONTEXT_DEBUG_REGISTERS)
97 {
98 /* Copy the debug registers */
99 TrapFrame->Dr0 = Context->Dr0;
100 TrapFrame->Dr1 = Context->Dr1;
101 TrapFrame->Dr2 = Context->Dr2;
102 TrapFrame->Dr3 = Context->Dr3;
103 TrapFrame->Dr6 = Context->Dr6;
104 TrapFrame->Dr7 = Context->Dr7;
105 }
106
107 /* Restore IRQL */
108 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
109 }
110
111 VOID
112 NTAPI
113 KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
114 IN PKEXCEPTION_FRAME ExceptionFrame,
115 IN OUT PCONTEXT Context)
116 {
117 KIRQL OldIrql;
118
119 /* Do this at APC_LEVEL */
120 OldIrql = KeGetCurrentIrql();
121 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
122
123 /* Handle integer registers */
124 if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
125 {
126 Context->Rax = TrapFrame->Rax;
127 Context->Rbx = TrapFrame->Rbx;
128 Context->Rcx = TrapFrame->Rcx;
129 Context->Rdx = TrapFrame->Rdx;
130 Context->Rsi = TrapFrame->Rsi;
131 Context->Rdi = TrapFrame->Rdi;
132 Context->Rbp = TrapFrame->Rbp;
133 Context->R8 = TrapFrame->R8;
134 Context->R9 = TrapFrame->R9;
135 Context->R10 = TrapFrame->R10;
136 Context->R11 = TrapFrame->R11;
137 }
138
139 /* Handle floating point registers */
140 if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
141 CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
142 {
143 Context->Xmm0 = TrapFrame->Xmm0;
144 Context->Xmm1 = TrapFrame->Xmm1;
145 Context->Xmm2 = TrapFrame->Xmm2;
146 Context->Xmm3 = TrapFrame->Xmm3;
147 Context->Xmm4 = TrapFrame->Xmm4;
148 Context->Xmm5 = TrapFrame->Xmm5;
149 }
150
151 /* Handle control registers */
152 if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
153 {
154 /* RIP, RSP, EFLAGS */
155 Context->Rip = TrapFrame->Rip;
156 Context->Rsp = TrapFrame->Rsp;
157 Context->EFlags = TrapFrame->EFlags;
158 }
159
160 /* Handle segment selectors */
161 if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
162 {
163 /* Check if this was a Kernel Trap */
164 if (TrapFrame->SegCs == KGDT_64_R0_CODE)
165 {
166 /* Set valid selectors */
167 Context->SegCs = KGDT_64_R0_CODE;
168 Context->SegDs = KGDT_64_DATA | RPL_MASK;
169 Context->SegEs = KGDT_64_DATA | RPL_MASK;
170 Context->SegFs = KGDT_32_R3_TEB;
171 Context->SegGs = KGDT_64_DATA | RPL_MASK;
172 Context->SegSs = KGDT_64_R0_SS;
173 }
174 else
175 {
176 /* Copy selectors */
177 Context->SegCs = TrapFrame->SegCs;
178 Context->SegDs = TrapFrame->SegDs;
179 Context->SegEs = TrapFrame->SegEs;
180 Context->SegFs = TrapFrame->SegFs;
181 Context->SegGs = TrapFrame->SegGs;
182 Context->SegSs = TrapFrame->SegSs;
183 }
184 }
185
186 /* Handle debug registers */
187 if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
188 CONTEXT_DEBUG_REGISTERS)
189 {
190 /* Copy the debug registers */
191 Context->Dr0 = TrapFrame->Dr0;
192 Context->Dr1 = TrapFrame->Dr1;
193 Context->Dr2 = TrapFrame->Dr2;
194 Context->Dr3 = TrapFrame->Dr3;
195 Context->Dr6 = TrapFrame->Dr6;
196 Context->Dr7 = TrapFrame->Dr7;
197 }
198
199 /* Restore IRQL */
200 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
201 }
202