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 KiDpcInterruptHandler:PROC
25 /* GLOBALS *******************************************************************/
29 PUBLIC MsgUnimplemented
31 .asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
34 .asciz "Page fault! Code = 0x%x, RIP = %p, FaultingAddress = %p\n"
37 .asciz "General protection fault at %p!\n"
40 .asciz "BreakpointTrap at %p\n"
42 MsgUnexpectedInterrupt:
43 .asciz "UnexpectedInterrupt Vector=0x%02lx\n"
45 MsgInvalidOpcodeFault:
46 .asciz "Invalid opcode fault at %p!\n"
49 .asciz "Double fault at %p, rbp=%p!\n"
52 .asciz "Trap: %s at %p\n"
58 label1: .asciz "\func"
68 lea rcx, MsgTrapInfo[rip]
70 mov r8, [rbp + KTRAP_FRAME_Rip]
71 call qword ptr FrLdrDbgPrint[rip]
83 /* Helper Macros *************************************************************/
85 MACRO(DispatchException, Status, Number, P1, P2, P3)
91 call InternalDispatchException
94 MACRO(Fatal, BugcheckCode)
98 call KiSystemFatalException
102 /* FUNCTIONS *****************************************************************/
108 MACRO(UnexpectedVectorStub, Vector)
109 /* This nop is to make the relative jmp address 4 bytes aligned and to
110 make the whole code 8 bytes long */
112 /* This is a push instruction with 8bit operand. Since the instruction
113 sign extends the value to 32 bits, we need to offset it */
114 PUBLIC KxUnexpectedInterrupt&Vector
115 KxUnexpectedInterrupt&Vector:
117 jmp KiUnexpectedInterrupt
120 PUBLIC KiUnexpectedRange
124 UnexpectedVectorStub %Vector
127 PUBLIC KiUnexpectedRangeEnd
128 KiUnexpectedRangeEnd:
130 PUBLIC KiInterruptDispatchTemplate
131 KiInterruptDispatchTemplate:
132 /* This instruction pushes the return address on the stack, which is the
133 address of the interrupt object's DispatchCode member, then jumps
134 to the address stored in the interrupt object's DispatchAddress member */
135 call qword ptr KiInterruptDispatchTemplate[rip - KINTERRUPT_DispatchCode + KINTERRUPT_DispatchAddress]
138 // rbp = TrapFrame, eax = ExceptionCode, edx = NumParams, r9,r10,r11 = params
139 FUNC InternalDispatchException
141 /* Allocate stack space for EXCEPTION_RECORD and KEXCEPTION_FRAME */
142 sub rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
143 .allocstack (EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH)
146 /* Set up EXCEPTION_RECORD */
147 lea rcx, [rsp + KEXCEPTION_FRAME_LENGTH]
148 mov [rcx + EXCEPTION_RECORD_ExceptionCode], eax
150 mov [rcx + EXCEPTION_RECORD_ExceptionFlags], eax
151 mov [rcx + EXCEPTION_RECORD_ExceptionRecord], rax
152 mov rax, [rbp + KTRAP_FRAME_Rip]
153 mov [rcx + EXCEPTION_RECORD_ExceptionAddress], rax
154 mov [rcx + EXCEPTION_RECORD_NumberParameters], edx
155 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(00)], r9
156 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(08)], r10
157 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(10)], r11
159 /* Set up KEXCEPTION_FRAME */
160 mov rax, [rbp + KTRAP_FRAME_Rbp]
161 mov [rsp + KEXCEPTION_FRAME_Rbp], rax
162 mov [rsp + KEXCEPTION_FRAME_Rbx], rbx
163 mov [rsp + KEXCEPTION_FRAME_Rdi], rdi
164 mov [rsp + KEXCEPTION_FRAME_Rsi], rsi
165 mov [rsp + KEXCEPTION_FRAME_R12], r12
166 mov [rsp + KEXCEPTION_FRAME_R13], r13
167 mov [rsp + KEXCEPTION_FRAME_R14], r14
168 mov [rsp + KEXCEPTION_FRAME_R15], r15
169 movdqa [rsp + KEXCEPTION_FRAME_Xmm6], xmm6
170 movdqa [rsp + KEXCEPTION_FRAME_Xmm7], xmm7
171 movdqa [rsp + KEXCEPTION_FRAME_Xmm8], xmm8
172 movdqa [rsp + KEXCEPTION_FRAME_Xmm9], xmm9
173 movdqa [rsp + KEXCEPTION_FRAME_Xmm10], xmm10
174 movdqa [rsp + KEXCEPTION_FRAME_Xmm11], xmm11
175 movdqa [rsp + KEXCEPTION_FRAME_Xmm12], xmm12
176 movdqa [rsp + KEXCEPTION_FRAME_Xmm13], xmm13
177 movdqa [rsp + KEXCEPTION_FRAME_Xmm14], xmm14
178 movdqa [rsp + KEXCEPTION_FRAME_Xmm15], xmm15
179 mov qword ptr [rsp + KEXCEPTION_FRAME_Return], 0
181 /* Call KiDispatchException */
182 // rcx already points to ExceptionRecord
183 mov rdx, rsp // ExceptionFrame
184 mov r8, rbp // TrapFrame
185 mov r9b, [r8 + KTRAP_FRAME_PreviousMode] // PreviousMode
186 mov byte ptr [rsp + KEXCEPTION_FRAME_P5], 1 // FirstChance
187 call KiDispatchException
189 /* Restore registers */
190 mov r12, [rsp + KEXCEPTION_FRAME_R12]
191 mov r13, [rsp + KEXCEPTION_FRAME_R13]
192 mov r14, [rsp + KEXCEPTION_FRAME_R14]
193 mov r15, [rsp + KEXCEPTION_FRAME_R15]
194 movdqa xmm6, [rsp + KEXCEPTION_FRAME_Xmm6]
195 movdqa xmm7, [rsp + KEXCEPTION_FRAME_Xmm7]
196 movdqa xmm8, [rsp + KEXCEPTION_FRAME_Xmm8]
197 movdqa xmm9, [rsp + KEXCEPTION_FRAME_Xmm9]
198 movdqa xmm10, [rsp + KEXCEPTION_FRAME_Xmm10]
199 movdqa xmm11, [rsp + KEXCEPTION_FRAME_Xmm11]
200 movdqa xmm12, [rsp + KEXCEPTION_FRAME_Xmm12]
201 movdqa xmm13, [rsp + KEXCEPTION_FRAME_Xmm13]
202 movdqa xmm14, [rsp + KEXCEPTION_FRAME_Xmm14]
203 movdqa xmm15, [rsp + KEXCEPTION_FRAME_Xmm15]
205 add rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
207 ENDFUNC InternalDispatchException
210 /* CPU EXCEPTION HANDLERS ****************************************************/
212 PUBLIC KiDivideErrorFault
213 FUNC KiDivideErrorFault
214 /* Push pseudo error code */
215 EnterTrap TF_SAVE_ALL
217 /* Enable interrupts */
220 /* Dispatch the exception */
221 DispatchException STATUS_INTEGER_DIVIDE_BY_ZERO, 0, 0, 0, 0
225 ENDFUNC KiDivideErrorFault
228 PUBLIC KiDebugTrapOrFault
229 FUNC KiDebugTrapOrFault
230 /* Push pseudo error code */
231 EnterTrap TF_SAVE_ALL
233 TRAPINFO KiDebugTrapOrFault
235 /* Check if the frame was from kernelmode */
236 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
237 jz KiDebugTrapOrFaultKMode
239 /* Enable interrupts for user-mode */
242 KiDebugTrapOrFaultKMode:
243 /* Dispatch the exception */
244 DispatchException STATUS_SINGLE_STEP, 0, 0, 0, 0
248 ENDFUNC KiDebugTrapOrFault
251 PUBLIC KiNmiInterrupt
253 /* Push pseudo error code */
254 EnterTrap TF_SAVE_ALL
256 UNIMPLEMENTED KiNmiInterrupt
261 ENDFUNC KiNmiInterrupt
264 PUBLIC KiBreakpointTrap
265 FUNC KiBreakpointTrap
266 /* Push pseudo error code */
267 EnterTrap TF_SAVE_ALL
269 /* Check if the frame was from kernelmode */
270 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
271 jz KiBreakpointTrapKMode
273 /* Enable interrupts for user-mode */
276 KiBreakpointTrapKMode:
277 /* Dispatch the exception */
278 DispatchException STATUS_BREAKPOINT, 3, BREAKPOINT_BREAK, 0, 0
282 ENDFUNC KiBreakpointTrap
285 PUBLIC KiOverflowTrap
287 /* Push pseudo error code */
288 EnterTrap TF_SAVE_ALL
290 /* Enable interrupts */
293 /* Dispatch the exception */
294 DispatchException STATUS_INTEGER_OVERFLOW, 3, 0, 0, 0
298 ENDFUNC KiOverflowTrap
304 EnterTrap TF_SAVE_ALL
306 /* Check if the frame was from kernelmode */
307 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
308 jnz KiBoundFaultUserMode
311 Fatal EXCEPTION_BOUND_CHECK
313 KiBoundFaultUserMode:
314 /* Enable interrupts for user-mode */
317 /* Dispatch the exception */
318 DispatchException STATUS_ARRAY_BOUNDS_EXCEEDED, 0, 0, 0, 0
325 PUBLIC KiInvalidOpcodeFault
326 FUNC KiInvalidOpcodeFault
328 EnterTrap TF_SAVE_ALL
330 TRAPINFO KiInvalidOpcodeFault
332 mov rdx, [rbp + KTRAP_FRAME_Rip]
333 lea rcx, MsgInvalidOpcodeFault[rip]
334 call qword ptr FrLdrDbgPrint[rip]
336 /* Enable interrupts */
339 /* Check if the frame was from kernelmode */
340 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
341 jz KiInvalidOpcodeKernel
343 // FIXME: handle STATUS_INVALID_LOCK_SEQUENCE
345 KiInvalidOpcodeKernel:
346 /* Kernel mode fault */
348 /* Dispatch the exception */
349 DispatchException STATUS_ILLEGAL_INSTRUCTION, 3, 0, 0, 0
353 ENDFUNC KiInvalidOpcodeFault
356 PUBLIC KiNpxNotAvailableFault
357 FUNC KiNpxNotAvailableFault
359 EnterTrap TF_SAVE_ALL
361 /* Call the C handler */
363 call KiNpxNotAvailableFaultHandler
365 /* Check the return status code */
367 jz KiNpxNotAvailableFaultExit
369 /* Dispatch the exception */
370 DispatchException eax, 3, 0, 0, 0
372 KiNpxNotAvailableFaultExit:
375 ENDFUNC KiNpxNotAvailableFault
378 PUBLIC KiDoubleFaultAbort
379 FUNC KiDoubleFaultAbort
381 EnterTrap TF_SAVE_ALL
383 lea rcx, MsgDoubleFault[rip]
384 mov rdx, [rbp + KTRAP_FRAME_FaultAddress]
386 call qword ptr FrLdrDbgPrint[rip]
389 Fatal 8 // EXCEPTION_DOUBLE_FAULT
391 ENDFUNC KiDoubleFaultAbort
394 PUBLIC KiNpxSegmentOverrunAbort
395 FUNC KiNpxSegmentOverrunAbort
397 EnterTrap TF_SAVE_ALL
400 Fatal EXCEPTION_NPX_OVERRUN
403 ENDFUNC KiNpxSegmentOverrunAbort
406 PUBLIC KiInvalidTssFault
407 FUNC KiInvalidTssFault
408 /* We have an error code */
409 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
412 Fatal EXCEPTION_INVALID_TSS
414 ENDFUNC KiInvalidTssFault
417 PUBLIC KiSegmentNotPresentFault
418 FUNC KiSegmentNotPresentFault
419 /* We have an error code */
420 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
423 Fatal EXCEPTION_SEGMENT_NOT_PRESENT
425 ENDFUNC KiSegmentNotPresentFault
430 /* We have an error code */
431 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
434 Fatal EXCEPTION_STACK_FAULT
439 PUBLIC KiGeneralProtectionFault
440 FUNC KiGeneralProtectionFault
441 /* We have an error code */
442 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
444 //TRAPINFO KiGeneralProtectionFault
445 //mov rdx, [rbp + KTRAP_FRAME_Rip]
446 //lea rcx, MsgGeneralProtFault[rip]
447 //call qword ptr FrLdrDbgPrint[rip]
449 /* Call the C handler */
451 call KiGeneralProtectionFaultHandler
453 /* Check for success */
457 /* Dispatch the exception */
458 DispatchException eax, 3, 0, 0, 0
463 mov ecx, UNEXPECTED_KERNEL_MODE_TRAP
464 mov rdx, HEX(000D) // EXCEPTION_GP_FAULT
466 mov r9, [rbp + KTRAP_FRAME_ErrorCode] // error code
468 mov [rsp + KTRAP_FRAME_P5+8], rbp // trap frame
469 call KeBugCheckWithTf
475 ENDFUNC KiGeneralProtectionFault
480 /* We have an error code */
481 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
486 lea rcx, MsgPageFault[rip]
487 mov rdx, [rbp + KTRAP_FRAME_ErrorCode]
488 mov r8, [rbp + KTRAP_FRAME_Rip]
489 mov r9, [rbp + KTRAP_FRAME_FaultAddress]
490 call qword ptr FrLdrDbgPrint[rip]
493 /* Save page fault address */
495 mov [rbp + KTRAP_FRAME_FaultAddress], rdx
497 /* Enable interrupts for the page fault handler */
500 /* Call page fault handler */
501 mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction
504 mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode
506 mov r9, rbp // TrapInformation
509 /* Check for success */
513 /* Disable interrupts again for the debugger */
516 /* Set parameter 1 to error code */
517 mov r9d, [rbp + KTRAP_FRAME_ErrorCode]
519 /* Set parameter2 to faulting address */
520 mov r10, cr2 // Param2 = faulting address
522 cmp eax, STATUS_ACCESS_VIOLATION
524 cmp eax, STATUS_GUARD_PAGE_VIOLATION
526 cmp eax, STATUS_STACK_OVERFLOW
531 /* Dispatch in-page exception */
532 mov r11d, eax // Param3 = Status
533 mov eax, STATUS_IN_PAGE_ERROR // ExceptionCode
534 mov edx, 3 // ParamCount
535 call InternalDispatchException
539 /* Use more proper status code */
540 mov eax, KI_EXCEPTION_ACCESS_VIOLATION
543 /* Setup a normal page fault exception */
544 mov edx, 2 // ParamCount
545 call InternalDispatchException
549 ExitTrap (TF_SAVE_ALL or TF_CHECKUSERAPC)
553 PUBLIC KiFloatingErrorFault
554 FUNC KiFloatingErrorFault
556 EnterTrap TF_SAVE_ALL
558 UNIMPLEMENTED KiFloatingErrorFault
563 ENDFUNC KiFloatingErrorFault
566 PUBLIC KiAlignmentFault
567 FUNC KiAlignmentFault
568 /* We have an error code */
569 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
572 Fatal EXCEPTION_ALIGNMENT_CHECK
574 ENDFUNC KiAlignmentFault
580 EnterTrap TF_SAVE_ALL
585 ENDFUNC KiMcheckAbort
588 PUBLIC KiXmmException
591 EnterTrap TF_SAVE_ALL
593 /* Call the C handler */
595 call KiXmmExceptionHandler
597 /* Check for success */
601 /* Dispatch the exception */
602 DispatchException eax, 3, 0, 0, 0
607 ENDFUNC KiXmmException
610 /* SOFTWARE INTERRUPT SERVICES ***********************************************/
612 PUBLIC KiRaiseAssertion
613 FUNC KiRaiseAssertion
614 /* We have an error code */
615 EnterTrap (TF_SAVE_ALL)
617 /* Decrement RIP to point to the INT2C instruction (2 bytes, not 1 like INT3) */
618 sub qword ptr [rbp + KTRAP_FRAME_Rip], 2
620 /* Dispatch the exception */
621 DispatchException STATUS_ASSERTION_FAILURE, 0, 0, 0, 0
625 ENDFUNC KiRaiseAssertion
628 PUBLIC KiDebugServiceTrap
629 FUNC KiDebugServiceTrap
631 EnterTrap TF_SAVE_ALL
633 TRAPINFO KiDebugServiceTrap
635 /* Increase Rip to skip the int3 */
636 inc qword ptr [rbp + KTRAP_FRAME_Rip]
638 /* Dispatch the exception (Params = service, buffer, legth) */
639 DispatchException STATUS_BREAKPOINT, 3, [rbp+KTRAP_FRAME_Rax], [rbp+KTRAP_FRAME_Rcx], [rbp+KTRAP_FRAME_Rdx]
643 ENDFUNC KiDebugServiceTrap
646 PUBLIC KiApcInterrupt
649 EnterTrap (TF_VOLATILES or TF_IRQL)
651 /* Raise to APC_LEVEL */
655 /* End the interrupt */
656 mov dword ptr [APIC_EOI], 0
658 /* Enable interrupts */
661 /* Call the worker routine */
662 mov cl, [rbp + KTRAP_FRAME_SegCs] // ProcessorMode
664 mov rdx, 0 // ExceptionFrame
665 mov r8, rdx // TrapFrame
668 /* Disable interrupts */
671 /* Lower IRQL back to PASSIVE */
672 mov rax, PASSIVE_LEVEL
676 ExitTrap (TF_VOLATILES or TF_IRQL)
679 EXTERN KiRetireDpcList:PROC
680 PUBLIC KiRetireDpcListInDpcStack
681 .PROC KiRetireDpcListInDpcStack
688 /* Switch stack and call the function */
693 /* Restore stack, cleanup and return */
699 PUBLIC KiDpcInterrupt
702 EnterTrap (TF_VOLATILES or TF_IRQL)
704 /* Call the worker routine */
705 call KiDpcInterruptHandler
707 /* Return, but don't send an EOI! */
708 ExitTrap (TF_VOLATILES or TF_IRQL)
712 PUBLIC KiIpiInterrupt
715 EnterTrap (TF_VOLATILES or TF_IRQL)
717 /* Raise to IPI_LEVEL */
721 /* End the interrupt */
722 mov dword ptr [APIC_EOI], 0
727 ExitTrap (TF_VOLATILES or TF_IRQL)
731 PUBLIC KiUnexpectedInterrupt
732 FUNC KiUnexpectedInterrupt
733 /* The error code is the vector */
734 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
737 /* Set bugcheck parameters */
738 mov ecx, TRAP_CAUSE_UNKNOWN
739 mov rdx, [rbp + KTRAP_FRAME_ErrorCode] // the vector
740 mov r8, 0 // The unknown floating-point exception
741 mov r9, 0 // The enabled and asserted status bits
743 mov [rbp + KTRAP_FRAME_P5 + 8], rbp // trap frame
744 call KeBugCheckWithTf
749 ENDFUNC KiUnexpectedInterrupt
751 PUBLIC KiInterruptDispatch
752 FUNC KiInterruptDispatch
753 /* The error code is a pointer to the interrupt object's code */
754 EnterTrap (TF_HAS_ERROR_CODE or TF_SAVE_ALL or TF_IRQL)
756 /* Increase interrupt count */
757 inc dword ptr gs:[PcInterruptCount];
759 /* Load the address of the interrupt object into rcx */
760 mov rcx, [rbp + KTRAP_FRAME_ErrorCode]
762 /* Substract offset of the DispatchCode member plus 6 for the call instruction */
763 sub rcx, KINTERRUPT_DispatchCode + 6
765 /* Raise IRQL to SynchronizeIrql */
766 movzx rax, byte ptr [rcx + KINTERRUPT_SynchronizeIrql]
770 /* Acquire interrupt lock */
771 mov r8, [rcx + KINTERRUPT_ActualLock]
773 //KxAcquireSpinLock(Interrupt->ActualLock);
777 mov rdx, [rcx + KINTERRUPT_ServiceContext]
778 call qword ptr [rcx + KINTERRUPT_ServiceRoutine]
781 /* Release interrupt lock */
782 //KxReleaseSpinLock(Interrupt->ActualLock);
785 /* Go back to old irql */
786 movzx rax, byte ptr [rbp + KTRAP_FRAME_PreviousIrql]
790 ExitTrap (TF_SAVE_ALL or TF_SEND_EOI)
794 #define MAX_SYSCALL_PARAM_SIZE (16 * 8)
795 #define HOME_SIZE 6*8
796 #define SYSCALL_ALLOCATION (MAX_SYSCALL_PARAM_SIZE + HOME_SIZE)
798 EXTERN KiSystemCallHandler:PROC
800 /*! \name KiSystemCallEntry64
802 * \brief This is the entrypoint for syscalls from 64bit user mode
804 * \param rax - The system call number
805 * \param rcx - User mode return address, set by the syscall instruction
806 * \param rdx,r8,r9 - Parameters 2-4 to the service function
807 * \param r10 - Parameter 1 to the service function
808 * \param r11 - RFLAGS saved by the syscall instruction
810 PUBLIC KiSystemCallEntry64
811 .PROC KiSystemCallEntry64
813 /* Old stack pointer is in rcx, lie and say we saved it in rbp */
817 /* Swap gs to kernel, so we can access the PCR */
820 /* Save the user mode rsp in the PCR */
821 mov gs:[PcUserRsp], rsp
823 /* Get the kernel stack from the PCR */
824 mov rsp, gs:[PcRspBase]
826 /* Allocate a TRAP_FRAME and space for parameters */
827 sub rsp, (KTRAP_FRAME_LENGTH + MAX_SYSCALL_PARAM_SIZE + HOME_SIZE)
829 /* Save rbp and load it with the old stack pointer */
830 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + HOME_SIZE + KTRAP_FRAME_Rbp], rbp
831 mov rbp, gs:[PcUserRsp]
834 /* Save important volatiles in the trap frame */
835 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rax], rax
836 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rcx], rcx
837 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R10], r10
838 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R11], r11
840 /* Set sane segments */
841 mov ax, (KGDT64_R3_DATA or RPL_MASK)
845 /* Call the C-handler (will enable interrupts) */
846 lea rcx, [rsp + SYSCALL_ALLOCATION]
847 call KiSystemCallHandler
849 /* Deallocate the handlers home stack frame */
852 /* The return value is the address of the Nt-function */
861 mov rbp, [rsp + SYSCALL_ALLOCATION + KTRAP_FRAME_Rbp]
864 /* Disable interrupts for return */
867 /* Restore old trap frame */
868 mov rcx, gs:[PcCurrentThread]
869 mov rdx, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_TrapFrame]
870 mov [rcx + KTHREAD_TrapFrame], rdx
872 /* Prepare user mode return address (rcx) and eflags (r11) for sysret */
873 mov rcx, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rcx]
874 mov r11, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R11]
876 /* Load user mode stack (It was copied to the trap frame) */
877 mov rsp, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rsp]
879 /* Swap gs back to user */
882 /* return to user mode */
883 .byte HEX(48) // REX prefix to return to long mode
888 PUBLIC KiSystemCallEntry32
894 PUBLIC KiZwSystemService
895 FUNC KiZwSystemService
898 sub rsp, KTRAP_FRAME_LENGTH
899 .allocstack KTRAP_FRAME_LENGTH
900 mov [rsp + KTRAP_FRAME_Rsi], rsi
901 .savereg rsi, KTRAP_FRAME_Rsi
902 mov [rsp + KTRAP_FRAME_Rdi], rdi
903 .savereg rdi, KTRAP_FRAME_Rdi
908 /* Get current thread */
909 mov r11, gs:[PcCurrentThread]
911 /* Save the old trap frame in TrapFrame.Rdx */
912 mov rdi, [r11 + KTHREAD_TrapFrame]
913 mov [rbp + KTRAP_FRAME_Rdx], rdi
915 /* Set the new trap frame and previous mode */
916 mov [r11 + ThTrapFrame], rbp
917 mov byte ptr [r11 + KTHREAD_PreviousMode], 0
919 /* allocate space for parameters */
921 and rsp, HEX(0fffffffffffffff0)
924 mov [rbp + KTRAP_FRAME_Rcx], rcx
926 /* copy parameters to the new location */
927 lea rsi, [rbp + KTRAP_FRAME_LENGTH + 16]
934 mov rcx, [rbp + KTRAP_FRAME_Rcx]
936 /* Call the service function */
939 /* Restore the old trap frame */
940 mov r11, gs:[PcCurrentThread]
941 mov rsi, [rsp + KTRAP_FRAME_Rdx]
942 mov [r11 + KTHREAD_TrapFrame], rsi
944 /* Restore rdi and rsi */
945 mov rsi, [rbp + KTRAP_FRAME_Rsi]
946 mov rdi, [rbp + KTRAP_FRAME_Rdi]
948 /* Cleanup the stack and return */
949 lea rsp, [rbp + KTRAP_FRAME_LENGTH]
962 * KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status));
966 mov [rcx + KTRAP_FRAME_Rax], rdx
971 //ExitTrap TF_SAVE_ALL
976 * KiServiceExit2(IN PKTRAP_FRAME TrapFrame);
978 PUBLIC KiServiceExit2
989 PUBLIC KiInitializeSegments
990 KiInitializeSegments:
991 mov ax, KGDT64_R3_DATA or RPL_MASK
1002 //void __lgdt(void *Source);
1005 lgdt fword ptr [rcx]
1008 //void __sgdt(void *Destination);
1011 sgdt fword ptr [rcx]
1014 // void __lldt(unsigned short Value)
1020 //void __sldt(void *Destination);
1026 //void __ltr(unsigned short Source);
1032 //void __str(unsigned short *Destination);