2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/include/trap_x.h
5 * PURPOSE: Internal Inlined Functions for the Trap Handling Code
6 * PROGRAMMERS: ReactOS Portable Systems Group
14 KiDumpTrapFrame(IN PKTRAP_FRAME TrapFrame
)
16 /* Dump the whole thing */
17 DPRINT1("DbgEbp: %x\n", TrapFrame
->DbgEbp
);
18 DPRINT1("DbgEip: %x\n", TrapFrame
->DbgEip
);
19 DPRINT1("DbgArgMark: %x\n", TrapFrame
->DbgArgMark
);
20 DPRINT1("DbgArgPointer: %x\n", TrapFrame
->DbgArgPointer
);
21 DPRINT1("TempSegCs: %x\n", TrapFrame
->TempSegCs
);
22 DPRINT1("TempEsp: %x\n", TrapFrame
->TempEsp
);
23 DPRINT1("Dr0: %x\n", TrapFrame
->Dr0
);
24 DPRINT1("Dr1: %x\n", TrapFrame
->Dr1
);
25 DPRINT1("Dr2: %x\n", TrapFrame
->Dr2
);
26 DPRINT1("Dr3: %x\n", TrapFrame
->Dr3
);
27 DPRINT1("Dr6: %x\n", TrapFrame
->Dr6
);
28 DPRINT1("Dr7: %x\n", TrapFrame
->Dr7
);
29 DPRINT1("SegGs: %x\n", TrapFrame
->SegGs
);
30 DPRINT1("SegEs: %x\n", TrapFrame
->SegEs
);
31 DPRINT1("SegDs: %x\n", TrapFrame
->SegDs
);
32 DPRINT1("Edx: %x\n", TrapFrame
->Edx
);
33 DPRINT1("Ecx: %x\n", TrapFrame
->Ecx
);
34 DPRINT1("Eax: %x\n", TrapFrame
->Eax
);
35 DPRINT1("PreviousPreviousMode: %x\n", TrapFrame
->PreviousPreviousMode
);
36 DPRINT1("ExceptionList: %x\n", TrapFrame
->ExceptionList
);
37 DPRINT1("SegFs: %x\n", TrapFrame
->SegFs
);
38 DPRINT1("Edi: %x\n", TrapFrame
->Edi
);
39 DPRINT1("Esi: %x\n", TrapFrame
->Esi
);
40 DPRINT1("Ebx: %x\n", TrapFrame
->Ebx
);
41 DPRINT1("Ebp: %x\n", TrapFrame
->Ebp
);
42 DPRINT1("ErrCode: %x\n", TrapFrame
->ErrCode
);
43 DPRINT1("Eip: %x\n", TrapFrame
->Eip
);
44 DPRINT1("SegCs: %x\n", TrapFrame
->SegCs
);
45 DPRINT1("EFlags: %x\n", TrapFrame
->EFlags
);
46 DPRINT1("HardwareEsp: %x\n", TrapFrame
->HardwareEsp
);
47 DPRINT1("HardwareSegSs: %x\n", TrapFrame
->HardwareSegSs
);
48 DPRINT1("V86Es: %x\n", TrapFrame
->V86Es
);
49 DPRINT1("V86Ds: %x\n", TrapFrame
->V86Ds
);
50 DPRINT1("V86Fs: %x\n", TrapFrame
->V86Fs
);
51 DPRINT1("V86Gs: %x\n", TrapFrame
->V86Gs
);
57 KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame
)
59 /* Set the debug information */
60 TrapFrame
->DbgArgPointer
= TrapFrame
->Edx
;
61 TrapFrame
->DbgArgMark
= 0xBADB0D00;
62 TrapFrame
->DbgEip
= TrapFrame
->Eip
;
63 TrapFrame
->DbgEbp
= TrapFrame
->Ebp
;
68 KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame
,
69 IN KTRAP_STATE_BITS SkipBits
)
71 /* Make sure interrupts are disabled */
72 if (__readeflags() & EFLAGS_INTERRUPT_MASK
)
74 DPRINT1("Exiting with interrupts enabled: %lx\n", __readeflags());
78 /* Make sure this is a real trap frame */
79 if (TrapFrame
->DbgArgMark
!= 0xBADB0D00)
81 DPRINT1("Exiting with an invalid trap frame? (No MAGIC in trap frame)\n");
82 KiDumpTrapFrame(TrapFrame
);
86 /* Make sure we're not in user-mode or something */
87 if (Ke386GetFs() != KGDT_R0_PCR
)
89 DPRINT1("Exiting with an invalid FS: %lx\n", Ke386GetFs());
93 /* Make sure we have a valid SEH chain */
94 if (KeGetPcr()->Tib
.ExceptionList
== 0)
96 DPRINT1("Exiting with NULL exception chain: %p\n", KeGetPcr()->Tib
.ExceptionList
);
100 /* Make sure we're restoring a valid SEH chain */
101 if (TrapFrame
->ExceptionList
== 0)
103 DPRINT1("Entered a trap with a NULL exception chain: %p\n", TrapFrame
->ExceptionList
);
107 /* If we're ignoring previous mode, make sure caller doesn't actually want it */
108 if ((SkipBits
.SkipPreviousMode
) && (TrapFrame
->PreviousPreviousMode
!= -1))
110 DPRINT1("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx", TrapFrame
->PreviousPreviousMode
);
115 #define KiExitTrapDebugChecks(x, y)
116 #define KiFillTrapFrameDebug(x)
125 KiUserTrap(IN PKTRAP_FRAME TrapFrame
)
127 /* Anything else but Ring 0 is Ring 3 */
128 return (TrapFrame
->SegCs
!= KGDT_R0_CODE
);
133 KiVdmTrap(IN PKTRAP_FRAME TrapFrame
)
135 /* Either the V8086 flag is on, or this is user-mode with a VDM */
136 return ((TrapFrame
->EFlags
& EFLAGS_V86_MASK
) ||
137 ((KiUserTrap(TrapFrame
)) && (PsGetCurrentProcess()->VdmObjects
)));
142 KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame
)
147 /* Check for V8086 or user-mode trap */
148 if ((TrapFrame
->EFlags
& EFLAGS_V86_MASK
) ||
149 (KiUserTrap(TrapFrame
)))
152 Thread
= KeGetCurrentThread();
155 /* Turn off the alerted state for kernel mode */
156 Thread
->Alerted
[KernelMode
] = FALSE
;
158 /* Are there pending user APCs? */
159 if (!Thread
->ApcState
.UserApcPending
) break;
161 /* Raise to APC level and enable interrupts */
162 OldIrql
= KfRaiseIrql(APC_LEVEL
);
166 KiDeliverApc(UserMode
, NULL
, TrapFrame
);
168 /* Restore IRQL and disable interrupts once again */
169 KfLowerIrql(OldIrql
);
177 KiDispatchException0Args(IN NTSTATUS Code
,
178 IN ULONG_PTR Address
,
179 IN PKTRAP_FRAME TrapFrame
)
181 /* Helper for exceptions with no arguments */
182 KiDispatchExceptionFromTrapFrame(Code
, Address
, 0, 0, 0, 0, TrapFrame
);
187 KiDispatchException1Args(IN NTSTATUS Code
,
188 IN ULONG_PTR Address
,
190 IN PKTRAP_FRAME TrapFrame
)
192 /* Helper for exceptions with no arguments */
193 KiDispatchExceptionFromTrapFrame(Code
, Address
, 1, P1
, 0, 0, TrapFrame
);
198 KiDispatchException2Args(IN NTSTATUS Code
,
199 IN ULONG_PTR Address
,
202 IN PKTRAP_FRAME TrapFrame
)
204 /* Helper for exceptions with no arguments */
205 KiDispatchExceptionFromTrapFrame(Code
, Address
, 2, P1
, P2
, 0, TrapFrame
);
210 KiSystemCallReturn(IN PKTRAP_FRAME TrapFrame
)
212 /* Restore nonvolatiles, EAX, and do a "jump" back to the kernel caller */
216 "movl %c[b](%%esp), %%ebx\n"
217 "movl %c[s](%%esp), %%esi\n"
218 "movl %c[i](%%esp), %%edi\n"
219 "movl %c[p](%%esp), %%ebp\n"
220 "movl %c[a](%%esp), %%eax\n"
221 "movl %c[e](%%esp), %%edx\n"
222 "addl $%c[v],%%esp\n" /* A WHOLE *KERNEL* frame since we're not IRET'ing */
226 [b
] "i"(KTRAP_FRAME_EBX
),
227 [s
] "i"(KTRAP_FRAME_ESI
),
228 [i
] "i"(KTRAP_FRAME_EDI
),
229 [p
] "i"(KTRAP_FRAME_EBP
),
230 [a
] "i"(KTRAP_FRAME_EAX
),
231 [e
] "i"(KTRAP_FRAME_EIP
),
232 [v
] "i"(KTRAP_FRAME_ESP
)
239 KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame
)
241 /* Regular interrupt exit, but we only restore EAX as a volatile */
245 "movl %c[b](%%esp), %%ebx\n"
246 "movl %c[s](%%esp), %%esi\n"
247 "movl %c[i](%%esp), %%edi\n"
248 "movl %c[p](%%esp), %%ebp\n"
249 "movl %c[a](%%esp), %%eax\n"
250 "addl $%c[e],%%esp\n"
254 [b
] "i"(KTRAP_FRAME_EBX
),
255 [s
] "i"(KTRAP_FRAME_ESI
),
256 [i
] "i"(KTRAP_FRAME_EDI
),
257 [p
] "i"(KTRAP_FRAME_EBP
),
258 [a
] "i"(KTRAP_FRAME_EAX
),
259 [e
] "i"(KTRAP_FRAME_EIP
)
266 KiSystemCallSysExitReturn(IN PKTRAP_FRAME TrapFrame
)
268 /* Restore nonvolatiles, EAX, and do a SYSEXIT back to the user caller */
272 "movl %c[s](%%esp), %%esi\n"
273 "movl %c[b](%%esp), %%ebx\n"
274 "movl %c[i](%%esp), %%edi\n"
275 "movl %c[p](%%esp), %%ebp\n"
276 "movl %c[a](%%esp), %%eax\n"
277 "movl %c[e](%%esp), %%edx\n" /* SYSEXIT says EIP in EDX */
278 "movl %c[x](%%esp), %%ecx\n" /* SYSEXIT says ESP in ECX */
279 "addl $%c[v],%%esp\n" /* A WHOLE *USER* frame since we're not IRET'ing */
283 [b
] "i"(KTRAP_FRAME_EBX
),
284 [s
] "i"(KTRAP_FRAME_ESI
),
285 [i
] "i"(KTRAP_FRAME_EDI
),
286 [p
] "i"(KTRAP_FRAME_EBP
),
287 [a
] "i"(KTRAP_FRAME_EAX
),
288 [e
] "i"(KTRAP_FRAME_EIP
),
289 [x
] "i"(KTRAP_FRAME_ESP
),
290 [v
] "i"(KTRAP_FRAME_V86_ES
)
297 KiTrapReturn(IN PKTRAP_FRAME TrapFrame
)
299 /* Regular interrupt exit */
303 "movl %c[a](%%esp), %%eax\n"
304 "movl %c[b](%%esp), %%ebx\n"
305 "movl %c[c](%%esp), %%ecx\n"
306 "movl %c[d](%%esp), %%edx\n"
307 "movl %c[s](%%esp), %%esi\n"
308 "movl %c[i](%%esp), %%edi\n"
309 "movl %c[p](%%esp), %%ebp\n"
310 "addl $%c[e],%%esp\n"
314 [a
] "i"(KTRAP_FRAME_EAX
),
315 [b
] "i"(KTRAP_FRAME_EBX
),
316 [c
] "i"(KTRAP_FRAME_ECX
),
317 [d
] "i"(KTRAP_FRAME_EDX
),
318 [s
] "i"(KTRAP_FRAME_ESI
),
319 [i
] "i"(KTRAP_FRAME_EDI
),
320 [p
] "i"(KTRAP_FRAME_EBP
),
321 [e
] "i"(KTRAP_FRAME_EIP
)