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