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
26 EXTERN KdSetOwedBreakpoints:PROC
30 /* GLOBALS *******************************************************************/
34 PUBLIC MsgUnimplemented
36 .asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
39 .asciz "Page fault! Code = 0x%x, RIP = %p, FaultingAddress = %p\n"
42 .asciz "General protection fault at %p!\n"
45 .asciz "BreakpointTrap at %p\n"
47 MsgUnexpectedInterrupt:
48 .asciz "UnexpectedInterrupt Vector=0x%02lx\n"
50 MsgInvalidOpcodeFault:
51 .asciz "Invalid opcode fault at %p!\n"
54 .asciz "Double fault at %p, rbp=%p!\n"
57 .asciz "Trap: %s at %p\n"
63 label1: .asciz "\func"
73 lea rcx, MsgTrapInfo[rip]
75 mov r8, [rbp + KTRAP_FRAME_Rip]
76 call qword ptr FrLdrDbgPrint[rip]
88 /* Helper Macros *************************************************************/
90 MACRO(DispatchException, Status, Number, P1, P2, P3)
96 call InternalDispatchException
99 MACRO(Fatal, BugcheckCode)
101 mov ecx, BugcheckCode
103 call KiSystemFatalException
107 /* FUNCTIONS *****************************************************************/
113 MACRO(UnexpectedVectorStub, Vector)
114 /* This nop is to make the relative jmp address 4 bytes aligned and to
115 make the whole code 8 bytes long */
117 /* This is a push instruction with 8bit operand. Since the instruction
118 sign extends the value to 32 bits, we need to offset it */
119 PUBLIC KxUnexpectedInterrupt&Vector
120 KxUnexpectedInterrupt&Vector:
122 jmp KiUnexpectedInterrupt
125 PUBLIC KiUnexpectedRange
129 UnexpectedVectorStub %Vector
132 PUBLIC KiUnexpectedRangeEnd
133 KiUnexpectedRangeEnd:
135 PUBLIC KiInterruptDispatchTemplate
136 KiInterruptDispatchTemplate:
137 /* This instruction pushes the return address on the stack, which is the
138 address of the interrupt object's DispatchCode member, then jumps
139 to the address stored in the interrupt object's DispatchAddress member */
140 call qword ptr KiInterruptDispatchTemplate[rip - KINTERRUPT_DispatchCode + KINTERRUPT_DispatchAddress]
143 // rbp = TrapFrame, eax = ExceptionCode, edx = NumParams, r9,r10,r11 = params
144 FUNC InternalDispatchException
146 /* Allocate stack space for EXCEPTION_RECORD and KEXCEPTION_FRAME */
147 sub rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
148 .allocstack (EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH)
151 /* Set up EXCEPTION_RECORD */
152 lea rcx, [rsp + KEXCEPTION_FRAME_LENGTH]
153 mov [rcx + EXCEPTION_RECORD_ExceptionCode], eax
155 mov [rcx + EXCEPTION_RECORD_ExceptionFlags], eax
156 mov [rcx + EXCEPTION_RECORD_ExceptionRecord], rax
157 mov rax, [rbp + KTRAP_FRAME_Rip]
158 mov [rcx + EXCEPTION_RECORD_ExceptionAddress], rax
159 mov [rcx + EXCEPTION_RECORD_NumberParameters], edx
160 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(00)], r9
161 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(08)], r10
162 mov [rcx + EXCEPTION_RECORD_ExceptionInformation + HEX(10)], r11
164 /* Set up KEXCEPTION_FRAME */
165 mov rax, [rbp + KTRAP_FRAME_Rbp]
166 mov [rsp + KEXCEPTION_FRAME_Rbp], rax
167 mov [rsp + KEXCEPTION_FRAME_Rbx], rbx
168 mov [rsp + KEXCEPTION_FRAME_Rdi], rdi
169 mov [rsp + KEXCEPTION_FRAME_Rsi], rsi
170 mov [rsp + KEXCEPTION_FRAME_R12], r12
171 mov [rsp + KEXCEPTION_FRAME_R13], r13
172 mov [rsp + KEXCEPTION_FRAME_R14], r14
173 mov [rsp + KEXCEPTION_FRAME_R15], r15
174 movdqa [rsp + KEXCEPTION_FRAME_Xmm6], xmm6
175 movdqa [rsp + KEXCEPTION_FRAME_Xmm7], xmm7
176 movdqa [rsp + KEXCEPTION_FRAME_Xmm8], xmm8
177 movdqa [rsp + KEXCEPTION_FRAME_Xmm9], xmm9
178 movdqa [rsp + KEXCEPTION_FRAME_Xmm10], xmm10
179 movdqa [rsp + KEXCEPTION_FRAME_Xmm11], xmm11
180 movdqa [rsp + KEXCEPTION_FRAME_Xmm12], xmm12
181 movdqa [rsp + KEXCEPTION_FRAME_Xmm13], xmm13
182 movdqa [rsp + KEXCEPTION_FRAME_Xmm14], xmm14
183 movdqa [rsp + KEXCEPTION_FRAME_Xmm15], xmm15
184 mov qword ptr [rsp + KEXCEPTION_FRAME_Return], 0
186 /* Call KiDispatchException */
187 // rcx already points to ExceptionRecord
188 mov rdx, rsp // ExceptionFrame
189 mov r8, rbp // TrapFrame
190 mov r9b, [r8 + KTRAP_FRAME_PreviousMode] // PreviousMode
191 mov byte ptr [rsp + KEXCEPTION_FRAME_P5], 1 // FirstChance
192 call KiDispatchException
194 /* Restore registers */
195 mov r12, [rsp + KEXCEPTION_FRAME_R12]
196 mov r13, [rsp + KEXCEPTION_FRAME_R13]
197 mov r14, [rsp + KEXCEPTION_FRAME_R14]
198 mov r15, [rsp + KEXCEPTION_FRAME_R15]
199 movdqa xmm6, [rsp + KEXCEPTION_FRAME_Xmm6]
200 movdqa xmm7, [rsp + KEXCEPTION_FRAME_Xmm7]
201 movdqa xmm8, [rsp + KEXCEPTION_FRAME_Xmm8]
202 movdqa xmm9, [rsp + KEXCEPTION_FRAME_Xmm9]
203 movdqa xmm10, [rsp + KEXCEPTION_FRAME_Xmm10]
204 movdqa xmm11, [rsp + KEXCEPTION_FRAME_Xmm11]
205 movdqa xmm12, [rsp + KEXCEPTION_FRAME_Xmm12]
206 movdqa xmm13, [rsp + KEXCEPTION_FRAME_Xmm13]
207 movdqa xmm14, [rsp + KEXCEPTION_FRAME_Xmm14]
208 movdqa xmm15, [rsp + KEXCEPTION_FRAME_Xmm15]
210 add rsp, EXCEPTION_RECORD_LENGTH + KEXCEPTION_FRAME_LENGTH
215 /* CPU EXCEPTION HANDLERS ****************************************************/
217 PUBLIC KiDivideErrorFault
218 FUNC KiDivideErrorFault
219 /* Push pseudo error code */
220 EnterTrap TF_SAVE_ALL
222 /* Enable interrupts */
225 /* Dispatch the exception */
226 DispatchException STATUS_INTEGER_DIVIDE_BY_ZERO, 0, 0, 0, 0
233 PUBLIC KiDebugTrapOrFault
234 FUNC KiDebugTrapOrFault
235 /* Push pseudo error code */
236 EnterTrap TF_SAVE_ALL
238 TRAPINFO KiDebugTrapOrFault
240 /* Check if the frame was from kernelmode */
241 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
242 jz KiDebugTrapOrFaultKMode
244 /* Enable interrupts for user-mode */
247 KiDebugTrapOrFaultKMode:
248 /* Dispatch the exception */
249 DispatchException STATUS_SINGLE_STEP, 0, 0, 0, 0
256 PUBLIC KiNmiInterrupt
258 /* Push pseudo error code */
259 EnterTrap TF_SAVE_ALL
261 UNIMPLEMENTED KiNmiInterrupt
269 PUBLIC KiBreakpointTrap
270 FUNC KiBreakpointTrap
271 /* Push pseudo error code */
272 EnterTrap TF_SAVE_ALL
274 /* Check if the frame was from kernelmode */
275 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
276 jz KiBreakpointTrapKMode
278 /* Enable interrupts for user-mode */
281 KiBreakpointTrapKMode:
282 /* Dispatch the exception */
283 DispatchException STATUS_BREAKPOINT, 3, BREAKPOINT_BREAK, 0, 0
290 PUBLIC KiOverflowTrap
292 /* Push pseudo error code */
293 EnterTrap TF_SAVE_ALL
295 /* Enable interrupts */
298 /* Dispatch the exception */
299 DispatchException STATUS_INTEGER_OVERFLOW, 3, 0, 0, 0
309 EnterTrap TF_SAVE_ALL
311 /* Check if the frame was from kernelmode */
312 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
313 jnz KiBoundFaultUserMode
316 Fatal EXCEPTION_BOUND_CHECK
318 KiBoundFaultUserMode:
319 /* Enable interrupts for user-mode */
322 /* Dispatch the exception */
323 DispatchException STATUS_ARRAY_BOUNDS_EXCEEDED, 0, 0, 0, 0
330 PUBLIC KiInvalidOpcodeFault
331 FUNC KiInvalidOpcodeFault
333 EnterTrap TF_SAVE_ALL
335 TRAPINFO KiInvalidOpcodeFault
337 mov rdx, [rbp + KTRAP_FRAME_Rip]
338 lea rcx, MsgInvalidOpcodeFault[rip]
339 call qword ptr FrLdrDbgPrint[rip]
341 /* Enable interrupts */
344 /* Check if the frame was from kernelmode */
345 test word ptr [rbp + KTRAP_FRAME_SegCs], 3
346 jz KiInvalidOpcodeKernel
348 // FIXME: handle STATUS_INVALID_LOCK_SEQUENCE
350 KiInvalidOpcodeKernel:
351 /* Kernel mode fault */
353 /* Dispatch the exception */
354 DispatchException STATUS_ILLEGAL_INSTRUCTION, 3, 0, 0, 0
361 PUBLIC KiNpxNotAvailableFault
362 FUNC KiNpxNotAvailableFault
364 EnterTrap TF_SAVE_ALL
366 /* Call the C handler */
368 call KiNpxNotAvailableFaultHandler
370 /* Check the return status code */
372 jz KiNpxNotAvailableFaultExit
374 /* Dispatch the exception */
375 DispatchException eax, 3, 0, 0, 0
377 KiNpxNotAvailableFaultExit:
383 PUBLIC KiDoubleFaultAbort
384 FUNC KiDoubleFaultAbort
386 EnterTrap TF_SAVE_ALL
388 lea rcx, MsgDoubleFault[rip]
389 mov rdx, [rbp + KTRAP_FRAME_FaultAddress]
391 call qword ptr FrLdrDbgPrint[rip]
394 Fatal 8 // EXCEPTION_DOUBLE_FAULT
399 PUBLIC KiNpxSegmentOverrunAbort
400 FUNC KiNpxSegmentOverrunAbort
402 EnterTrap TF_SAVE_ALL
405 Fatal EXCEPTION_NPX_OVERRUN
411 PUBLIC KiInvalidTssFault
412 FUNC KiInvalidTssFault
413 /* We have an error code */
414 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
417 Fatal EXCEPTION_INVALID_TSS
422 PUBLIC KiSegmentNotPresentFault
423 FUNC KiSegmentNotPresentFault
424 /* We have an error code */
425 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
428 Fatal EXCEPTION_SEGMENT_NOT_PRESENT
435 /* We have an error code */
436 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
439 Fatal EXCEPTION_STACK_FAULT
444 PUBLIC KiGeneralProtectionFault
445 FUNC KiGeneralProtectionFault
446 /* We have an error code */
447 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
449 //TRAPINFO KiGeneralProtectionFault
450 //mov rdx, [rbp + KTRAP_FRAME_Rip]
451 //lea rcx, MsgGeneralProtFault[rip]
452 //call qword ptr FrLdrDbgPrint[rip]
454 /* Call the C handler */
456 call KiGeneralProtectionFaultHandler
458 /* Check for success */
462 /* Dispatch the exception */
463 DispatchException eax, 3, 0, 0, 0
468 mov ecx, UNEXPECTED_KERNEL_MODE_TRAP
469 mov rdx, HEX(000D) // EXCEPTION_GP_FAULT
471 mov r9, [rbp + KTRAP_FRAME_ErrorCode] // error code
473 mov [rsp + KTRAP_FRAME_P5+8], rbp // trap frame
474 call KeBugCheckWithTf
485 /* We have an error code */
486 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
491 lea rcx, MsgPageFault[rip]
492 mov rdx, [rbp + KTRAP_FRAME_ErrorCode]
493 mov r8, [rbp + KTRAP_FRAME_Rip]
494 mov r9, [rbp + KTRAP_FRAME_FaultAddress]
495 call qword ptr FrLdrDbgPrint[rip]
498 /* Save page fault address */
500 mov [rbp + KTRAP_FRAME_FaultAddress], rdx
502 /* Enable interrupts for the page fault handler */
505 /* Call page fault handler */
506 mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction
509 mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode
511 mov r9, rbp // TrapInformation
514 /* Check for success */
521 /* Check whether the kernel debugger has owed breakpoints to be inserted */
522 call KdSetOwedBreakpoints
523 /* We succeeded, return */
529 /* Disable interrupts again for the debugger */
532 /* Set parameter 1 to error code */
533 mov r9d, [rbp + KTRAP_FRAME_ErrorCode]
535 /* Set parameter2 to faulting address */
536 mov r10, cr2 // Param2 = faulting address
538 cmp eax, STATUS_ACCESS_VIOLATION
540 cmp eax, STATUS_GUARD_PAGE_VIOLATION
542 cmp eax, STATUS_STACK_OVERFLOW
546 /* Dispatch in-page exception */
547 mov r11d, eax // Param3 = Status
548 mov eax, STATUS_IN_PAGE_ERROR // ExceptionCode
549 mov edx, 3 // ParamCount
550 call InternalDispatchException
554 /* Use more proper status code */
555 mov eax, KI_EXCEPTION_ACCESS_VIOLATION
558 /* Setup a normal page fault exception */
559 mov edx, 2 // ParamCount
560 call InternalDispatchException
564 ExitTrap (TF_SAVE_ALL or TF_CHECKUSERAPC)
568 PUBLIC KiFloatingErrorFault
569 FUNC KiFloatingErrorFault
571 EnterTrap TF_SAVE_ALL
573 UNIMPLEMENTED KiFloatingErrorFault
581 PUBLIC KiAlignmentFault
582 FUNC KiAlignmentFault
583 /* We have an error code */
584 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
587 Fatal EXCEPTION_ALIGNMENT_CHECK
595 EnterTrap TF_SAVE_ALL
603 PUBLIC KiXmmException
606 EnterTrap TF_SAVE_ALL
608 /* Call the C handler */
610 call KiXmmExceptionHandler
612 /* Check for success */
616 /* Dispatch the exception */
617 DispatchException eax, 3, 0, 0, 0
625 /* SOFTWARE INTERRUPT SERVICES ***********************************************/
627 PUBLIC KiRaiseAssertion
628 FUNC KiRaiseAssertion
629 /* We have an error code */
630 EnterTrap (TF_SAVE_ALL)
632 /* Decrement RIP to point to the INT2C instruction (2 bytes, not 1 like INT3) */
633 sub qword ptr [rbp + KTRAP_FRAME_Rip], 2
635 /* Dispatch the exception */
636 DispatchException STATUS_ASSERTION_FAILURE, 0, 0, 0, 0
643 PUBLIC KiDebugServiceTrap
644 FUNC KiDebugServiceTrap
646 EnterTrap TF_SAVE_ALL
648 TRAPINFO KiDebugServiceTrap
650 /* Increase Rip to skip the int3 */
651 inc qword ptr [rbp + KTRAP_FRAME_Rip]
653 /* Dispatch the exception (Params = service, buffer, legth) */
654 DispatchException STATUS_BREAKPOINT, 3, [rbp+KTRAP_FRAME_Rax], [rbp+KTRAP_FRAME_Rcx], [rbp+KTRAP_FRAME_Rdx]
661 PUBLIC KiApcInterrupt
664 EnterTrap (TF_VOLATILES or TF_IRQL)
666 /* Raise to APC_LEVEL */
670 /* End the interrupt */
671 mov dword ptr [APIC_EOI], 0
673 /* Enable interrupts */
676 /* Call the worker routine */
677 mov cl, [rbp + KTRAP_FRAME_SegCs] // ProcessorMode
679 mov rdx, 0 // ExceptionFrame
680 mov r8, rdx // TrapFrame
683 /* Disable interrupts */
686 /* Lower IRQL back to PASSIVE */
687 mov rax, PASSIVE_LEVEL
691 ExitTrap (TF_VOLATILES or TF_IRQL)
694 EXTERN KiRetireDpcList:PROC
695 PUBLIC KiRetireDpcListInDpcStack
696 .PROC KiRetireDpcListInDpcStack
703 /* Switch stack and call the function */
708 /* Restore stack, cleanup and return */
714 PUBLIC KiDpcInterrupt
717 EnterTrap (TF_VOLATILES or TF_IRQL)
719 /* Call the worker routine */
720 call KiDpcInterruptHandler
722 /* Return, but don't send an EOI! */
723 ExitTrap (TF_VOLATILES or TF_IRQL)
727 PUBLIC KiIpiInterrupt
730 EnterTrap (TF_VOLATILES or TF_IRQL)
732 /* Raise to IPI_LEVEL */
736 /* End the interrupt */
737 mov dword ptr [APIC_EOI], 0
742 ExitTrap (TF_VOLATILES or TF_IRQL)
746 PUBLIC KiUnexpectedInterrupt
747 FUNC KiUnexpectedInterrupt
748 /* The error code is the vector */
749 EnterTrap (TF_HAS_ERROR_CODE OR TF_SAVE_ALL)
752 /* Set bugcheck parameters */
753 mov ecx, TRAP_CAUSE_UNKNOWN
754 mov rdx, [rbp + KTRAP_FRAME_ErrorCode] // the vector
755 mov r8, 0 // The unknown floating-point exception
756 mov r9, 0 // The enabled and asserted status bits
758 mov [rbp + KTRAP_FRAME_P5 + 8], rbp // trap frame
759 call KeBugCheckWithTf
766 PUBLIC KiInterruptDispatch
767 FUNC KiInterruptDispatch
768 /* The error code is a pointer to the interrupt object's code */
769 EnterTrap (TF_HAS_ERROR_CODE or TF_SAVE_ALL or TF_IRQL)
771 /* Increase interrupt count */
772 inc dword ptr gs:[PcInterruptCount];
774 /* Load the address of the interrupt object into rcx */
775 mov rcx, [rbp + KTRAP_FRAME_ErrorCode]
777 /* Substract offset of the DispatchCode member plus 6 for the call instruction */
778 sub rcx, KINTERRUPT_DispatchCode + 6
780 /* Raise IRQL to SynchronizeIrql */
781 movzx rax, byte ptr [rcx + KINTERRUPT_SynchronizeIrql]
785 /* Acquire interrupt lock */
786 mov r8, [rcx + KINTERRUPT_ActualLock]
788 //KxAcquireSpinLock(Interrupt->ActualLock);
792 mov rdx, [rcx + KINTERRUPT_ServiceContext]
793 call qword ptr [rcx + KINTERRUPT_ServiceRoutine]
796 /* Release interrupt lock */
797 //KxReleaseSpinLock(Interrupt->ActualLock);
800 /* Go back to old irql */
801 movzx rax, byte ptr [rbp + KTRAP_FRAME_PreviousIrql]
805 ExitTrap (TF_SAVE_ALL or TF_SEND_EOI)
809 #define MAX_SYSCALL_PARAM_SIZE (16 * 8)
810 #define HOME_SIZE 6*8
811 #define SYSCALL_ALLOCATION (MAX_SYSCALL_PARAM_SIZE + HOME_SIZE)
813 EXTERN KiSystemCallHandler:PROC
815 /*! \name KiSystemCallEntry64
817 * \brief This is the entrypoint for syscalls from 64bit user mode
819 * \param rax - The system call number
820 * \param rcx - User mode return address, set by the syscall instruction
821 * \param rdx,r8,r9 - Parameters 2-4 to the service function
822 * \param r10 - Parameter 1 to the service function
823 * \param r11 - RFLAGS saved by the syscall instruction
825 PUBLIC KiSystemCallEntry64
826 .PROC KiSystemCallEntry64
828 /* Old stack pointer is in rcx, lie and say we saved it in rbp */
832 /* Swap gs to kernel, so we can access the PCR */
835 /* Save the user mode rsp in the PCR */
836 mov gs:[PcUserRsp], rsp
838 /* Get the kernel stack from the PCR */
839 mov rsp, gs:[PcRspBase]
841 /* Allocate a TRAP_FRAME and space for parameters */
842 sub rsp, (KTRAP_FRAME_LENGTH + MAX_SYSCALL_PARAM_SIZE + HOME_SIZE)
844 /* Save rbp and load it with the old stack pointer */
845 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + HOME_SIZE + KTRAP_FRAME_Rbp], rbp
846 mov rbp, gs:[PcUserRsp]
849 /* Save important volatiles in the trap frame */
850 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rax], rax
851 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rcx], rcx
852 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R10], r10
853 mov [rsp + HOME_SIZE + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R11], r11
855 /* Set sane segments */
856 mov ax, (KGDT64_R3_DATA or RPL_MASK)
860 /* Call the C-handler (will enable interrupts) */
861 lea rcx, [rsp + SYSCALL_ALLOCATION]
862 call KiSystemCallHandler
864 /* Deallocate the handlers home stack frame */
867 /* The return value is the address of the Nt-function */
876 mov rbp, [rsp + SYSCALL_ALLOCATION + KTRAP_FRAME_Rbp]
879 /* Disable interrupts for return */
882 /* Restore old trap frame */
883 mov rcx, gs:[PcCurrentThread]
884 mov rdx, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_TrapFrame]
885 mov [rcx + KTHREAD_TrapFrame], rdx
887 /* Prepare user mode return address (rcx) and eflags (r11) for sysret */
888 mov rcx, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rcx]
889 mov r11, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_R11]
891 /* Load user mode stack (It was copied to the trap frame) */
892 mov rsp, [rsp + MAX_SYSCALL_PARAM_SIZE + KTRAP_FRAME_Rsp]
894 /* Swap gs back to user */
897 /* return to user mode */
898 .byte HEX(48) // REX prefix to return to long mode
903 PUBLIC KiSystemCallEntry32
909 PUBLIC KiZwSystemService
910 FUNC KiZwSystemService
913 sub rsp, KTRAP_FRAME_LENGTH
914 .allocstack KTRAP_FRAME_LENGTH
915 mov [rsp + KTRAP_FRAME_Rsi], rsi
916 .savereg rsi, KTRAP_FRAME_Rsi
917 mov [rsp + KTRAP_FRAME_Rdi], rdi
918 .savereg rdi, KTRAP_FRAME_Rdi
923 /* Get current thread */
924 mov r11, gs:[PcCurrentThread]
926 /* Save the old trap frame in TrapFrame.Rdx */
927 mov rdi, [r11 + KTHREAD_TrapFrame]
928 mov [rbp + KTRAP_FRAME_Rdx], rdi
930 /* Set the new trap frame and previous mode */
931 mov [r11 + ThTrapFrame], rbp
932 mov byte ptr [r11 + KTHREAD_PreviousMode], 0
934 /* allocate space for parameters */
936 and rsp, HEX(0fffffffffffffff0)
939 mov [rbp + KTRAP_FRAME_Rcx], rcx
941 /* copy parameters to the new location */
942 lea rsi, [rbp + KTRAP_FRAME_LENGTH + 16]
949 mov rcx, [rbp + KTRAP_FRAME_Rcx]
951 /* Call the service function */
954 /* Restore the old trap frame */
955 mov r11, gs:[PcCurrentThread]
956 mov rsi, [rsp + KTRAP_FRAME_Rdx]
957 mov [r11 + KTHREAD_TrapFrame], rsi
959 /* Restore rdi and rsi */
960 mov rsi, [rbp + KTRAP_FRAME_Rsi]
961 mov rdi, [rbp + KTRAP_FRAME_Rdi]
963 /* Cleanup the stack and return */
964 lea rsp, [rbp + KTRAP_FRAME_LENGTH]
977 * KiServiceExit(IN PKTRAP_FRAME TrapFrame, IN NTSTATUS Status));
981 mov [rcx + KTRAP_FRAME_Rax], rdx
986 //ExitTrap TF_SAVE_ALL
991 * KiServiceExit2(IN PKTRAP_FRAME TrapFrame);
993 PUBLIC KiServiceExit2
1001 ExitTrap TF_SAVE_ALL
1004 PUBLIC KiInitializeSegments
1005 KiInitializeSegments:
1006 mov ax, KGDT64_R3_DATA or RPL_MASK
1017 //void __lgdt(void *Source);
1020 lgdt fword ptr [rcx]
1023 //void __sgdt(void *Destination);
1026 sgdt fword ptr [rcx]
1029 // void __lldt(unsigned short Value)
1035 //void __sldt(void *Destination);
1041 //void __ltr(unsigned short Source);
1047 //void __str(unsigned short *Destination);