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 // Unreachable code hint for GCC 4.5.x, older GCC versions, and MSVC
17 #if __GNUC__ * 100 + __GNUC_MINOR__ >= 405
18 #define UNREACHABLE __builtin_unreachable()
20 #define UNREACHABLE __builtin_trap()
23 #define UNREACHABLE __assume(0)
24 #define __builtin_expect(a,b) (a)
34 KiUserTrap(IN PKTRAP_FRAME TrapFrame
)
36 /* Anything else but Ring 0 is Ring 3 */
37 return (TrapFrame
->SegCs
& MODE_MASK
);
45 KiDumpTrapFrame(IN PKTRAP_FRAME TrapFrame
)
47 /* Dump the whole thing */
48 DbgPrint("DbgEbp: %x\n", TrapFrame
->DbgEbp
);
49 DbgPrint("DbgEip: %x\n", TrapFrame
->DbgEip
);
50 DbgPrint("DbgArgMark: %x\n", TrapFrame
->DbgArgMark
);
51 DbgPrint("DbgArgPointer: %x\n", TrapFrame
->DbgArgPointer
);
52 DbgPrint("TempSegCs: %x\n", TrapFrame
->TempSegCs
);
53 DbgPrint("TempEsp: %x\n", TrapFrame
->TempEsp
);
54 DbgPrint("Dr0: %x\n", TrapFrame
->Dr0
);
55 DbgPrint("Dr1: %x\n", TrapFrame
->Dr1
);
56 DbgPrint("Dr2: %x\n", TrapFrame
->Dr2
);
57 DbgPrint("Dr3: %x\n", TrapFrame
->Dr3
);
58 DbgPrint("Dr6: %x\n", TrapFrame
->Dr6
);
59 DbgPrint("Dr7: %x\n", TrapFrame
->Dr7
);
60 DbgPrint("SegGs: %x\n", TrapFrame
->SegGs
);
61 DbgPrint("SegEs: %x\n", TrapFrame
->SegEs
);
62 DbgPrint("SegDs: %x\n", TrapFrame
->SegDs
);
63 DbgPrint("Edx: %x\n", TrapFrame
->Edx
);
64 DbgPrint("Ecx: %x\n", TrapFrame
->Ecx
);
65 DbgPrint("Eax: %x\n", TrapFrame
->Eax
);
66 DbgPrint("PreviousPreviousMode: %x\n", TrapFrame
->PreviousPreviousMode
);
67 DbgPrint("ExceptionList: %x\n", TrapFrame
->ExceptionList
);
68 DbgPrint("SegFs: %x\n", TrapFrame
->SegFs
);
69 DbgPrint("Edi: %x\n", TrapFrame
->Edi
);
70 DbgPrint("Esi: %x\n", TrapFrame
->Esi
);
71 DbgPrint("Ebx: %x\n", TrapFrame
->Ebx
);
72 DbgPrint("Ebp: %x\n", TrapFrame
->Ebp
);
73 DbgPrint("ErrCode: %x\n", TrapFrame
->ErrCode
);
74 DbgPrint("Eip: %x\n", TrapFrame
->Eip
);
75 DbgPrint("SegCs: %x\n", TrapFrame
->SegCs
);
76 DbgPrint("EFlags: %x\n", TrapFrame
->EFlags
);
77 DbgPrint("HardwareEsp: %x\n", TrapFrame
->HardwareEsp
);
78 DbgPrint("HardwareSegSs: %x\n", TrapFrame
->HardwareSegSs
);
79 DbgPrint("V86Es: %x\n", TrapFrame
->V86Es
);
80 DbgPrint("V86Ds: %x\n", TrapFrame
->V86Ds
);
81 DbgPrint("V86Fs: %x\n", TrapFrame
->V86Fs
);
82 DbgPrint("V86Gs: %x\n", TrapFrame
->V86Gs
);
88 KiFillTrapFrameDebug(IN PKTRAP_FRAME TrapFrame
)
90 /* Set the debug information */
91 TrapFrame
->DbgArgPointer
= TrapFrame
->Edx
;
92 TrapFrame
->DbgArgMark
= 0xBADB0D00;
93 TrapFrame
->DbgEip
= TrapFrame
->Eip
;
94 TrapFrame
->DbgEbp
= TrapFrame
->Ebp
;
95 TrapFrame
->PreviousPreviousMode
= -1;
100 KiExitTrapDebugChecks(IN PKTRAP_FRAME TrapFrame
,
101 IN KTRAP_EXIT_SKIP_BITS SkipBits
)
103 /* Make sure interrupts are disabled */
104 if (__readeflags() & EFLAGS_INTERRUPT_MASK
)
106 DbgPrint("Exiting with interrupts enabled: %lx\n", __readeflags());
110 /* Make sure this is a real trap frame */
111 if (TrapFrame
->DbgArgMark
!= 0xBADB0D00)
113 DbgPrint("Exiting with an invalid trap frame? (No MAGIC in trap frame)\n");
114 KiDumpTrapFrame(TrapFrame
);
118 /* Make sure we're not in user-mode or something */
119 if (Ke386GetFs() != KGDT_R0_PCR
)
121 DbgPrint("Exiting with an invalid FS: %lx\n", Ke386GetFs());
125 /* Make sure we have a valid SEH chain */
126 if (KeGetPcr()->NtTib
.ExceptionList
== 0)
128 DbgPrint("Exiting with NULL exception chain: %p\n", KeGetPcr()->NtTib
.ExceptionList
);
132 /* Make sure we're restoring a valid SEH chain */
133 if (TrapFrame
->ExceptionList
== 0)
135 DbgPrint("Entered a trap with a NULL exception chain: %p\n", TrapFrame
->ExceptionList
);
139 /* If we're ignoring previous mode, make sure caller doesn't actually want it */
140 if ((SkipBits
.SkipPreviousMode
) && (TrapFrame
->PreviousPreviousMode
!= -1))
142 DbgPrint("Exiting a trap witout restoring previous mode, yet previous mode seems valid: %lx\n", TrapFrame
->PreviousPreviousMode
);
149 KiExitSystemCallDebugChecks(IN ULONG SystemCall
,
150 IN PKTRAP_FRAME TrapFrame
)
154 /* Check if this was a user call */
155 if (KiUserTrap(TrapFrame
))
157 /* Make sure we are not returning with elevated IRQL */
158 OldIrql
= KeGetCurrentIrql();
159 if (OldIrql
!= PASSIVE_LEVEL
)
161 /* Forcibly put us in a sane state */
162 KeGetPcr()->Irql
= PASSIVE_LEVEL
;
166 KeBugCheckEx(IRQL_GT_ZERO_AT_SYSTEM_SERVICE
,
173 /* Make sure we're not attached and that APCs are not disabled */
174 if ((KeGetCurrentThread()->ApcStateIndex
!= CurrentApcEnvironment
) ||
175 (KeGetCurrentThread()->CombinedApcDisable
!= 0))
178 KeBugCheckEx(APC_INDEX_MISMATCH
,
180 KeGetCurrentThread()->ApcStateIndex
,
181 KeGetCurrentThread()->CombinedApcDisable
,
187 #define KiExitTrapDebugChecks(x, y)
188 #define KiFillTrapFrameDebug(x)
189 #define KiExitSystemCallDebugChecks(x, y)
193 // Generic Exit Routine
195 DECLSPEC_NORETURN VOID FASTCALL
KiSystemCallReturn(IN PKTRAP_FRAME TrapFrame
);
196 DECLSPEC_NORETURN VOID FASTCALL
KiSystemCallSysExitReturn(IN PKTRAP_FRAME TrapFrame
);
197 DECLSPEC_NORETURN VOID FASTCALL
KiSystemCallTrapReturn(IN PKTRAP_FRAME TrapFrame
);
198 DECLSPEC_NORETURN VOID FASTCALL
KiEditedTrapReturn(IN PKTRAP_FRAME TrapFrame
);
199 DECLSPEC_NORETURN VOID FASTCALL
KiTrapReturn(IN PKTRAP_FRAME TrapFrame
);
200 DECLSPEC_NORETURN VOID FASTCALL
KiTrapReturnNoSegments(IN PKTRAP_FRAME TrapFrame
);
205 (FASTCALL
*PFAST_SYSTEM_CALL_EXIT
)(
206 IN PKTRAP_FRAME TrapFrame
209 extern PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler
;
212 // Virtual 8086 Mode Optimized Trap Exit
217 KiExitV86Trap(IN PKTRAP_FRAME TrapFrame
)
223 Thread
= KeGetCurrentThread();
226 /* Return if this isn't V86 mode anymore */
227 if (!(TrapFrame
->EFlags
& EFLAGS_V86_MASK
)) KiEoiHelper(TrapFrame
);
229 /* Turn off the alerted state for kernel mode */
230 Thread
->Alerted
[KernelMode
] = FALSE
;
232 /* Are there pending user APCs? */
233 if (__builtin_expect(!Thread
->ApcState
.UserApcPending
, 1)) break;
235 /* Raise to APC level and enable interrupts */
236 OldIrql
= KfRaiseIrql(APC_LEVEL
);
240 KiDeliverApc(UserMode
, NULL
, TrapFrame
);
242 /* Restore IRQL and disable interrupts once again */
243 KfLowerIrql(OldIrql
);
247 /* If we got here, we're still in a valid V8086 context, so quit it */
248 if (__builtin_expect(TrapFrame
->Dr7
& ~DR7_RESERVED_MASK
, 0))
250 /* Not handled yet */
251 DbgPrint("Need Hardware Breakpoint Support!\n");
255 /* Return from interrupt */
256 KiTrapReturnNoSegments(TrapFrame
);
260 // Virtual 8086 Mode Optimized Trap Entry
264 KiEnterV86Trap(IN PKTRAP_FRAME TrapFrame
)
266 /* Save exception list */
267 TrapFrame
->ExceptionList
= KeGetPcr()->NtTib
.ExceptionList
;
269 /* Save DR7 and check for debugging */
270 TrapFrame
->Dr7
= __readdr(7);
271 if (__builtin_expect(TrapFrame
->Dr7
& ~DR7_RESERVED_MASK
, 0))
273 DbgPrint("Need Hardware Breakpoint Support!\n");
279 // Interrupt Trap Entry
283 KiEnterInterruptTrap(IN PKTRAP_FRAME TrapFrame
)
285 /* Save exception list and terminate it */
286 TrapFrame
->ExceptionList
= KeGetPcr()->NtTib
.ExceptionList
;
287 KeGetPcr()->NtTib
.ExceptionList
= EXCEPTION_CHAIN_END
;
289 /* Flush DR7 and check for debugging */
291 if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader
.DebugActive
& 0xFF, 0))
293 DbgPrint("Need Hardware Breakpoint Support!\n");
297 /* Set debug header */
298 KiFillTrapFrameDebug(TrapFrame
);
302 // Generic Trap Entry
306 KiEnterTrap(IN PKTRAP_FRAME TrapFrame
)
308 /* Save exception list */
309 TrapFrame
->ExceptionList
= KeGetPcr()->NtTib
.ExceptionList
;
311 /* Flush DR7 and check for debugging */
313 if (__builtin_expect(KeGetCurrentThread()->DispatcherHeader
.DebugActive
& 0xFF, 0))
315 DbgPrint("Need Hardware Breakpoint Support!\n");
319 /* Set debug header */
320 KiFillTrapFrameDebug(TrapFrame
);