2 * FILE: ntoskrnl/ke/amd64/trap.S
3 * COPYRIGHT: See COPYING in the top level directory
4 * PURPOSE: System Traps, Entrypoints and Exitpoints
5 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
8 /* INCLUDES ******************************************************************/
11 #include <ksamd64.inc>
12 #include <trapamd64.inc>
14 EXTERN KiDispatchException:PROC
15 EXTERN FrLdrDbgPrint:DWORD
16 EXTERN KeBugCheckWithTf:PROC
17 EXTERN MmAccessFault:PROC
18 EXTERN KiSystemFatalException:PROC
19 EXTERN KiNpxNotAvailableFaultHandler:PROC
20 EXTERN KiGeneralProtectionFaultHandler:PROC
21 EXTERN KiXmmExceptionHandler:PROC
22 EXTERN KiDeliverApc:PROC
23 EXTERN KiDispatchInterrupt:PROC
25 /* GLOBALS *******************************************************************/
29 PUBLIC MsgUnimplemented
31 .asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
34 /* Helper Macros *************************************************************/
36 MACRO(DispatchException, Status, Number, P1, P2, P3)
42 call InternalDispatchException
45 MACRO(Fatal, BugcheckCode)
49 call KiSystemFatalException
53 /* FUNCTIONS *****************************************************************/
59 PUBLIC InterruptDispatchTable
60 InterruptDispatchTable:
64 jmp KiUnexpectedInterrupt
69 // rbp = TrapFrame, eax = ExceptionCode, edx = NumParams, r9,r10,r11 = params
70 .PROC InternalDispatchException
72 /* Allocate stack space for EXCEPTION_RECORD and KEXCEPTION_FRAME */
73 sub rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
74 .allocstack (EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH)
77 /* Set up EXCEPTION_RECORD */
78 lea rcx, [rsp + KEXCEPTION_FRAME_LENGTH]
79 mov [rcx + EXCEPTION_RECORD_ExceptionCode], eax
81 mov [rcx + EXCEPTION_RECORD_ExceptionFlags], eax
82 mov [rcx + EXCEPTION_RECORD_ExceptionRecord], rax
83 mov rax, [rbp + KTRAP_FRAME_Rip]
84 mov [rcx + EXCEPTION_RECORD_ExceptionAddress], rax
85 mov [rcx + EXCEPTION_RECORD_NumberParameters], edx
86 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(00)], r9
87 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(08)], r10
88 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(10)], r11
90 /* Set up KEXCEPTION_FRAME */
91 mov rax, [rbp + KTRAP_FRAME_Rbp]
92 mov [rsp + KEXCEPTION_FRAME_Rbp], rax
93 mov [rsp + KEXCEPTION_FRAME_Rbx], rbx
94 mov [rsp + KEXCEPTION_FRAME_Rdi], rdi
95 mov [rsp + KEXCEPTION_FRAME_Rsi], rsi
96 mov [rsp + KEXCEPTION_FRAME_R12], r12
97 mov [rsp + KEXCEPTION_FRAME_R13], r13
98 mov [rsp + KEXCEPTION_FRAME_R14], r14
99 mov [rsp + KEXCEPTION_FRAME_R15], r15
100 movdqa [rsp + KEXCEPTION_FRAME_Xmm6], xmm6
101 movdqa [rsp + KEXCEPTION_FRAME_Xmm7], xmm7
102 movdqa [rsp + KEXCEPTION_FRAME_Xmm8], xmm8
103 movdqa [rsp + KEXCEPTION_FRAME_Xmm9], xmm9
104 movdqa [rsp + KEXCEPTION_FRAME_Xmm10], xmm10
105 movdqa [rsp + KEXCEPTION_FRAME_Xmm11], xmm11
106 movdqa [rsp + KEXCEPTION_FRAME_Xmm12], xmm12
107 movdqa [rsp + KEXCEPTION_FRAME_Xmm13], xmm13
108 movdqa [rsp + KEXCEPTION_FRAME_Xmm14], xmm14
109 movdqa [rsp + KEXCEPTION_FRAME_Xmm15], xmm15
110 mov qword ptr [rsp + KEXCEPTION_FRAME_Return], 0
112 /* Call KiDispatchException */
113 // rcx already points to ExceptionRecord
114 mov rdx, rsp // ExceptionFrame
115 mov r8, rbp // TrapFrame
116 mov r9b, [r8 + KTRAP_FRAME_PreviousMode] // PreviousMode
117 mov byte ptr [rsp + KEXCEPTION_FRAME_P5], 1 // FirstChance
118 call KiDispatchException
120 /* Restore registers */
121 mov r12, [rsp + KEXCEPTION_FRAME_R12]
122 mov r13, [rsp + KEXCEPTION_FRAME_R13]
123 mov r14, [rsp + KEXCEPTION_FRAME_R14]
124 mov r15, [rsp + KEXCEPTION_FRAME_R15]
125 movdqa xmm6, [rsp + KEXCEPTION_FRAME_Xmm6]
126 movdqa xmm7, [rsp + KEXCEPTION_FRAME_Xmm7]
127 movdqa xmm8, [rsp + KEXCEPTION_FRAME_Xmm8]
128 movdqa xmm9, [rsp + KEXCEPTION_FRAME_Xmm9]
129 movdqa xmm10, [rsp + KEXCEPTION_FRAME_Xmm10]
130 movdqa xmm11, [rsp + KEXCEPTION_FRAME_Xmm11]
131 movdqa xmm12, [rsp + KEXCEPTION_FRAME_Xmm12]
132 movdqa xmm13, [rsp + KEXCEPTION_FRAME_Xmm13]
133 movdqa xmm14, [rsp + KEXCEPTION_FRAME_Xmm14]
134 movdqa xmm15, [rsp + KEXCEPTION_FRAME_Xmm15]
136 add rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
138 .ENDP InternalDispatchException
141 /* SOFTWARE INTERRUPT SERVICES ***********************************************/
143 PUBLIC KiDivideErrorFault
144 FUNC KiDivideErrorFault
145 /* Push pseudo error code */
146 EnterTrap TF_SAVE_ALL
148 /* Enable interrupts */
151 /* Dispatch the exception */
152 DispatchException STATUS_INTEGER_DIVIDE_BY_ZERO, 0, 0, 0, 0
156 ENDFUNC KiDivideErrorFault
159 PUBLIC KiDebugTrapOrFault
160 FUNC KiDebugTrapOrFault
161 /* Push pseudo error code */
162 EnterTrap TF_SAVE_ALL
164 /* Check if the frame was from kernelmode */
165 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
166 jz KiDebugTrapOrFaultKMode
168 /* Enable interrupts for user-mode */
171 KiDebugTrapOrFaultKMode:
172 /* Dispatch the exception */
173 DispatchException STATUS_SINGLE_STEP, 0, 0, 0, 0
177 ENDFUNC KiDebugTrapOrFault
180 PUBLIC KiNmiInterrupt
182 /* Push pseudo error code */
183 EnterTrap TF_SAVE_ALL
185 UNIMPLEMENTED KiNmiInterrupt
190 ENDFUNC KiNmiInterrupt
193 PUBLIC KiBreakpointTrap
194 FUNC KiBreakpointTrap
195 /* Push pseudo error code */
196 EnterTrap TF_SAVE_ALL
198 /* Dispatch the exception */
199 DispatchException STATUS_BREAKPOINT, 3, 0, 0, 0
203 ENDFUNC KiBreakpointTrap
206 PUBLIC KiOverflowTrap
208 /* Push pseudo error code */
209 EnterTrap TF_SAVE_ALL
211 /* Enable interrupts */
214 /* Dispatch the exception */
215 DispatchException STATUS_INTEGER_OVERFLOW, 3, 0, 0, 0
219 ENDFUNC KiOverflowTrap
225 EnterTrap TF_SAVE_ALL
227 /* Check if the frame was from kernelmode */
228 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
229 jnz KiBoundFaultUserMode
232 Fatal EXCEPTION_BOUND_CHECK
234 KiBoundFaultUserMode:
235 /* Enable interrupts for user-mode */
238 /* Dispatch the exception */
239 DispatchException STATUS_ARRAY_BOUNDS_EXCEEDED, 0, 0, 0, 0
246 PUBLIC KiInvalidOpcodeFault
247 FUNC KiInvalidOpcodeFault
249 EnterTrap TF_SAVE_ALL
251 /* Enable interrupts */
254 /* Check if the frame was from kernelmode */
255 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
256 jz KiInvalidOpcodeKernel
258 // FIXME: handle STATUS_INVALID_LOCK_SEQUENCE
260 KiInvalidOpcodeKernel:
261 /* Kernel mode fault */
263 /* Dispatch the exception */
264 DispatchException STATUS_ILLEGAL_INSTRUCTION, 3, 0, 0, 0
268 ENDFUNC KiInvalidOpcodeFault
271 PUBLIC KiNpxNotAvailableFault
272 FUNC KiNpxNotAvailableFault
274 EnterTrap TF_SAVE_ALL
276 /* Call the C handler */
278 call KiNpxNotAvailableFaultHandler
280 /* Check the return status code */
282 jz KiNpxNotAvailableFaultExit
284 /* Dispatch the exception */
285 DispatchException eax, 3, 0, 0, 0
287 KiNpxNotAvailableFaultExit:
290 ENDFUNC KiNpxNotAvailableFault
293 PUBLIC KiDoubleFaultAbort
294 FUNC KiDoubleFaultAbort
296 EnterTrap TF_SAVE_ALL
299 Fatal 8 // EXCEPTION_DOUBLE_FAULT
301 ENDFUNC KiDoubleFaultAbort
304 PUBLIC KiNpxSegmentOverrunAbort
305 FUNC KiNpxSegmentOverrunAbort
307 EnterTrap TF_SAVE_ALL
310 Fatal EXCEPTION_NPX_OVERRUN
312 ENDFUNC KiNpxSegmentOverrunAbort
315 PUBLIC KiInvalidTssFault
316 FUNC KiInvalidTssFault
317 /* We have an error code */
318 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
321 Fatal EXCEPTION_INVALID_TSS
323 ENDFUNC KiInvalidTssFault
326 PUBLIC KiSegmentNotPresentFault
327 FUNC KiSegmentNotPresentFault
328 /* We have an error code */
329 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
332 Fatal EXCEPTION_SEGMENT_NOT_PRESENT
334 ENDFUNC KiSegmentNotPresentFault
339 /* We have an error code */
340 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
343 Fatal EXCEPTION_STACK_FAULT
348 PUBLIC KiGeneralProtectionFault
349 FUNC KiGeneralProtectionFault
350 /* We have an error code */
351 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
353 /* Call the C handler */
355 call KiGeneralProtectionFaultHandler
357 /* Check for success */
361 /* Dispatch the exception */
362 DispatchException eax, 3, 0, 0, 0
367 mov ecx, UNEXPECTED_KERNEL_MODE_TRAP
368 mov rdx, HEX(000D) // EXCEPTION_GP_FAULT
370 mov r9, [rbp + KTRAP_FRAME_ErrorCode] // error code
372 mov [rsp + KTRAP_FRAME_P5+8], rbp // trap frame
373 call KeBugCheckWithTf
379 ENDFUNC KiGeneralProtectionFault
384 /* We have an error code */
385 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
387 /* Save page fault address */
389 mov [rbp + KTRAP_FRAME_FaultAddress], rdx
391 /* Call page fault handler */
392 mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction
395 mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode
397 mov r9, rbp // TrapInformation
400 /* Check for success */
404 /* Set parameter 1 to error code */
405 mov r9d, [rbp + KTRAP_FRAME_ErrorCode]
407 /* Set parameter2 to faulting address */
408 mov r10, cr2 // Param2 = faulting address
410 cmp eax, STATUS_ACCESS_VIOLATION
412 cmp eax, STATUS_GUARD_PAGE_VIOLATION
414 cmp eax, STATUS_STACK_OVERFLOW
419 /* Dispatch in-page exception */
420 mov r11d, eax // Param3 = Status
421 mov eax, STATUS_IN_PAGE_ERROR // ExceptionCode
422 mov edx, 3 // ParamCount
423 call InternalDispatchException
427 /* Use more proper status code */
428 mov eax, KI_EXCEPTION_ACCESS_VIOLATION
431 /* Setup a normal page fault exception */
432 mov edx, 2 // ParamCount
433 call InternalDispatchException
441 PUBLIC KiFloatingErrorFault
442 FUNC KiFloatingErrorFault
444 EnterTrap TF_SAVE_ALL
446 UNIMPLEMENTED KiFloatingErrorFault
451 ENDFUNC KiFloatingErrorFault
454 PUBLIC KiAlignmentFault
455 FUNC KiAlignmentFault
456 /* We have an error code */
457 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
460 Fatal EXCEPTION_ALIGNMENT_CHECK
462 ENDFUNC KiAlignmentFault
468 EnterTrap TF_SAVE_ALL
473 ENDFUNC KiMcheckAbort
476 PUBLIC KiXmmException
479 EnterTrap TF_SAVE_ALL
481 /* Call the C handler */
483 call KiXmmExceptionHandler
485 /* Check for success */
489 /* Dispatch the exception */
490 DispatchException eax, 3, 0, 0, 0
495 ENDFUNC KiXmmException
498 PUBLIC KiRaiseAssertion
499 FUNC KiRaiseAssertion
500 /* We have an error code */
501 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
503 /* Decrement RIP to point to the INT2C instruction (2 bytes, not 1 like INT3) */
504 sub qword ptr [rbp + KTRAP_FRAME_Rip], 2
506 /* Dispatch the exception */
507 DispatchException STATUS_ASSERTION_FAILURE, 0, 0, 0, 0
511 ENDFUNC KiRaiseAssertion
514 PUBLIC KiDebugServiceTrap
515 .PROC KiDebugServiceTrap
517 EnterTrap TF_SAVE_ALL
519 /* Increase Rip to skip the int3 */
520 inc qword ptr [rbp + KTRAP_FRAME_Rip]
522 /* Dispatch the exception (Params = service, buffer, legth) */
523 DispatchException STATUS_BREAKPOINT, 3, [rbp+KTRAP_FRAME_Rax], [rbp+KTRAP_FRAME_Rcx], [rbp+KTRAP_FRAME_Rdx]
527 .ENDP KiDebugServiceTrap
530 PUBLIC KiApcInterrupt
533 EnterTrap (TF_VOLATILES or TF_IRQL)
535 /* Raise to APC_LEVEL */
539 /* End the interrupt */
540 mov dword ptr [APIC_EOI], 0
542 /* Enable interrupts */
545 /* Call the worker routine */
546 mov cl, [rbp + KTRAP_FRAME_SegCs] // ProcessorMode
548 mov rdx, 0 // ExceptionFrame
549 mov r8, rdx // TrapFrame
552 /* Disable interrupts */
556 ExitTrap (TF_VOLATILES or TF_IRQL)
560 PUBLIC KiDpcInterrupt
563 EnterTrap (TF_VOLATILES or TF_IRQL)
565 /* Raise to DISPATCH_LEVEL */
566 mov rax, DISPATCH_LEVEL
569 /* End the interrupt */
570 mov dword ptr [APIC_EOI], 0
572 /* Call the worker routine */
574 call KiDispatchInterrupt
578 ExitTrap (TF_VOLATILES or TF_IRQL)
582 PUBLIC KiIpiInterrupt
585 EnterTrap (TF_VOLATILES or TF_IRQL)
587 /* Raise to IPI_LEVEL */
591 /* End the interrupt */
592 mov dword ptr [APIC_EOI], 0
597 ExitTrap (TF_VOLATILES or TF_IRQL)
601 PUBLIC KiUnexpectedInterrupt
602 FUNC KiUnexpectedInterrupt
603 /* The error code is the vector */
604 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
607 /* Set bugcheck parameters */
608 mov ecx, TRAP_CAUSE_UNKNOWN
609 mov rdx, [rbp + KTRAP_FRAME_ErrorCode] // the vector
610 mov r8, 0 // The unknown floating-point exception
611 mov r9, 0 // The enabled and asserted status bits
613 mov [rbp + KTRAP_FRAME_P5 + 8], rbp // trap frame
614 call KeBugCheckWithTf
619 ENDFUNC KiUnexpectedInterrupt
625 //void __lgdt(void *Source);
631 //void __sgdt(void *Destination);
637 // void __lldt(unsigned short Value)
643 //void __sldt(void *Destination);
649 //void __ltr(unsigned short Source);
655 //void __str(unsigned short *Destination);