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)
8 /* INCLUDES ******************************************************************/
15 /* FUNCTIONS *****************************************************************/
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
)
27 /* Make sure we have an amd64 context, then remove the flag */
28 ASSERT(ContextFlags
& CONTEXT_AMD64
);
29 ContextFlags
&= ~CONTEXT_AMD64
;
31 /* Do this at APC_LEVEL */
32 OldIrql
= KeGetCurrentIrql();
33 if (OldIrql
< APC_LEVEL
) KeRaiseIrql(APC_LEVEL
, &OldIrql
);
35 /* Handle integer registers */
36 if (ContextFlags
& CONTEXT_INTEGER
)
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
;
51 ExceptionFrame
->R12
= Context
->R12
;
52 ExceptionFrame
->R13
= Context
->R13
;
53 ExceptionFrame
->R14
= Context
->R14
;
54 ExceptionFrame
->R15
= Context
->R15
;
58 /* Handle floating point registers */
59 if ((ContextFlags
& CONTEXT_FLOATING_POINT
) &&
60 ((Context
->SegCs
& MODE_MASK
) != KernelMode
))
62 TrapFrame
->MxCsr
= Context
->MxCsr
;
63 TrapFrame
->Xmm0
= Context
->Xmm0
;
64 TrapFrame
->Xmm1
= Context
->Xmm1
;
65 TrapFrame
->Xmm2
= Context
->Xmm2
;
66 TrapFrame
->Xmm3
= Context
->Xmm3
;
67 TrapFrame
->Xmm4
= Context
->Xmm4
;
68 TrapFrame
->Xmm5
= Context
->Xmm5
;
71 ExceptionFrame
->Xmm6
= Context
->Xmm6
;
72 ExceptionFrame
->Xmm7
= Context
->Xmm7
;
73 ExceptionFrame
->Xmm8
= Context
->Xmm8
;
74 ExceptionFrame
->Xmm9
= Context
->Xmm9
;
75 ExceptionFrame
->Xmm10
= Context
->Xmm10
;
76 ExceptionFrame
->Xmm11
= Context
->Xmm11
;
77 ExceptionFrame
->Xmm12
= Context
->Xmm12
;
78 ExceptionFrame
->Xmm13
= Context
->Xmm13
;
79 ExceptionFrame
->Xmm14
= Context
->Xmm14
;
80 ExceptionFrame
->Xmm15
= Context
->Xmm15
;
84 /* Handle control registers */
85 if (ContextFlags
& CONTEXT_CONTROL
)
87 /* Check if this was a Kernel Trap */
88 if ((Context
->SegCs
& MODE_MASK
) == KernelMode
)
90 /* Set valid selectors */
91 TrapFrame
->SegCs
= KGDT64_R0_CODE
;
92 TrapFrame
->SegSs
= KGDT64_R0_DATA
;
97 TrapFrame
->SegCs
= Context
->SegCs
;
98 TrapFrame
->SegSs
= Context
->SegSs
;
101 /* RIP, RSP, EFLAGS */
102 TrapFrame
->Rip
= Context
->Rip
;
103 TrapFrame
->Rsp
= Context
->Rsp
;
104 TrapFrame
->EFlags
= Context
->EFlags
;
107 /* Handle segment selectors */
108 if (ContextFlags
& CONTEXT_SEGMENTS
)
110 /* Check if this was a Kernel Trap */
111 if ((Context
->SegCs
& MODE_MASK
) == KernelMode
)
113 /* Set valid selectors */
114 TrapFrame
->SegDs
= KGDT64_R3_DATA
| RPL_MASK
;
115 TrapFrame
->SegEs
= KGDT64_R3_DATA
| RPL_MASK
;
116 TrapFrame
->SegFs
= KGDT64_R3_CMTEB
| RPL_MASK
;
117 TrapFrame
->SegGs
= KGDT64_R3_DATA
| RPL_MASK
;
122 TrapFrame
->SegDs
= Context
->SegDs
;
123 TrapFrame
->SegEs
= Context
->SegEs
;
124 TrapFrame
->SegFs
= Context
->SegFs
;
125 TrapFrame
->SegGs
= Context
->SegGs
;
129 /* Handle debug registers */
130 if (ContextFlags
& CONTEXT_DEBUG_REGISTERS
)
132 /* Copy the debug registers */
133 TrapFrame
->Dr0
= Context
->Dr0
;
134 TrapFrame
->Dr1
= Context
->Dr1
;
135 TrapFrame
->Dr2
= Context
->Dr2
;
136 TrapFrame
->Dr3
= Context
->Dr3
;
137 TrapFrame
->Dr6
= Context
->Dr6
;
138 TrapFrame
->Dr7
= Context
->Dr7
;
142 if (OldIrql
< APC_LEVEL
) KeLowerIrql(OldIrql
);
147 KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame
,
148 IN PKEXCEPTION_FRAME ExceptionFrame
,
149 IN OUT PCONTEXT Context
)
154 /* Do this at APC_LEVEL */
155 OldIrql
= KeGetCurrentIrql();
156 if (OldIrql
< APC_LEVEL
) KeRaiseIrql(APC_LEVEL
, &OldIrql
);
158 /* Make sure we have an amd64 context, then remove the flag */
159 ContextFlags
= Context
->ContextFlags
;
160 ASSERT(ContextFlags
& CONTEXT_AMD64
);
161 ContextFlags
&= ~CONTEXT_AMD64
;
163 /* Handle integer registers */
164 if (ContextFlags
& CONTEXT_INTEGER
)
166 Context
->Rax
= TrapFrame
->Rax
;
167 Context
->Rbx
= TrapFrame
->Rbx
;
168 Context
->Rcx
= TrapFrame
->Rcx
;
169 Context
->Rdx
= TrapFrame
->Rdx
;
170 Context
->Rsi
= TrapFrame
->Rsi
;
171 Context
->Rdi
= TrapFrame
->Rdi
;
172 Context
->Rbp
= TrapFrame
->Rbp
;
173 Context
->R8
= TrapFrame
->R8
;
174 Context
->R9
= TrapFrame
->R9
;
175 Context
->R10
= TrapFrame
->R10
;
176 Context
->R11
= TrapFrame
->R11
;
180 Context
->R12
= ExceptionFrame
->R12
;
181 Context
->R13
= ExceptionFrame
->R13
;
182 Context
->R14
= ExceptionFrame
->R14
;
183 Context
->R15
= ExceptionFrame
->R15
;
187 /* Handle floating point registers */
188 if ((ContextFlags
& CONTEXT_FLOATING_POINT
) &&
189 ((TrapFrame
->SegCs
& MODE_MASK
) != KernelMode
))
191 Context
->Xmm0
= TrapFrame
->Xmm0
;
192 Context
->Xmm1
= TrapFrame
->Xmm1
;
193 Context
->Xmm2
= TrapFrame
->Xmm2
;
194 Context
->Xmm3
= TrapFrame
->Xmm3
;
195 Context
->Xmm4
= TrapFrame
->Xmm4
;
196 Context
->Xmm5
= TrapFrame
->Xmm5
;
199 Context
->Xmm6
= ExceptionFrame
->Xmm6
;
200 Context
->Xmm7
= ExceptionFrame
->Xmm7
;
201 Context
->Xmm8
= ExceptionFrame
->Xmm8
;
202 Context
->Xmm9
= ExceptionFrame
->Xmm9
;
203 Context
->Xmm10
= ExceptionFrame
->Xmm10
;
204 Context
->Xmm11
= ExceptionFrame
->Xmm11
;
205 Context
->Xmm12
= ExceptionFrame
->Xmm12
;
206 Context
->Xmm13
= ExceptionFrame
->Xmm13
;
207 Context
->Xmm14
= ExceptionFrame
->Xmm14
;
208 Context
->Xmm15
= ExceptionFrame
->Xmm15
;
212 /* Handle control registers */
213 if (ContextFlags
& CONTEXT_CONTROL
)
215 /* Check if this was a Kernel Trap */
216 if ((TrapFrame
->SegCs
& MODE_MASK
) == KernelMode
)
218 /* Set valid selectors */
219 Context
->SegCs
= KGDT64_R0_CODE
;
220 Context
->SegSs
= KGDT64_R0_DATA
;
225 Context
->SegCs
= TrapFrame
->SegCs
;
226 Context
->SegSs
= TrapFrame
->SegSs
;
229 /* Copy RIP, RSP, EFLAGS */
230 Context
->Rip
= TrapFrame
->Rip
;
231 Context
->Rsp
= TrapFrame
->Rsp
;
232 Context
->EFlags
= TrapFrame
->EFlags
;
235 /* Handle segment selectors */
236 if (ContextFlags
& CONTEXT_SEGMENTS
)
238 /* Check if this was a Kernel Trap */
239 if ((TrapFrame
->SegCs
& MODE_MASK
) == KernelMode
)
241 /* Set valid selectors */
242 Context
->SegDs
= KGDT64_R3_DATA
| RPL_MASK
;
243 Context
->SegEs
= KGDT64_R3_DATA
| RPL_MASK
;
244 Context
->SegFs
= KGDT64_R3_CMTEB
| RPL_MASK
;
245 Context
->SegGs
= KGDT64_R3_DATA
| RPL_MASK
;
250 Context
->SegDs
= TrapFrame
->SegDs
;
251 Context
->SegEs
= TrapFrame
->SegEs
;
252 Context
->SegFs
= TrapFrame
->SegFs
;
253 Context
->SegGs
= TrapFrame
->SegGs
;
257 /* Handle debug registers */
258 if (ContextFlags
& CONTEXT_DEBUG_REGISTERS
)
260 /* Copy the debug registers */
261 Context
->Dr0
= TrapFrame
->Dr0
;
262 Context
->Dr1
= TrapFrame
->Dr1
;
263 Context
->Dr2
= TrapFrame
->Dr2
;
264 Context
->Dr3
= TrapFrame
->Dr3
;
265 Context
->Dr6
= TrapFrame
->Dr6
;
266 Context
->Dr7
= TrapFrame
->Dr7
;
270 if (OldIrql
< APC_LEVEL
) KeLowerIrql(OldIrql
);