Branching for 0.3.15 release after two days of no response from a certain sphere...
[reactos.git] / 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 /* Make sure we have an amd64 context, then remove the flag */
28 ASSERT(ContextFlags & CONTEXT_AMD64);
29 ContextFlags &= ~CONTEXT_AMD64;
30
31 /* Do this at APC_LEVEL */
32 OldIrql = KeGetCurrentIrql();
33 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
34
35 /* Handle integer registers */
36 if (ContextFlags & CONTEXT_INTEGER)
37 {
38 TrapFrame->Rax = Context->Rax;
39 TrapFrame->Rbx = Context->Rbx;
40 TrapFrame->Rcx = Context->Rcx;
41 TrapFrame->Rdx = Context->Rdx;
42 TrapFrame->Rsi = Context->Rsi;
43 TrapFrame->Rdi = Context->Rdi;
44 TrapFrame->Rbp = Context->Rbp;
45 TrapFrame->R8 = Context->R8;
46 TrapFrame->R9 = Context->R9;
47 TrapFrame->R10 = Context->R10;
48 TrapFrame->R11 = Context->R11;
49 if (ExceptionFrame)
50 {
51 ExceptionFrame->R12 = Context->R12;
52 ExceptionFrame->R13 = Context->R13;
53 ExceptionFrame->R14 = Context->R14;
54 ExceptionFrame->R15 = Context->R15;
55 }
56 }
57
58 /* Handle floating point registers */
59 if ((ContextFlags & CONTEXT_FLOATING_POINT) &&
60 (Context->SegCs & MODE_MASK))
61 {
62 TrapFrame->Xmm0 = Context->Xmm0;
63 TrapFrame->Xmm1 = Context->Xmm1;
64 TrapFrame->Xmm2 = Context->Xmm2;
65 TrapFrame->Xmm3 = Context->Xmm3;
66 TrapFrame->Xmm4 = Context->Xmm4;
67 TrapFrame->Xmm5 = Context->Xmm5;
68 if (ExceptionFrame)
69 {
70 ExceptionFrame->Xmm6 = Context->Xmm6;
71 ExceptionFrame->Xmm7 = Context->Xmm7;
72 ExceptionFrame->Xmm8 = Context->Xmm8;
73 ExceptionFrame->Xmm9 = Context->Xmm9;
74 ExceptionFrame->Xmm10 = Context->Xmm10;
75 ExceptionFrame->Xmm11 = Context->Xmm11;
76 ExceptionFrame->Xmm12 = Context->Xmm12;
77 ExceptionFrame->Xmm13 = Context->Xmm13;
78 ExceptionFrame->Xmm14 = Context->Xmm14;
79 ExceptionFrame->Xmm15 = Context->Xmm15;
80 }
81 }
82
83 /* Handle control registers */
84 if (ContextFlags & CONTEXT_CONTROL)
85 {
86 /* Check if this was a Kernel Trap */
87 if (Context->SegCs == KGDT64_R0_CODE)
88 {
89 /* Set valid selectors */
90 TrapFrame->SegCs = KGDT64_R0_CODE;
91 TrapFrame->SegSs = KGDT64_R0_DATA;
92 }
93 else
94 {
95 /* Copy selectors */
96 TrapFrame->SegCs = Context->SegCs;
97 TrapFrame->SegSs = Context->SegSs;
98 }
99
100 /* RIP, RSP, EFLAGS */
101 TrapFrame->Rip = Context->Rip;
102 TrapFrame->Rsp = Context->Rsp;
103 TrapFrame->EFlags = Context->EFlags;
104 }
105
106 /* Handle segment selectors */
107 if (ContextFlags & CONTEXT_SEGMENTS)
108 {
109 /* Check if this was a Kernel Trap */
110 if (Context->SegCs == KGDT64_R0_CODE)
111 {
112 /* Set valid selectors */
113 TrapFrame->SegDs = KGDT64_R3_DATA | RPL_MASK;
114 TrapFrame->SegEs = KGDT64_R3_DATA | RPL_MASK;
115 TrapFrame->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
116 TrapFrame->SegGs = KGDT64_R3_DATA | RPL_MASK;
117 }
118 else
119 {
120 /* Copy selectors */
121 TrapFrame->SegDs = Context->SegDs;
122 TrapFrame->SegEs = Context->SegEs;
123 TrapFrame->SegFs = Context->SegFs;
124 TrapFrame->SegGs = Context->SegGs;
125 }
126 }
127
128 /* Handle debug registers */
129 if (ContextFlags & CONTEXT_DEBUG_REGISTERS)
130 {
131 /* Copy the debug registers */
132 TrapFrame->Dr0 = Context->Dr0;
133 TrapFrame->Dr1 = Context->Dr1;
134 TrapFrame->Dr2 = Context->Dr2;
135 TrapFrame->Dr3 = Context->Dr3;
136 TrapFrame->Dr6 = Context->Dr6;
137 TrapFrame->Dr7 = Context->Dr7;
138 }
139
140 /* Restore IRQL */
141 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
142 }
143
144 VOID
145 NTAPI
146 KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
147 IN PKEXCEPTION_FRAME ExceptionFrame,
148 IN OUT PCONTEXT Context)
149 {
150 KIRQL OldIrql;
151
152 /* Do this at APC_LEVEL */
153 OldIrql = KeGetCurrentIrql();
154 if (OldIrql < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
155
156 /* Handle integer registers */
157 if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
158 {
159 Context->Rax = TrapFrame->Rax;
160 Context->Rbx = TrapFrame->Rbx;
161 Context->Rcx = TrapFrame->Rcx;
162 Context->Rdx = TrapFrame->Rdx;
163 Context->Rsi = TrapFrame->Rsi;
164 Context->Rdi = TrapFrame->Rdi;
165 Context->Rbp = TrapFrame->Rbp;
166 Context->R8 = TrapFrame->R8;
167 Context->R9 = TrapFrame->R9;
168 Context->R10 = TrapFrame->R10;
169 Context->R11 = TrapFrame->R11;
170
171 if (ExceptionFrame)
172 {
173 Context->R12 = ExceptionFrame->R12;
174 Context->R13 = ExceptionFrame->R13;
175 Context->R14 = ExceptionFrame->R14;
176 Context->R15 = ExceptionFrame->R15;
177 }
178 }
179
180 /* Handle floating point registers */
181 if (((Context->ContextFlags & CONTEXT_FLOATING_POINT) ==
182 CONTEXT_FLOATING_POINT) && (TrapFrame->SegCs & MODE_MASK))
183 {
184 Context->Xmm0 = TrapFrame->Xmm0;
185 Context->Xmm1 = TrapFrame->Xmm1;
186 Context->Xmm2 = TrapFrame->Xmm2;
187 Context->Xmm3 = TrapFrame->Xmm3;
188 Context->Xmm4 = TrapFrame->Xmm4;
189 Context->Xmm5 = TrapFrame->Xmm5;
190 if (ExceptionFrame)
191 {
192 Context->Xmm6 = ExceptionFrame->Xmm6;
193 Context->Xmm7 = ExceptionFrame->Xmm7;
194 Context->Xmm8 = ExceptionFrame->Xmm8;
195 Context->Xmm9 = ExceptionFrame->Xmm9;
196 Context->Xmm10 = ExceptionFrame->Xmm10;
197 Context->Xmm11 = ExceptionFrame->Xmm11;
198 Context->Xmm12 = ExceptionFrame->Xmm12;
199 Context->Xmm13 = ExceptionFrame->Xmm13;
200 Context->Xmm14 = ExceptionFrame->Xmm14;
201 Context->Xmm15 = ExceptionFrame->Xmm15;
202 }
203 }
204
205 /* Handle control registers */
206 if ((Context->ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL)
207 {
208 /* Check if this was a Kernel Trap */
209 if (TrapFrame->SegCs == KGDT64_R0_CODE)
210 {
211 /* Set valid selectors */
212 Context->SegCs = KGDT64_R0_CODE;
213 Context->SegSs = KGDT64_R0_DATA;
214 }
215 else
216 {
217 /* Copy selectors */
218 Context->SegCs = TrapFrame->SegCs;
219 Context->SegSs = TrapFrame->SegSs;
220 }
221
222 /* Copy RIP, RSP, EFLAGS */
223 Context->Rip = TrapFrame->Rip;
224 Context->Rsp = TrapFrame->Rsp;
225 Context->EFlags = TrapFrame->EFlags;
226 }
227
228 /* Handle segment selectors */
229 if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
230 {
231 /* Check if this was a Kernel Trap */
232 if (TrapFrame->SegCs == KGDT64_R0_CODE)
233 {
234 /* Set valid selectors */
235 Context->SegDs = KGDT64_R3_DATA | RPL_MASK;
236 Context->SegEs = KGDT64_R3_DATA | RPL_MASK;
237 Context->SegFs = KGDT64_R3_CMTEB | RPL_MASK;
238 Context->SegGs = KGDT64_R3_DATA | RPL_MASK;
239 }
240 else
241 {
242 /* Copy selectors */
243 Context->SegDs = TrapFrame->SegDs;
244 Context->SegEs = TrapFrame->SegEs;
245 Context->SegFs = TrapFrame->SegFs;
246 Context->SegGs = TrapFrame->SegGs;
247 }
248 }
249
250 /* Handle debug registers */
251 if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) ==
252 CONTEXT_DEBUG_REGISTERS)
253 {
254 /* Copy the debug registers */
255 Context->Dr0 = TrapFrame->Dr0;
256 Context->Dr1 = TrapFrame->Dr1;
257 Context->Dr2 = TrapFrame->Dr2;
258 Context->Dr3 = TrapFrame->Dr3;
259 Context->Dr6 = TrapFrame->Dr6;
260 Context->Dr7 = TrapFrame->Dr7;
261 }
262
263 /* Restore IRQL */
264 if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
265 }
266