Sync with trunk (48237)
[reactos.git] / ntoskrnl / ke / amd64 / trap.S
1 /*
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)
6 */
7
8 /* INCLUDES ******************************************************************/
9
10 #include <reactos/asm.h>
11 #include <ndk/amd64/asm.h>
12
13 EXTERN KiDispatchException:PROC
14 EXTERN FrLdrDbgPrint:DWORD
15 EXTERN KeBugCheckWithTf:PROC
16 EXTERN MmAccessFault:PROC
17 EXTERN KiSystemFatalException:PROC
18 EXTERN KiNpxNotAvailableFaultHandler:PROC
19 EXTERN KiGeneralProtectionFaultHandler:PROC
20 EXTERN KiXmmExceptionHandler:PROC
21
22 /* GLOBALS *******************************************************************/
23
24 .data
25
26 PUBLIC MsgUnimplemented
27 MsgUnimplemented:
28 .asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
29
30 MsgPageFault:
31 .asciz "Page fault! Code = 0x%x, RIP = %p, FaultingAddress = %p\n"
32
33 MsgGeneralProtFault:
34 .asciz "General protection fault at %p!\n"
35
36 MsgBreakpointTrap:
37 .asciz "BreakpointTrap at %p\n"
38
39 MsgUnexpectedInterrupt:
40 .asciz "UnexpectedInterrupt Vector=0x%02lx\n"
41
42 MsgInvalidOpcodeFault:
43 .asciz "Invalid opcode fault at %p!\n"
44
45 MsgDoubleFault:
46 .asciz "Double fault at %p, rbp=%p!\n"
47
48 MsgTrapInfo:
49 .asciz "Trap: %s at %p\n"
50
51 MACRO(TRAPINFO, func)
52 LOCAL label1, label2
53 #if 0
54 jmp label2
55 label1: .asciz "\func"
56 label2:
57 sub rsp, 32
58 lea rcx, MsgTrapInfo[rip]
59 lea rdx, 1b[rip]
60 mov r8, [rbp + KTRAP_FRAME_Rip]
61 call qword ptr FrLdrDbgPrint[rip]
62 add rsp, 32
63 #endif
64 ENDM
65
66 /* Helper Macros *************************************************************/
67
68 #define TRAPFLAG_VOLATILES HEX(01)
69 #define TRAPFLAG_NONVOLATILES HEX(02)
70 #define TRAPFLAG_XMM HEX(04)
71 #define TRAPFLAG_SEGMENTS HEX(08)
72 #define TRAPFLAG_DEBUG HEX(10)
73 #define TRAPFLAG_HAS_ERRORCODE HEX(100)
74
75 #define TRAPFLAG_SYSTEMSERVICE (TRAPFLAG_VOLATILES|TRAPFLAG_DEBUG)
76 #define TRAPFLAG_ALL HEX(ff)
77
78 /*
79 * Stack Layout:
80 * |-------------------|
81 * | KTRAP_FRAME |
82 * |-------------------| <- rbp
83 * | EXCEPTION_RECORD |
84 * |-------------------|
85 * | KEXCEPTION_FRAME |
86 * |-------------------| <- rsp
87 *
88 */
89
90 /*
91 * ENTER_TRAP_FRAME - Allocate SIZE_KTRAP_FRAME and save registers to it
92 */
93 MACRO(ENTER_TRAP_FRAME, Flags)
94 LOCAL dont_swap
95
96 /* Save the trap flags for this trap */
97 TRAPFLAGS = VAL(Flags)
98
99 /* Size of hardware trap frame */
100 if (TRAPFLAGS AND TRAPFLAG_HAS_ERRORCODE)
101 .pushframe code
102 SIZE_INITIAL_FRAME = 6 * 8
103 else
104 .pushframe
105 SIZE_INITIAL_FRAME = 5 * 8
106 endif
107
108 /* Make room for a KTRAP_FRAME */
109 sub rsp, (SIZE_KTRAP_FRAME - SIZE_INITIAL_FRAME)
110 .allocstack (SIZE_KTRAP_FRAME - SIZE_INITIAL_FRAME)
111 .endprolog
112
113 /* Save rbp */
114 mov [rsp + KTRAP_FRAME_Rbp], rbp
115
116 /* Point rbp to the KTRAP_FRAME */
117 lea rbp, [rsp]
118
119 if (TRAPFLAGS AND TRAPFLAG_NONVOLATILES)
120 /* Save non-volatile registers */
121 mov [rbp + KTRAP_FRAME_Rbx], rbx
122 mov [rbp + KTRAP_FRAME_Rdi], rdi
123 mov [rbp + KTRAP_FRAME_Rsi], rsi
124 endif
125
126 if (TRAPFLAGS AND TRAPFLAG_VOLATILES)
127 /* Save volatile registers */
128 mov [rbp + KTRAP_FRAME_Rax], rax
129 mov [rbp + KTRAP_FRAME_Rcx], rcx
130 mov [rbp + KTRAP_FRAME_Rdx], rdx
131 mov [rbp + KTRAP_FRAME_R8], r8
132 mov [rbp + KTRAP_FRAME_R9], r9
133 mov [rbp + KTRAP_FRAME_R10], r10
134 mov [rbp + KTRAP_FRAME_R11], r11
135 endif
136
137 if (TRAPFLAGS AND TRAPFLAG_XMM)
138 /* Save xmm registers */
139 movdqa [rbp + KTRAP_FRAME_Xmm0], xmm0
140 movdqa [rbp + KTRAP_FRAME_Xmm1], xmm1
141 movdqa [rbp + KTRAP_FRAME_Xmm2], xmm2
142 movdqa [rbp + KTRAP_FRAME_Xmm3], xmm3
143 movdqa [rbp + KTRAP_FRAME_Xmm4], xmm4
144 movdqa [rbp + KTRAP_FRAME_Xmm5], xmm5
145 endif
146
147 if (TRAPFLAGS AND TRAPFLAG_SEGMENTS)
148 /* Save segment selectors */
149 mov ax, ds
150 mov [rbp + KTRAP_FRAME_SegDs], ax
151 mov ax, es
152 mov [rbp + KTRAP_FRAME_SegEs], ax
153 mov ax, fs
154 mov [rbp + KTRAP_FRAME_SegFs], ax
155 mov ax, gs
156 mov [rbp + KTRAP_FRAME_SegGs], ax
157 endif
158
159 /* Save previous mode and swap gs when it was UserMode */
160 mov ax, [rbp + KTRAP_FRAME_SegCs]
161 and al, 1
162 mov [rbp + KTRAP_FRAME_PreviousMode], al
163 jz dont_swap
164 swapgs
165 dont_swap:
166
167 /* Save previous irql */
168 mov rax, cr8
169 mov [rbp + KTRAP_FRAME_PreviousIrql], al
170
171 // KTRAP_FRAME_FaultIndicator
172 // KTRAP_FRAME_ExceptionActive
173 // KTRAP_FRAME_MxCsr
174
175 if (TRAPFLAGS AND TRAPFLAG_DEBUG)
176 /* Save debug registers */
177 mov rax, dr0
178 mov [rbp + KTRAP_FRAME_Dr0], rax
179 mov rax, dr1
180 mov [rbp + KTRAP_FRAME_Dr1], rax
181 mov rax, dr2
182 mov [rbp + KTRAP_FRAME_Dr2], rax
183 mov rax, dr3
184 mov [rbp + KTRAP_FRAME_Dr3], rax
185 mov rax, dr6
186 mov [rbp + KTRAP_FRAME_Dr6], rax
187 mov rax, dr7
188 mov [rbp + KTRAP_FRAME_Dr7], rax
189 endif
190
191 // KTRAP_FRAME_DebugControl
192 // KTRAP_FRAME_LastBranchToRip
193 // KTRAP_FRAME_LastBranchFromRip
194 // KTRAP_FRAME_LastExceptionToRip
195 // KTRAP_FRAME_LastExceptionFromRip
196 // KTRAP_FRAME_TrapFrame
197
198 /* Make sure the direction flag is cleared */
199 cld
200 ENDM
201
202
203 /*
204 * LEAVE_TRAP_FRAME - Restore registers and free stack space
205 */
206 MACRO(LEAVE_TRAP_FRAME)
207 LOCAL dont_swap_back
208 if (TRAPFLAGS AND TRAPFLAG_SEGMENTS)
209 /* Restore segment selectors */
210 mov ax, [rbp + KTRAP_FRAME_SegDs]
211 mov ds, ax
212 mov ax, [rbp + KTRAP_FRAME_SegEs]
213 mov es, ax
214 mov ax, [rbp + KTRAP_FRAME_SegFs]
215 mov fs, ax
216 endif
217
218 test byte ptr [rbp + KTRAP_FRAME_PreviousMode], 1
219 jz dont_swap_back
220 swapgs
221 dont_swap_back:
222
223 if (TRAPFLAGS AND TRAPFLAG_NONVOLATILES)
224 /* Restore non-volatile registers */
225 mov rbx, [rbp + KTRAP_FRAME_Rbx]
226 mov rdi, [rbp + KTRAP_FRAME_Rdi]
227 mov rsi, [rbp + KTRAP_FRAME_Rsi]
228 endif
229
230 if (TRAPFLAGS AND TRAPFLAG_VOLATILES)
231 /* Restore volatile registers */
232 mov rax, [rbp + KTRAP_FRAME_Rax]
233 mov rcx, [rbp + KTRAP_FRAME_Rcx]
234 mov rdx, [rbp + KTRAP_FRAME_Rdx]
235 mov r8, [rbp + KTRAP_FRAME_R8]
236 mov r9, [rbp + KTRAP_FRAME_R9]
237 mov r10, [rbp + KTRAP_FRAME_R10]
238 mov r11, [rbp + KTRAP_FRAME_R11]
239 endif
240
241 if (TRAPFLAGS AND TRAPFLAG_XMM)
242 /* Restore xmm registers */
243 movdqa xmm0, [rbp + KTRAP_FRAME_Xmm0]
244 movdqa xmm1, [rbp + KTRAP_FRAME_Xmm1]
245 movdqa xmm2, [rbp + KTRAP_FRAME_Xmm2]
246 movdqa xmm3, [rbp + KTRAP_FRAME_Xmm3]
247 movdqa xmm4, [rbp + KTRAP_FRAME_Xmm4]
248 movdqa xmm5, [rbp + KTRAP_FRAME_Xmm5]
249 endif
250
251 /* Restore rbp */
252 mov rbp, [rbp + KTRAP_FRAME_Rbp]
253
254 /* Adjust stack pointer */
255 add rsp, KTRAP_FRAME_Rip
256 ENDM
257
258
259 /* FUNCTIONS *****************************************************************/
260
261 .text
262 .code64
263
264 ALIGN 8
265
266 PUBLIC InterruptDispatchTable
267 InterruptDispatchTable:
268 Vector = 0
269 REPEAT 256
270 push Vector
271 jmp KiUnexpectedInterrupt
272 ALIGN 8
273 Vector = Vector+1
274 ENDR
275
276 // rbp = TrapFrame, eax = ExceptionCode, edx = NumParams, r9,r10,r11 = params
277 .PROC InternalDispatchException
278
279 /* Allocate stack space for EXCEPTION_RECORD and KEXCEPTION_FRAME */
280 sub rsp, SIZE_EXCEPTION_RECORD + SIZE_KEXCEPTION_FRAME
281 .allocstack (SIZE_EXCEPTION_RECORD + SIZE_KEXCEPTION_FRAME)
282 .endprolog
283
284 /* Set up EXCEPTION_RECORD */
285 lea rcx, [rsp + SIZE_KEXCEPTION_FRAME]
286 mov [rcx + EXCEPTION_RECORD_ExceptionCode], eax
287 xor rax, rax
288 mov [rcx + EXCEPTION_RECORD_ExceptionFlags], eax
289 mov [rcx + EXCEPTION_RECORD_ExceptionRecord], rax
290 mov rax, [rbp + KTRAP_FRAME_Rip]
291 mov [rcx + EXCEPTION_RECORD_ExceptionAddress], rax
292 mov [rcx + EXCEPTION_RECORD_NumberParameters], edx
293 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(00)], r9
294 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(08)], r10
295 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(10)], r11
296
297 /* Set up KEXCEPTION_FRAME */
298 mov rax, [rbp + KTRAP_FRAME_Rbp]
299 mov [rsp + KEXCEPTION_FRAME_Rbp], rax
300 mov [rsp + KEXCEPTION_FRAME_Rbx], rbx
301 mov [rsp + KEXCEPTION_FRAME_Rdi], rdi
302 mov [rsp + KEXCEPTION_FRAME_Rsi], rsi
303 mov [rsp + KEXCEPTION_FRAME_R12], r12
304 mov [rsp + KEXCEPTION_FRAME_R13], r13
305 mov [rsp + KEXCEPTION_FRAME_R14], r14
306 mov [rsp + KEXCEPTION_FRAME_R15], r15
307 movdqa [rsp + KEXCEPTION_FRAME_Xmm6], xmm6
308 movdqa [rsp + KEXCEPTION_FRAME_Xmm7], xmm7
309 movdqa [rsp + KEXCEPTION_FRAME_Xmm8], xmm8
310 movdqa [rsp + KEXCEPTION_FRAME_Xmm9], xmm9
311 movdqa [rsp + KEXCEPTION_FRAME_Xmm10], xmm10
312 movdqa [rsp + KEXCEPTION_FRAME_Xmm11], xmm11
313 movdqa [rsp + KEXCEPTION_FRAME_Xmm12], xmm12
314 movdqa [rsp + KEXCEPTION_FRAME_Xmm13], xmm13
315 movdqa [rsp + KEXCEPTION_FRAME_Xmm14], xmm14
316 movdqa [rsp + KEXCEPTION_FRAME_Xmm15], xmm15
317 mov qword ptr [rsp + KEXCEPTION_FRAME_Return], 0
318
319 /* Call KiDispatchException */
320 // rcx already points to ExceptionRecord
321 mov rdx, rsp // ExceptionFrame
322 mov r8, rbp // TrapFrame
323 mov r9b, [r8 + KTRAP_FRAME_PreviousMode] // PreviousMode
324 mov byte ptr [rsp + KEXCEPTION_FRAME_P5], 1 // FirstChance
325 call KiDispatchException
326
327 /* Restore registers */
328 mov r12, [rsp + KEXCEPTION_FRAME_R12]
329 mov r13, [rsp + KEXCEPTION_FRAME_R13]
330 mov r14, [rsp + KEXCEPTION_FRAME_R14]
331 mov r15, [rsp + KEXCEPTION_FRAME_R15]
332 movdqa xmm6, [rsp + KEXCEPTION_FRAME_Xmm6]
333 movdqa xmm7, [rsp + KEXCEPTION_FRAME_Xmm7]
334 movdqa xmm8, [rsp + KEXCEPTION_FRAME_Xmm8]
335 movdqa xmm9, [rsp + KEXCEPTION_FRAME_Xmm9]
336 movdqa xmm10, [rsp + KEXCEPTION_FRAME_Xmm10]
337 movdqa xmm11, [rsp + KEXCEPTION_FRAME_Xmm11]
338 movdqa xmm12, [rsp + KEXCEPTION_FRAME_Xmm12]
339 movdqa xmm13, [rsp + KEXCEPTION_FRAME_Xmm13]
340 movdqa xmm14, [rsp + KEXCEPTION_FRAME_Xmm14]
341 movdqa xmm15, [rsp + KEXCEPTION_FRAME_Xmm15]
342
343 add rsp, SIZE_EXCEPTION_RECORD + SIZE_KEXCEPTION_FRAME
344 ret
345 .ENDP InternalDispatchException
346
347
348 /* SOFTWARE INTERRUPT SERVICES ***********************************************/
349
350 PUBLIC KiDivideErrorFault
351 .PROC KiDivideErrorFault
352 /* Push pseudo error code */
353 ENTER_TRAP_FRAME TRAPFLAG_ALL
354
355 /* Enable interrupts */
356 sti
357
358 /* Dispatch the exception */
359 mov eax, STATUS_INTEGER_DIVIDE_BY_ZERO
360 mov edx, 0
361 mov r9, 0
362 mov r10, 0
363 mov r11, 0
364 call InternalDispatchException
365
366 /* Return */
367 LEAVE_TRAP_FRAME
368 iretq
369 .ENDP KiDivideErrorFault
370
371
372 PUBLIC KiDebugTrapOrFault
373 .PROC KiDebugTrapOrFault
374 /* Push pseudo error code */
375 ENTER_TRAP_FRAME TRAPFLAG_ALL
376
377 TRAPINFO KiDebugTrapOrFault
378
379 /* Check if the frame was from kernelmode */
380 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
381 jz KiDebugTrapOrFaultKMode
382
383 /* Enable interrupts for user-mode */
384 sti
385
386 KiDebugTrapOrFaultKMode:
387
388 /* Dispatch the exception */
389 mov eax, STATUS_SINGLE_STEP
390 mov edx, 0
391 mov r9, 0
392 mov r10, 0
393 mov r11, 0
394 call InternalDispatchException
395
396 /* Return */
397 LEAVE_TRAP_FRAME
398 iretq
399 .ENDP KiDebugTrapOrFault
400
401
402 PUBLIC KiNmiInterrupt
403 .PROC KiNmiInterrupt
404 /* Push pseudo error code */
405 ENTER_TRAP_FRAME TRAPFLAG_ALL
406
407 UNIMPLEMENTED KiNmiInterrupt
408
409 jmp $
410
411 /* Return */
412 LEAVE_TRAP_FRAME
413 iretq
414 .ENDP KiNmiInterrupt
415
416
417 PUBLIC KiBreakpointTrap
418 .PROC KiBreakpointTrap
419 /* Push pseudo error code */
420 ENTER_TRAP_FRAME TRAPFLAG_ALL
421
422 TRAPINFO KiBreakpointTrap
423
424 // lea rcx, MsgBreakpointTrap[rip]
425 // mov rdx, rsp
426 // call qword ptr FrLdrDbgPrint[rip]
427
428 /* Dispatch the exception */
429 mov eax, STATUS_BREAKPOINT
430 mov edx, 3
431 mov r9, 0
432 mov r10, 0
433 mov r11, 0
434 call InternalDispatchException
435
436 /* Return */
437 LEAVE_TRAP_FRAME
438 iretq
439 .ENDP KiBreakpointTrap
440
441
442 PUBLIC KiOverflowTrap
443 .PROC KiOverflowTrap
444 /* Push pseudo error code */
445 ENTER_TRAP_FRAME TRAPFLAG_ALL
446
447 /* Enable interrupts */
448 sti
449
450 /* Dispatch the exception */
451 mov eax, STATUS_INTEGER_OVERFLOW
452 mov edx, 3
453 mov r9, 0
454 mov r10, 0
455 mov r11, 0
456 call InternalDispatchException
457
458 /* Return */
459 LEAVE_TRAP_FRAME
460 iretq
461 .ENDP KiOverflowTrap
462
463
464 PUBLIC KiBoundFault
465 .PROC KiBoundFault
466 /* Push pseudo error code */
467 ENTER_TRAP_FRAME TRAPFLAG_ALL
468
469 /* Check if the frame was from kernelmode */
470 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
471 jnz KiBoundFaltUserMode
472
473 /* Bugcheck */
474 mov ecx, EXCEPTION_BOUND_CHECK
475 mov rdx, rbp
476 call KiSystemFatalException
477
478 KiBoundFaltUserMode:
479 /* Enable interrupts for user-mode */
480 sti
481
482 /* Dispatch the exception */
483 mov eax, STATUS_INTEGER_OVERFLOW
484 mov edx, 3
485 mov r9, 0
486 mov r10, 0
487 mov r11, 0
488 call InternalDispatchException
489
490 /* Return */
491 LEAVE_TRAP_FRAME
492 iretq
493 .ENDP KiBoundFault
494
495
496 PUBLIC KiInvalidOpcodeFault
497 .PROC KiInvalidOpcodeFault
498 /* Push pseudo error code */
499 ENTER_TRAP_FRAME TRAPFLAG_ALL
500
501 TRAPINFO KiInvalidOpcodeFault
502
503 mov rdx, [rbp + KTRAP_FRAME_Rip]
504 lea rcx, MsgInvalidOpcodeFault[rip]
505 call qword ptr FrLdrDbgPrint[rip]
506
507 /* Enable interrupts */
508 sti
509
510 /* Check if the frame was from kernelmode */
511 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
512 jz KiInvalidOpcodeKernel
513
514 // FIXME: handle STATUS_INVALID_LOCK_SEQUENCE
515
516 KiInvalidOpcodeKernel:
517 /* Kernel mode fault */
518
519 /* Dispatch the exception */
520 mov eax, STATUS_ILLEGAL_INSTRUCTION
521 mov edx, 3
522 mov r9, 0
523 mov r10, 0
524 mov r11, 0
525 call InternalDispatchException
526
527 /* Return */
528 LEAVE_TRAP_FRAME
529 iretq
530 .ENDP KiInvalidOpcodeFault
531
532
533 PUBLIC KiNpxNotAvailableFault
534 .PROC KiNpxNotAvailableFault
535 /* Push pseudo error code */
536 ENTER_TRAP_FRAME TRAPFLAG_ALL
537
538 /* Call the C handler */
539 mov rcx, rbp
540 call KiNpxNotAvailableFaultHandler
541
542 /* Check the return status code */
543 test eax, eax
544 jz KiNpxNotAvailableFaultExit
545
546 /* Dispatch the exception */
547 mov edx, 3
548 mov r9, 0
549 mov r10, 0
550 mov r11, 0
551 call InternalDispatchException
552
553 KiNpxNotAvailableFaultExit:
554 /* Return */
555 LEAVE_TRAP_FRAME
556 iretq
557 .ENDP KiNpxNotAvailableFault
558
559
560 PUBLIC KiDoubleFaultAbort
561 .PROC KiDoubleFaultAbort
562 /* Push pseudo error code */
563 ENTER_TRAP_FRAME TRAPFLAG_ALL
564
565 lea rcx, MsgDoubleFault[rip]
566 mov rdx, [rbp + KTRAP_FRAME_FaultAddress]
567 mov r8, rbp
568 call qword ptr FrLdrDbgPrint[rip]
569
570 /* Bugcheck */
571 mov ecx, 8 // EXCEPTION_DOUBLE_FAULT
572 mov rdx, rbp
573 call KiSystemFatalException
574
575 jmp $
576 .ENDP KiDoubleFaultAbort
577
578
579 PUBLIC KiNpxSegmentOverrunAbort
580 .PROC KiNpxSegmentOverrunAbort
581 /* Push pseudo error code */
582 ENTER_TRAP_FRAME TRAPFLAG_ALL
583
584 /* Bugcheck */
585 mov ecx, EXCEPTION_NPX_OVERRUN
586 mov rdx, rbp
587 call KiSystemFatalException
588
589 jmp $
590 .ENDP KiNpxSegmentOverrunAbort
591
592
593 PUBLIC KiInvalidTssFault
594 .PROC KiInvalidTssFault
595 /* We have an error code */
596 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
597
598 /* Bugcheck */
599 mov ecx, EXCEPTION_INVALID_TSS
600 mov rdx, rbp
601 call KiSystemFatalException
602
603 jmp $
604 .ENDP KiInvalidTssFault
605
606
607 PUBLIC KiSegmentNotPresentFault
608 .PROC KiSegmentNotPresentFault
609 /* We have an error code */
610 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
611
612 /* Bugcheck */
613 mov ecx, EXCEPTION_SEGMENT_NOT_PRESENT
614 mov rdx, rbp
615 call KiSystemFatalException
616
617 jmp $
618 .ENDP KiSegmentNotPresentFault
619
620
621 PUBLIC KiStackFault
622 .PROC KiStackFault
623 /* We have an error code */
624 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
625
626 /* Bugcheck */
627 mov ecx, EXCEPTION_STACK_FAULT
628 mov rdx, rbp
629 call KiSystemFatalException
630
631 jmp $
632 .ENDP KiStackFault
633
634
635 PUBLIC KiGeneralProtectionFault
636 .PROC KiGeneralProtectionFault
637 /* We have an error code */
638 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
639
640 TRAPINFO KiGeneralProtectionFault
641 mov rdx, [rbp + KTRAP_FRAME_Rip]
642 lea rcx, MsgGeneralProtFault[rip]
643 call qword ptr FrLdrDbgPrint[rip]
644
645 /* Call the C handler */
646 call KiGeneralProtectionFaultHandler
647
648 /* Check for success */
649 test eax, eax
650 jge KiGpfExit
651
652 /* Dispatch the exception */
653 mov edx, 3
654 mov r9, 0
655 mov r10, 0
656 mov r11, 0
657 call InternalDispatchException
658
659 KiGpfFatal:
660
661 /* Bugcheck */
662 mov ecx, UNEXPECTED_KERNEL_MODE_TRAP
663 mov rdx, HEX(000D) // EXCEPTION_GP_FAULT
664 xor r8, r8
665 mov r9, [rbp + KTRAP_FRAME_ErrorCode] // error code
666 sub rsp, 8
667 mov [rsp + KTRAP_FRAME_P5+8], rbp // trap frame
668 call KeBugCheckWithTf
669
670 KiGpfExit:
671 /* Return */
672 LEAVE_TRAP_FRAME
673 iretq
674 .ENDP KiGeneralProtectionFault
675
676
677 PUBLIC KiPageFault
678 .PROC KiPageFault
679 /* We have an error code */
680 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
681
682 TRAPINFO KiPageFault
683
684 #if 0
685 lea rcx, MsgPageFault[rip]
686 mov rdx, [rbp + KTRAP_FRAME_ErrorCode]
687 mov r8, [rbp + KTRAP_FRAME_Rip]
688 mov r9, [rbp + KTRAP_FRAME_FaultAddress]
689 call qword ptr FrLdrDbgPrint[rip]
690 #endif
691
692 /* Save page fault address */
693 mov rdx, cr2
694 mov [rbp + KTRAP_FRAME_FaultAddress], rdx
695
696 /* Call page fault handler */
697 mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction
698 and ecx, 1
699 // rdx == Address
700 mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode
701 and r8b, 1
702 mov r9, rbp // TrapInformation
703 call MmAccessFault
704
705 /* Check for success */
706 test eax, eax
707 jge PageFaultReturn
708
709 /* Set parameter 1 to error code */
710 mov r9d, [rbp + KTRAP_FRAME_ErrorCode]
711
712 /* Set parameter2 to faulting address */
713 mov r10, cr2 // Param2 = faulting address
714
715 cmp eax, STATUS_ACCESS_VIOLATION
716 je AccessViolation
717 cmp eax, STATUS_GUARD_PAGE_VIOLATION
718 je SpecialCode
719 cmp eax, STATUS_STACK_OVERFLOW
720 je SpecialCode
721
722 InPageException:
723 /* Dispatch in-page exception */
724 mov r11d, eax // Param3 = Status
725 mov eax, STATUS_IN_PAGE_ERROR // ExceptionCode
726 mov edx, 3 // ParamCount
727 call InternalDispatchException
728 jmp PageFaultReturn
729
730 AccessViolation:
731 /* Use more proper status code */
732 mov eax, KI_EXCEPTION_ACCESS_VIOLATION
733
734 SpecialCode:
735 /* Setup a normal page fault exception */
736 mov edx, 2 // ParamCount
737 call InternalDispatchException
738
739 PageFaultReturn:
740 LEAVE_TRAP_FRAME
741 iretq
742 .ENDP KiPageFault
743
744
745 PUBLIC KiFloatingErrorFault
746 .PROC KiFloatingErrorFault
747 /* Push pseudo error code */
748 ENTER_TRAP_FRAME TRAPFLAG_ALL
749
750 UNIMPLEMENTED KiFloatingErrorFault
751
752 jmp $
753 .ENDP KiFloatingErrorFault
754
755
756 PUBLIC KiAlignmentFault
757 .PROC KiAlignmentFault
758 /* We have an error code */
759 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
760
761 /* Enable interrupts */
762 sti
763
764 /* Bugcheck */
765 mov ecx, EXCEPTION_ALIGNMENT_CHECK
766 mov rdx, rbp
767 call KiSystemFatalException
768
769 jmp $
770 .ENDP KiAlignmentFault
771
772
773 PUBLIC KiMcheckAbort
774 .PROC KiMcheckAbort
775 /* Push pseudo error code */
776 ENTER_TRAP_FRAME TRAPFLAG_ALL
777
778 /* Bugcheck */
779 mov ecx, HEX(12)
780 mov rdx, rbp
781 call KiSystemFatalException
782
783 jmp $
784 .ENDP KiMcheckAbort
785
786
787 PUBLIC KiXmmException
788 .PROC KiXmmException
789 /* Push pseudo error code */
790 ENTER_TRAP_FRAME TRAPFLAG_ALL
791
792 /* Call the C handler */
793 mov rcx, rbp
794 call KiXmmExceptionHandler
795
796 /* Check for success */
797 test eax, eax
798 jge KiXmmExit
799
800 /* Dispatch the exception */
801 mov edx, 3
802 mov r9, 0
803 mov r10, 0
804 mov r11, 0
805 call InternalDispatchException
806
807 KiXmmExit:
808 LEAVE_TRAP_FRAME
809 iretq
810 .ENDP KiXmmException
811
812
813 PUBLIC KiApcInterrupt
814 .PROC KiApcInterrupt
815 /* We have an error code */
816 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
817
818 UNIMPLEMENTED KiApcInterrupt
819
820 jmp $
821 .ENDP KiApcInterrupt
822
823
824 PUBLIC KiRaiseAssertion
825 .PROC KiRaiseAssertion
826 /* We have an error code */
827 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
828
829 /* Decrement RIP to point to the INT2C instruction (2 bytes, not 1 like INT3) */
830 sub qword ptr [rbp + KTRAP_FRAME_Rip], 2
831
832 /* Dispatch the exception */
833 mov eax, STATUS_ASSERTION_FAILURE
834 mov edx, 0
835 mov r9, 0
836 mov r10, 0
837 mov r11, 0
838 call InternalDispatchException
839
840 LEAVE_TRAP_FRAME
841 iretq
842 .ENDP KiRaiseAssertion
843
844
845 PUBLIC KiDebugServiceTrap
846 .PROC KiDebugServiceTrap
847 /* Push pseudo error code */
848 ENTER_TRAP_FRAME TRAPFLAG_ALL
849
850 TRAPINFO KiDebugServiceTrap
851
852 /* Increase Rip to skip the int3 */
853 inc qword ptr [rbp + KTRAP_FRAME_Rip]
854
855 /* Dispatch the exception */
856 mov eax, STATUS_BREAKPOINT
857 mov edx, 3
858 mov r9, [rbp+KTRAP_FRAME_Rax] // Service
859 mov r10, [rbp+KTRAP_FRAME_Rcx] // Buffer
860 mov r11, [rbp+KTRAP_FRAME_Rdx] // Length
861 call InternalDispatchException
862
863 LEAVE_TRAP_FRAME;
864 iretq
865 .ENDP KiDebugServiceTrap
866
867
868 PUBLIC KiDpcInterrupt
869 .PROC KiDpcInterrupt
870 /* We have an error code */
871 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
872
873 UNIMPLEMENTED KiDpcInterrupt
874
875 jmp $
876 .ENDP KiDpcInterrupt
877
878
879 PUBLIC KiIpiInterrupt
880 .PROC KiIpiInterrupt
881 /* We have an error code */
882 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
883
884 UNIMPLEMENTED KiIpiInterrupt
885
886 jmp $
887 .ENDP KiIpiInterrupt
888
889
890 PUBLIC KiUnexpectedInterrupt
891 .PROC KiUnexpectedInterrupt
892 /* The error code is the vector */
893 cli
894 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
895
896 /* Set bugcheck parameters */
897 mov ecx, TRAP_CAUSE_UNKNOWN
898 mov rdx, [rbp + KTRAP_FRAME_ErrorCode] // the vector
899 mov r8, 0 // The unknown floating-point exception
900 mov r9, 0 // The enabled and asserted status bits
901 sub rsp, 8
902 mov [rbp + KTRAP_FRAME_P5 + 8], rbp // trap frame
903 call KeBugCheckWithTf
904
905 jmp $
906 .ENDP KiUnexpectedInterrupt
907
908 #ifdef _MSC_VER
909
910 //void __lgdt(void *Source);
911 PUBLIC __lgdt
912 __lgdt:
913 lgdt fword ptr [rcx]
914 ret
915
916 //void __sgdt(void *Destination);
917 PUBLIC __sgdt
918 __sgdt:
919 sgdt fword ptr [rcx]
920 ret
921
922 // void __lldt(unsigned short Value)
923 PUBLIC __lldt
924 __lldt:
925 lldt cx
926 ret
927
928 //void __sldt(void *Destination);
929 PUBLIC __sldt
930 __sldt:
931 sldt word ptr [rcx]
932 ret
933
934 //void __ltr(unsigned short Source);
935 PUBLIC __ltr
936 __ltr:
937 ltr cx
938 ret
939
940 //void __str(unsigned short *Destination);
941 PUBLIC __str
942 __str:
943 str word ptr [rcx]
944 ret
945
946 #endif
947
948 END