[NTOSKRNL]
[reactos.git] / reactos / 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 <asm.inc>
11
12 #include <ksamd64.inc>
13
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
23 /* GLOBALS *******************************************************************/
24
25 .data
26
27 PUBLIC MsgUnimplemented
28 MsgUnimplemented:
29 .asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
30
31 MsgPageFault:
32 .asciz "Page fault! Code = 0x%x, RIP = %p, FaultingAddress = %p\n"
33
34 MsgGeneralProtFault:
35 .asciz "General protection fault at %p!\n"
36
37 MsgBreakpointTrap:
38 .asciz "BreakpointTrap at %p\n"
39
40 MsgUnexpectedInterrupt:
41 .asciz "UnexpectedInterrupt Vector=0x%02lx\n"
42
43 MsgInvalidOpcodeFault:
44 .asciz "Invalid opcode fault at %p!\n"
45
46 MsgDoubleFault:
47 .asciz "Double fault at %p, rbp=%p!\n"
48
49 MsgTrapInfo:
50 .asciz "Trap: %s at %p\n"
51
52 MACRO(TRAPINFO, func)
53 LOCAL label1, label2
54 #if 0
55 jmp label2
56 label1: .asciz "\func"
57 label2:
58 sub rsp, 32
59 lea rcx, MsgTrapInfo[rip]
60 lea rdx, 1b[rip]
61 mov r8, [rbp + KTRAP_FRAME_Rip]
62 call qword ptr FrLdrDbgPrint[rip]
63 add rsp, 32
64 #endif
65 ENDM
66
67 /* Helper Macros *************************************************************/
68
69 #define TRAPFLAG_VOLATILES HEX(01)
70 #define TRAPFLAG_NONVOLATILES HEX(02)
71 #define TRAPFLAG_XMM HEX(04)
72 #define TRAPFLAG_SEGMENTS HEX(08)
73 #define TRAPFLAG_DEBUG HEX(10)
74 #define TRAPFLAG_HAS_ERRORCODE HEX(100)
75
76 #define TRAPFLAG_SYSTEMSERVICE (TRAPFLAG_VOLATILES|TRAPFLAG_DEBUG)
77 #define TRAPFLAG_ALL HEX(ff)
78
79 /*
80 * Stack Layout:
81 * |-------------------|
82 * | KTRAP_FRAME |
83 * |-------------------| <- rbp
84 * | EXCEPTION_RECORD |
85 * |-------------------|
86 * | KEXCEPTION_FRAME |
87 * |-------------------| <- rsp
88 *
89 */
90
91 /*
92 * ENTER_TRAP_FRAME - Allocate KTRAP_FRAME_LENGTH and save registers to it
93 */
94 MACRO(ENTER_TRAP_FRAME, Flags)
95 LOCAL dont_swap
96
97 /* Save the trap flags for this trap */
98 TRAPFLAGS = VAL(Flags)
99
100 /* Size of hardware trap frame */
101 if (TRAPFLAGS AND TRAPFLAG_HAS_ERRORCODE)
102 .pushframe code
103 SIZE_INITIAL_FRAME = 6 * 8
104 else
105 .pushframe
106 SIZE_INITIAL_FRAME = 5 * 8
107 endif
108
109 /* Make room for a KTRAP_FRAME */
110 sub rsp, (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME)
111 .allocstack (KTRAP_FRAME_LENGTH - SIZE_INITIAL_FRAME)
112 .endprolog
113
114 /* Save rbp */
115 mov [rsp + KTRAP_FRAME_Rbp], rbp
116
117 /* Point rbp to the KTRAP_FRAME */
118 lea rbp, [rsp]
119
120 if (TRAPFLAGS AND TRAPFLAG_NONVOLATILES)
121 /* Save non-volatile registers */
122 mov [rbp + KTRAP_FRAME_Rbx], rbx
123 mov [rbp + KTRAP_FRAME_Rdi], rdi
124 mov [rbp + KTRAP_FRAME_Rsi], rsi
125 endif
126
127 if (TRAPFLAGS AND TRAPFLAG_VOLATILES)
128 /* Save volatile registers */
129 mov [rbp + KTRAP_FRAME_Rax], rax
130 mov [rbp + KTRAP_FRAME_Rcx], rcx
131 mov [rbp + KTRAP_FRAME_Rdx], rdx
132 mov [rbp + KTRAP_FRAME_R8], r8
133 mov [rbp + KTRAP_FRAME_R9], r9
134 mov [rbp + KTRAP_FRAME_R10], r10
135 mov [rbp + KTRAP_FRAME_R11], r11
136 endif
137
138 if (TRAPFLAGS AND TRAPFLAG_XMM)
139 /* Save xmm registers */
140 movdqa [rbp + KTRAP_FRAME_Xmm0], xmm0
141 movdqa [rbp + KTRAP_FRAME_Xmm1], xmm1
142 movdqa [rbp + KTRAP_FRAME_Xmm2], xmm2
143 movdqa [rbp + KTRAP_FRAME_Xmm3], xmm3
144 movdqa [rbp + KTRAP_FRAME_Xmm4], xmm4
145 movdqa [rbp + KTRAP_FRAME_Xmm5], xmm5
146 endif
147
148 if (TRAPFLAGS AND TRAPFLAG_SEGMENTS)
149 /* Save segment selectors */
150 mov ax, ds
151 mov [rbp + KTRAP_FRAME_SegDs], ax
152 mov ax, es
153 mov [rbp + KTRAP_FRAME_SegEs], ax
154 mov ax, fs
155 mov [rbp + KTRAP_FRAME_SegFs], ax
156 mov ax, gs
157 mov [rbp + KTRAP_FRAME_SegGs], ax
158 endif
159
160 /* Save previous mode and swap gs when it was UserMode */
161 mov ax, [rbp + KTRAP_FRAME_SegCs]
162 and al, 1
163 mov [rbp + KTRAP_FRAME_PreviousMode], al
164 jz dont_swap
165 swapgs
166 dont_swap:
167
168 /* Save previous irql */
169 mov rax, cr8
170 mov [rbp + KTRAP_FRAME_PreviousIrql], al
171
172 // KTRAP_FRAME_FaultIndicator
173 // KTRAP_FRAME_ExceptionActive
174 // KTRAP_FRAME_MxCsr
175
176 if (TRAPFLAGS AND TRAPFLAG_DEBUG)
177 /* Save debug registers */
178 mov rax, dr0
179 mov [rbp + KTRAP_FRAME_Dr0], rax
180 mov rax, dr1
181 mov [rbp + KTRAP_FRAME_Dr1], rax
182 mov rax, dr2
183 mov [rbp + KTRAP_FRAME_Dr2], rax
184 mov rax, dr3
185 mov [rbp + KTRAP_FRAME_Dr3], rax
186 mov rax, dr6
187 mov [rbp + KTRAP_FRAME_Dr6], rax
188 mov rax, dr7
189 mov [rbp + KTRAP_FRAME_Dr7], rax
190 endif
191
192 // KTRAP_FRAME_DebugControl
193 // KTRAP_FRAME_LastBranchToRip
194 // KTRAP_FRAME_LastBranchFromRip
195 // KTRAP_FRAME_LastExceptionToRip
196 // KTRAP_FRAME_LastExceptionFromRip
197 // KTRAP_FRAME_TrapFrame
198
199 /* Make sure the direction flag is cleared */
200 cld
201 ENDM
202
203
204 /*
205 * LEAVE_TRAP_FRAME - Restore registers and free stack space
206 */
207 MACRO(LEAVE_TRAP_FRAME)
208 LOCAL dont_swap_back
209 if (TRAPFLAGS AND TRAPFLAG_SEGMENTS)
210 /* Restore segment selectors */
211 mov ax, [rbp + KTRAP_FRAME_SegDs]
212 mov ds, ax
213 mov ax, [rbp + KTRAP_FRAME_SegEs]
214 mov es, ax
215 mov ax, [rbp + KTRAP_FRAME_SegFs]
216 mov fs, ax
217 endif
218
219 test byte ptr [rbp + KTRAP_FRAME_PreviousMode], 1
220 jz dont_swap_back
221 swapgs
222 dont_swap_back:
223
224 if (TRAPFLAGS AND TRAPFLAG_NONVOLATILES)
225 /* Restore non-volatile registers */
226 mov rbx, [rbp + KTRAP_FRAME_Rbx]
227 mov rdi, [rbp + KTRAP_FRAME_Rdi]
228 mov rsi, [rbp + KTRAP_FRAME_Rsi]
229 endif
230
231 if (TRAPFLAGS AND TRAPFLAG_VOLATILES)
232 /* Restore volatile registers */
233 mov rax, [rbp + KTRAP_FRAME_Rax]
234 mov rcx, [rbp + KTRAP_FRAME_Rcx]
235 mov rdx, [rbp + KTRAP_FRAME_Rdx]
236 mov r8, [rbp + KTRAP_FRAME_R8]
237 mov r9, [rbp + KTRAP_FRAME_R9]
238 mov r10, [rbp + KTRAP_FRAME_R10]
239 mov r11, [rbp + KTRAP_FRAME_R11]
240 endif
241
242 if (TRAPFLAGS AND TRAPFLAG_XMM)
243 /* Restore xmm registers */
244 movdqa xmm0, [rbp + KTRAP_FRAME_Xmm0]
245 movdqa xmm1, [rbp + KTRAP_FRAME_Xmm1]
246 movdqa xmm2, [rbp + KTRAP_FRAME_Xmm2]
247 movdqa xmm3, [rbp + KTRAP_FRAME_Xmm3]
248 movdqa xmm4, [rbp + KTRAP_FRAME_Xmm4]
249 movdqa xmm5, [rbp + KTRAP_FRAME_Xmm5]
250 endif
251
252 /* Restore rbp */
253 mov rbp, [rbp + KTRAP_FRAME_Rbp]
254
255 /* Adjust stack pointer */
256 add rsp, KTRAP_FRAME_Rip
257 ENDM
258
259
260 /* FUNCTIONS *****************************************************************/
261
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, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
281 .allocstack (EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH)
282 .endprolog
283
284 /* Set up EXCEPTION_RECORD */
285 lea rcx, [rsp + KEXCEPTION_FRAME_LENGTH]
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, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
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 #undef lgdt
910 #undef lidt
911
912 //void __lgdt(void *Source);
913 PUBLIC __lgdt
914 __lgdt:
915 lgdt fword ptr [rcx]
916 ret
917
918 //void __sgdt(void *Destination);
919 PUBLIC __sgdt
920 __sgdt:
921 sgdt fword ptr [rcx]
922 ret
923
924 // void __lldt(unsigned short Value)
925 PUBLIC __lldt
926 __lldt:
927 lldt cx
928 ret
929
930 //void __sldt(void *Destination);
931 PUBLIC __sldt
932 __sldt:
933 sldt word ptr [rcx]
934 ret
935
936 //void __ltr(unsigned short Source);
937 PUBLIC __ltr
938 __ltr:
939 ltr cx
940 ret
941
942 //void __str(unsigned short *Destination);
943 PUBLIC __str
944 __str:
945 str word ptr [rcx]
946 ret
947
948 #endif
949
950 END