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 KiTrapFrameFromPushaStack(IN PKTRAP_FRAME TrapFrame
)
145 * This sequence is Bavarian Alchemist Black Magic
147 * *** DO NOT MODIFY ***
149 TrapFrame
->Edx
= TrapFrame
->Esi
;
150 TrapFrame
->Esi
= TrapFrame
->PreviousPreviousMode
;
151 TrapFrame
->Ecx
= TrapFrame
->Ebx
;
152 TrapFrame
->Ebx
= TrapFrame
->Edi
;
153 TrapFrame
->Edi
= TrapFrame
->Eax
;
154 TrapFrame
->Eax
= TrapFrame
->Ebp
;
155 TrapFrame
->Ebp
= (ULONG
)TrapFrame
->ExceptionList
;
156 TrapFrame
->TempEsp
= TrapFrame
->SegFs
;
161 KiPushaStackFromTrapFrame(IN PKTRAP_FRAME TrapFrame
)
164 * This sequence is Bavarian Alchemist Black Magic
166 * *** DO NOT MODIFY ***
168 TrapFrame
->SegFs
= TrapFrame
->TempEsp
;
169 TrapFrame
->ExceptionList
= (PVOID
)TrapFrame
->Ebp
;
170 TrapFrame
->Ebp
= TrapFrame
->Eax
;
171 TrapFrame
->Eax
= TrapFrame
->Edi
;
172 TrapFrame
->Edi
= TrapFrame
->Ebx
;
173 TrapFrame
->Ebx
= TrapFrame
->Ecx
;
174 TrapFrame
->PreviousPreviousMode
= TrapFrame
->Esi
;
175 TrapFrame
->Esi
= TrapFrame
->Edx
;
180 KiCheckForApcDelivery(IN PKTRAP_FRAME TrapFrame
)
185 /* Check for V8086 or user-mode trap */
186 if ((TrapFrame
->EFlags
& EFLAGS_V86_MASK
) ||
187 (KiUserTrap(TrapFrame
)))
190 Thread
= KeGetCurrentThread();
193 /* Turn off the alerted state for kernel mode */
194 Thread
->Alerted
[KernelMode
] = FALSE
;
196 /* Are there pending user APCs? */
197 if (!Thread
->ApcState
.UserApcPending
) break;
199 /* Raise to APC level and enable interrupts */
200 OldIrql
= KfRaiseIrql(APC_LEVEL
);
204 KiDeliverApc(UserMode
, NULL
, TrapFrame
);
206 /* Restore IRQL and disable interrupts once again */
207 KfLowerIrql(OldIrql
);
215 KiDispatchException0Args(IN NTSTATUS Code
,
216 IN ULONG_PTR Address
,
217 IN PKTRAP_FRAME TrapFrame
)
219 /* Helper for exceptions with no arguments */
220 KiDispatchExceptionFromTrapFrame(Code
, Address
, 0, 0, 0, 0, TrapFrame
);
225 KiDispatchException1Args(IN NTSTATUS Code
,
226 IN ULONG_PTR Address
,
228 IN PKTRAP_FRAME TrapFrame
)
230 /* Helper for exceptions with no arguments */
231 KiDispatchExceptionFromTrapFrame(Code
, Address
, 1, P1
, 0, 0, TrapFrame
);
236 KiDispatchException2Args(IN NTSTATUS Code
,
237 IN ULONG_PTR Address
,
240 IN PKTRAP_FRAME TrapFrame
)
242 /* Helper for exceptions with no arguments */
243 KiDispatchExceptionFromTrapFrame(Code
, Address
, 2, P1
, P2
, 0, TrapFrame
);
248 KiTrapReturn(IN PKTRAP_FRAME TrapFrame
)
250 /* Restore registers */
251 KiPushaStackFromTrapFrame(TrapFrame
);
253 /* Regular interrupt exit */
262 : "r"(TrapFrame
), "i"(KTRAP_FRAME_LENGTH
- KTRAP_FRAME_PREVIOUS_MODE
)