Import my Hybrid-CD stuff from last year.
[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 .text
263 .code64
264
265 ALIGN 8
266
267 PUBLIC InterruptDispatchTable
268 InterruptDispatchTable:
269 Vector = 0
270 REPEAT 256
271 push Vector
272 jmp KiUnexpectedInterrupt
273 ALIGN 8
274 Vector = Vector+1
275 ENDR
276
277 // rbp = TrapFrame, eax = ExceptionCode, edx = NumParams, r9,r10,r11 = params
278 .PROC InternalDispatchException
279
280 /* Allocate stack space for EXCEPTION_RECORD and KEXCEPTION_FRAME */
281 sub rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
282 .allocstack (EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH)
283 .endprolog
284
285 /* Set up EXCEPTION_RECORD */
286 lea rcx, [rsp + KEXCEPTION_FRAME_LENGTH]
287 mov [rcx + EXCEPTION_RECORD_ExceptionCode], eax
288 xor rax, rax
289 mov [rcx + EXCEPTION_RECORD_ExceptionFlags], eax
290 mov [rcx + EXCEPTION_RECORD_ExceptionRecord], rax
291 mov rax, [rbp + KTRAP_FRAME_Rip]
292 mov [rcx + EXCEPTION_RECORD_ExceptionAddress], rax
293 mov [rcx + EXCEPTION_RECORD_NumberParameters], edx
294 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(00)], r9
295 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(08)], r10
296 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(10)], r11
297
298 /* Set up KEXCEPTION_FRAME */
299 mov rax, [rbp + KTRAP_FRAME_Rbp]
300 mov [rsp + KEXCEPTION_FRAME_Rbp], rax
301 mov [rsp + KEXCEPTION_FRAME_Rbx], rbx
302 mov [rsp + KEXCEPTION_FRAME_Rdi], rdi
303 mov [rsp + KEXCEPTION_FRAME_Rsi], rsi
304 mov [rsp + KEXCEPTION_FRAME_R12], r12
305 mov [rsp + KEXCEPTION_FRAME_R13], r13
306 mov [rsp + KEXCEPTION_FRAME_R14], r14
307 mov [rsp + KEXCEPTION_FRAME_R15], r15
308 movdqa [rsp + KEXCEPTION_FRAME_Xmm6], xmm6
309 movdqa [rsp + KEXCEPTION_FRAME_Xmm7], xmm7
310 movdqa [rsp + KEXCEPTION_FRAME_Xmm8], xmm8
311 movdqa [rsp + KEXCEPTION_FRAME_Xmm9], xmm9
312 movdqa [rsp + KEXCEPTION_FRAME_Xmm10], xmm10
313 movdqa [rsp + KEXCEPTION_FRAME_Xmm11], xmm11
314 movdqa [rsp + KEXCEPTION_FRAME_Xmm12], xmm12
315 movdqa [rsp + KEXCEPTION_FRAME_Xmm13], xmm13
316 movdqa [rsp + KEXCEPTION_FRAME_Xmm14], xmm14
317 movdqa [rsp + KEXCEPTION_FRAME_Xmm15], xmm15
318 mov qword ptr [rsp + KEXCEPTION_FRAME_Return], 0
319
320 /* Call KiDispatchException */
321 // rcx already points to ExceptionRecord
322 mov rdx, rsp // ExceptionFrame
323 mov r8, rbp // TrapFrame
324 mov r9b, [r8 + KTRAP_FRAME_PreviousMode] // PreviousMode
325 mov byte ptr [rsp + KEXCEPTION_FRAME_P5], 1 // FirstChance
326 call KiDispatchException
327
328 /* Restore registers */
329 mov r12, [rsp + KEXCEPTION_FRAME_R12]
330 mov r13, [rsp + KEXCEPTION_FRAME_R13]
331 mov r14, [rsp + KEXCEPTION_FRAME_R14]
332 mov r15, [rsp + KEXCEPTION_FRAME_R15]
333 movdqa xmm6, [rsp + KEXCEPTION_FRAME_Xmm6]
334 movdqa xmm7, [rsp + KEXCEPTION_FRAME_Xmm7]
335 movdqa xmm8, [rsp + KEXCEPTION_FRAME_Xmm8]
336 movdqa xmm9, [rsp + KEXCEPTION_FRAME_Xmm9]
337 movdqa xmm10, [rsp + KEXCEPTION_FRAME_Xmm10]
338 movdqa xmm11, [rsp + KEXCEPTION_FRAME_Xmm11]
339 movdqa xmm12, [rsp + KEXCEPTION_FRAME_Xmm12]
340 movdqa xmm13, [rsp + KEXCEPTION_FRAME_Xmm13]
341 movdqa xmm14, [rsp + KEXCEPTION_FRAME_Xmm14]
342 movdqa xmm15, [rsp + KEXCEPTION_FRAME_Xmm15]
343
344 add rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
345 ret
346 .ENDP InternalDispatchException
347
348
349 /* SOFTWARE INTERRUPT SERVICES ***********************************************/
350
351 PUBLIC KiDivideErrorFault
352 .PROC KiDivideErrorFault
353 /* Push pseudo error code */
354 ENTER_TRAP_FRAME TRAPFLAG_ALL
355
356 /* Enable interrupts */
357 sti
358
359 /* Dispatch the exception */
360 mov eax, STATUS_INTEGER_DIVIDE_BY_ZERO
361 mov edx, 0
362 mov r9, 0
363 mov r10, 0
364 mov r11, 0
365 call InternalDispatchException
366
367 /* Return */
368 LEAVE_TRAP_FRAME
369 iretq
370 .ENDP KiDivideErrorFault
371
372
373 PUBLIC KiDebugTrapOrFault
374 .PROC KiDebugTrapOrFault
375 /* Push pseudo error code */
376 ENTER_TRAP_FRAME TRAPFLAG_ALL
377
378 TRAPINFO KiDebugTrapOrFault
379
380 /* Check if the frame was from kernelmode */
381 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
382 jz KiDebugTrapOrFaultKMode
383
384 /* Enable interrupts for user-mode */
385 sti
386
387 KiDebugTrapOrFaultKMode:
388
389 /* Dispatch the exception */
390 mov eax, STATUS_SINGLE_STEP
391 mov edx, 0
392 mov r9, 0
393 mov r10, 0
394 mov r11, 0
395 call InternalDispatchException
396
397 /* Return */
398 LEAVE_TRAP_FRAME
399 iretq
400 .ENDP KiDebugTrapOrFault
401
402
403 PUBLIC KiNmiInterrupt
404 .PROC KiNmiInterrupt
405 /* Push pseudo error code */
406 ENTER_TRAP_FRAME TRAPFLAG_ALL
407
408 UNIMPLEMENTED KiNmiInterrupt
409
410 jmp $
411
412 /* Return */
413 LEAVE_TRAP_FRAME
414 iretq
415 .ENDP KiNmiInterrupt
416
417
418 PUBLIC KiBreakpointTrap
419 .PROC KiBreakpointTrap
420 /* Push pseudo error code */
421 ENTER_TRAP_FRAME TRAPFLAG_ALL
422
423 TRAPINFO KiBreakpointTrap
424
425 // lea rcx, MsgBreakpointTrap[rip]
426 // mov rdx, rsp
427 // call qword ptr FrLdrDbgPrint[rip]
428
429 /* Dispatch the exception */
430 mov eax, STATUS_BREAKPOINT
431 mov edx, 3
432 mov r9, 0
433 mov r10, 0
434 mov r11, 0
435 call InternalDispatchException
436
437 /* Return */
438 LEAVE_TRAP_FRAME
439 iretq
440 .ENDP KiBreakpointTrap
441
442
443 PUBLIC KiOverflowTrap
444 .PROC KiOverflowTrap
445 /* Push pseudo error code */
446 ENTER_TRAP_FRAME TRAPFLAG_ALL
447
448 /* Enable interrupts */
449 sti
450
451 /* Dispatch the exception */
452 mov eax, STATUS_INTEGER_OVERFLOW
453 mov edx, 3
454 mov r9, 0
455 mov r10, 0
456 mov r11, 0
457 call InternalDispatchException
458
459 /* Return */
460 LEAVE_TRAP_FRAME
461 iretq
462 .ENDP KiOverflowTrap
463
464
465 PUBLIC KiBoundFault
466 .PROC KiBoundFault
467 /* Push pseudo error code */
468 ENTER_TRAP_FRAME TRAPFLAG_ALL
469
470 /* Check if the frame was from kernelmode */
471 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
472 jnz KiBoundFaltUserMode
473
474 /* Bugcheck */
475 mov ecx, EXCEPTION_BOUND_CHECK
476 mov rdx, rbp
477 call KiSystemFatalException
478
479 KiBoundFaltUserMode:
480 /* Enable interrupts for user-mode */
481 sti
482
483 /* Dispatch the exception */
484 mov eax, STATUS_INTEGER_OVERFLOW
485 mov edx, 3
486 mov r9, 0
487 mov r10, 0
488 mov r11, 0
489 call InternalDispatchException
490
491 /* Return */
492 LEAVE_TRAP_FRAME
493 iretq
494 .ENDP KiBoundFault
495
496
497 PUBLIC KiInvalidOpcodeFault
498 .PROC KiInvalidOpcodeFault
499 /* Push pseudo error code */
500 ENTER_TRAP_FRAME TRAPFLAG_ALL
501
502 TRAPINFO KiInvalidOpcodeFault
503
504 mov rdx, [rbp + KTRAP_FRAME_Rip]
505 lea rcx, MsgInvalidOpcodeFault[rip]
506 call qword ptr FrLdrDbgPrint[rip]
507
508 /* Enable interrupts */
509 sti
510
511 /* Check if the frame was from kernelmode */
512 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
513 jz KiInvalidOpcodeKernel
514
515 // FIXME: handle STATUS_INVALID_LOCK_SEQUENCE
516
517 KiInvalidOpcodeKernel:
518 /* Kernel mode fault */
519
520 /* Dispatch the exception */
521 mov eax, STATUS_ILLEGAL_INSTRUCTION
522 mov edx, 3
523 mov r9, 0
524 mov r10, 0
525 mov r11, 0
526 call InternalDispatchException
527
528 /* Return */
529 LEAVE_TRAP_FRAME
530 iretq
531 .ENDP KiInvalidOpcodeFault
532
533
534 PUBLIC KiNpxNotAvailableFault
535 .PROC KiNpxNotAvailableFault
536 /* Push pseudo error code */
537 ENTER_TRAP_FRAME TRAPFLAG_ALL
538
539 /* Call the C handler */
540 mov rcx, rbp
541 call KiNpxNotAvailableFaultHandler
542
543 /* Check the return status code */
544 test eax, eax
545 jz KiNpxNotAvailableFaultExit
546
547 /* Dispatch the exception */
548 mov edx, 3
549 mov r9, 0
550 mov r10, 0
551 mov r11, 0
552 call InternalDispatchException
553
554 KiNpxNotAvailableFaultExit:
555 /* Return */
556 LEAVE_TRAP_FRAME
557 iretq
558 .ENDP KiNpxNotAvailableFault
559
560
561 PUBLIC KiDoubleFaultAbort
562 .PROC KiDoubleFaultAbort
563 /* Push pseudo error code */
564 ENTER_TRAP_FRAME TRAPFLAG_ALL
565
566 lea rcx, MsgDoubleFault[rip]
567 mov rdx, [rbp + KTRAP_FRAME_FaultAddress]
568 mov r8, rbp
569 call qword ptr FrLdrDbgPrint[rip]
570
571 /* Bugcheck */
572 mov ecx, 8 // EXCEPTION_DOUBLE_FAULT
573 mov rdx, rbp
574 call KiSystemFatalException
575
576 jmp $
577 .ENDP KiDoubleFaultAbort
578
579
580 PUBLIC KiNpxSegmentOverrunAbort
581 .PROC KiNpxSegmentOverrunAbort
582 /* Push pseudo error code */
583 ENTER_TRAP_FRAME TRAPFLAG_ALL
584
585 /* Bugcheck */
586 mov ecx, EXCEPTION_NPX_OVERRUN
587 mov rdx, rbp
588 call KiSystemFatalException
589
590 jmp $
591 .ENDP KiNpxSegmentOverrunAbort
592
593
594 PUBLIC KiInvalidTssFault
595 .PROC KiInvalidTssFault
596 /* We have an error code */
597 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
598
599 /* Bugcheck */
600 mov ecx, EXCEPTION_INVALID_TSS
601 mov rdx, rbp
602 call KiSystemFatalException
603
604 jmp $
605 .ENDP KiInvalidTssFault
606
607
608 PUBLIC KiSegmentNotPresentFault
609 .PROC KiSegmentNotPresentFault
610 /* We have an error code */
611 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
612
613 /* Bugcheck */
614 mov ecx, EXCEPTION_SEGMENT_NOT_PRESENT
615 mov rdx, rbp
616 call KiSystemFatalException
617
618 jmp $
619 .ENDP KiSegmentNotPresentFault
620
621
622 PUBLIC KiStackFault
623 .PROC KiStackFault
624 /* We have an error code */
625 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
626
627 /* Bugcheck */
628 mov ecx, EXCEPTION_STACK_FAULT
629 mov rdx, rbp
630 call KiSystemFatalException
631
632 jmp $
633 .ENDP KiStackFault
634
635
636 PUBLIC KiGeneralProtectionFault
637 .PROC KiGeneralProtectionFault
638 /* We have an error code */
639 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
640
641 TRAPINFO KiGeneralProtectionFault
642 mov rdx, [rbp + KTRAP_FRAME_Rip]
643 lea rcx, MsgGeneralProtFault[rip]
644 call qword ptr FrLdrDbgPrint[rip]
645
646 /* Call the C handler */
647 call KiGeneralProtectionFaultHandler
648
649 /* Check for success */
650 test eax, eax
651 jge KiGpfExit
652
653 /* Dispatch the exception */
654 mov edx, 3
655 mov r9, 0
656 mov r10, 0
657 mov r11, 0
658 call InternalDispatchException
659
660 KiGpfFatal:
661
662 /* Bugcheck */
663 mov ecx, UNEXPECTED_KERNEL_MODE_TRAP
664 mov rdx, HEX(000D) // EXCEPTION_GP_FAULT
665 xor r8, r8
666 mov r9, [rbp + KTRAP_FRAME_ErrorCode] // error code
667 sub rsp, 8
668 mov [rsp + KTRAP_FRAME_P5+8], rbp // trap frame
669 call KeBugCheckWithTf
670
671 KiGpfExit:
672 /* Return */
673 LEAVE_TRAP_FRAME
674 iretq
675 .ENDP KiGeneralProtectionFault
676
677
678 PUBLIC KiPageFault
679 .PROC KiPageFault
680 /* We have an error code */
681 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
682
683 TRAPINFO KiPageFault
684
685 #if 0
686 lea rcx, MsgPageFault[rip]
687 mov rdx, [rbp + KTRAP_FRAME_ErrorCode]
688 mov r8, [rbp + KTRAP_FRAME_Rip]
689 mov r9, [rbp + KTRAP_FRAME_FaultAddress]
690 call qword ptr FrLdrDbgPrint[rip]
691 #endif
692
693 /* Save page fault address */
694 mov rdx, cr2
695 mov [rbp + KTRAP_FRAME_FaultAddress], rdx
696
697 /* Call page fault handler */
698 mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction
699 and ecx, 1
700 // rdx == Address
701 mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode
702 and r8b, 1
703 mov r9, rbp // TrapInformation
704 call MmAccessFault
705
706 /* Check for success */
707 test eax, eax
708 jge PageFaultReturn
709
710 /* Set parameter 1 to error code */
711 mov r9d, [rbp + KTRAP_FRAME_ErrorCode]
712
713 /* Set parameter2 to faulting address */
714 mov r10, cr2 // Param2 = faulting address
715
716 cmp eax, STATUS_ACCESS_VIOLATION
717 je AccessViolation
718 cmp eax, STATUS_GUARD_PAGE_VIOLATION
719 je SpecialCode
720 cmp eax, STATUS_STACK_OVERFLOW
721 je SpecialCode
722
723 InPageException:
724 /* Dispatch in-page exception */
725 mov r11d, eax // Param3 = Status
726 mov eax, STATUS_IN_PAGE_ERROR // ExceptionCode
727 mov edx, 3 // ParamCount
728 call InternalDispatchException
729 jmp PageFaultReturn
730
731 AccessViolation:
732 /* Use more proper status code */
733 mov eax, KI_EXCEPTION_ACCESS_VIOLATION
734
735 SpecialCode:
736 /* Setup a normal page fault exception */
737 mov edx, 2 // ParamCount
738 call InternalDispatchException
739
740 PageFaultReturn:
741 LEAVE_TRAP_FRAME
742 iretq
743 .ENDP KiPageFault
744
745
746 PUBLIC KiFloatingErrorFault
747 .PROC KiFloatingErrorFault
748 /* Push pseudo error code */
749 ENTER_TRAP_FRAME TRAPFLAG_ALL
750
751 UNIMPLEMENTED KiFloatingErrorFault
752
753 jmp $
754 .ENDP KiFloatingErrorFault
755
756
757 PUBLIC KiAlignmentFault
758 .PROC KiAlignmentFault
759 /* We have an error code */
760 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
761
762 /* Enable interrupts */
763 sti
764
765 /* Bugcheck */
766 mov ecx, EXCEPTION_ALIGNMENT_CHECK
767 mov rdx, rbp
768 call KiSystemFatalException
769
770 jmp $
771 .ENDP KiAlignmentFault
772
773
774 PUBLIC KiMcheckAbort
775 .PROC KiMcheckAbort
776 /* Push pseudo error code */
777 ENTER_TRAP_FRAME TRAPFLAG_ALL
778
779 /* Bugcheck */
780 mov ecx, HEX(12)
781 mov rdx, rbp
782 call KiSystemFatalException
783
784 jmp $
785 .ENDP KiMcheckAbort
786
787
788 PUBLIC KiXmmException
789 .PROC KiXmmException
790 /* Push pseudo error code */
791 ENTER_TRAP_FRAME TRAPFLAG_ALL
792
793 /* Call the C handler */
794 mov rcx, rbp
795 call KiXmmExceptionHandler
796
797 /* Check for success */
798 test eax, eax
799 jge KiXmmExit
800
801 /* Dispatch the exception */
802 mov edx, 3
803 mov r9, 0
804 mov r10, 0
805 mov r11, 0
806 call InternalDispatchException
807
808 KiXmmExit:
809 LEAVE_TRAP_FRAME
810 iretq
811 .ENDP KiXmmException
812
813
814 PUBLIC KiApcInterrupt
815 .PROC KiApcInterrupt
816 /* We have an error code */
817 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
818
819 UNIMPLEMENTED KiApcInterrupt
820
821 jmp $
822 .ENDP KiApcInterrupt
823
824
825 PUBLIC KiRaiseAssertion
826 .PROC KiRaiseAssertion
827 /* We have an error code */
828 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
829
830 /* Decrement RIP to point to the INT2C instruction (2 bytes, not 1 like INT3) */
831 sub qword ptr [rbp + KTRAP_FRAME_Rip], 2
832
833 /* Dispatch the exception */
834 mov eax, STATUS_ASSERTION_FAILURE
835 mov edx, 0
836 mov r9, 0
837 mov r10, 0
838 mov r11, 0
839 call InternalDispatchException
840
841 LEAVE_TRAP_FRAME
842 iretq
843 .ENDP KiRaiseAssertion
844
845
846 PUBLIC KiDebugServiceTrap
847 .PROC KiDebugServiceTrap
848 /* Push pseudo error code */
849 ENTER_TRAP_FRAME TRAPFLAG_ALL
850
851 TRAPINFO KiDebugServiceTrap
852
853 /* Increase Rip to skip the int3 */
854 inc qword ptr [rbp + KTRAP_FRAME_Rip]
855
856 /* Dispatch the exception */
857 mov eax, STATUS_BREAKPOINT
858 mov edx, 3
859 mov r9, [rbp+KTRAP_FRAME_Rax] // Service
860 mov r10, [rbp+KTRAP_FRAME_Rcx] // Buffer
861 mov r11, [rbp+KTRAP_FRAME_Rdx] // Length
862 call InternalDispatchException
863
864 LEAVE_TRAP_FRAME;
865 iretq
866 .ENDP KiDebugServiceTrap
867
868
869 PUBLIC KiDpcInterrupt
870 .PROC KiDpcInterrupt
871 /* We have an error code */
872 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
873
874 UNIMPLEMENTED KiDpcInterrupt
875
876 jmp $
877 .ENDP KiDpcInterrupt
878
879
880 PUBLIC KiIpiInterrupt
881 .PROC KiIpiInterrupt
882 /* We have an error code */
883 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
884
885 UNIMPLEMENTED KiIpiInterrupt
886
887 jmp $
888 .ENDP KiIpiInterrupt
889
890
891 PUBLIC KiUnexpectedInterrupt
892 .PROC KiUnexpectedInterrupt
893 /* The error code is the vector */
894 cli
895 ENTER_TRAP_FRAME (TRAPFLAG_HAS_ERRORCODE OR TRAPFLAG_ALL)
896
897 /* Set bugcheck parameters */
898 mov ecx, TRAP_CAUSE_UNKNOWN
899 mov rdx, [rbp + KTRAP_FRAME_ErrorCode] // the vector
900 mov r8, 0 // The unknown floating-point exception
901 mov r9, 0 // The enabled and asserted status bits
902 sub rsp, 8
903 mov [rbp + KTRAP_FRAME_P5 + 8], rbp // trap frame
904 call KeBugCheckWithTf
905
906 jmp $
907 .ENDP KiUnexpectedInterrupt
908
909 #ifdef _MSC_VER
910
911 //void __lgdt(void *Source);
912 PUBLIC __lgdt
913 __lgdt:
914 lgdt fword ptr [rcx]
915 ret
916
917 //void __sgdt(void *Destination);
918 PUBLIC __sgdt
919 __sgdt:
920 sgdt fword ptr [rcx]
921 ret
922
923 // void __lldt(unsigned short Value)
924 PUBLIC __lldt
925 __lldt:
926 lldt cx
927 ret
928
929 //void __sldt(void *Destination);
930 PUBLIC __sldt
931 __sldt:
932 sldt word ptr [rcx]
933 ret
934
935 //void __ltr(unsigned short Source);
936 PUBLIC __ltr
937 __ltr:
938 ltr cx
939 ret
940
941 //void __str(unsigned short *Destination);
942 PUBLIC __str
943 __str:
944 str word ptr [rcx]
945 ret
946
947 #endif
948
949 END