3 * Copyright (C) 2000 David Welch <welch@cwcom.net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 * FILE: ntoskrnl/hal/x86/syscall.s
22 * PURPOSE: 2E trap handler
23 * PROGRAMMER: David Welch (david.welch@seh.ox.ac.uk)
28 #include <ddk/status.h>
29 #include <internal/i386/segment.h>
30 #include <internal/ps.h>
32 #define KernelMode (0)
38 .globl KeReturnFromSystemCall
39 .globl KeReturnFromSystemCallWithHook
40 .globl _interrupt_handler2e
43 /* Construct a trap frame on the stack */
52 /* Load PCR selector into fs */
53 movl $PCR_SELECTOR, %ebx
56 /* Save the old exception list */
57 movl %fs:KPCR_EXCEPTION_LIST, %ebx
59 /* Set the exception handler chain terminator */
60 movl $0xffffffff, %fs:KPCR_EXCEPTION_LIST
61 /* Get a pointer to the current thread */
62 movl %fs:KPCR_CURRENT_THREAD, %esi
63 /* Save the old previous mode */
65 movb %ss:KTHREAD_PREVIOUS_MODE(%esi), %bl
67 /* Set the new previous mode based on the saved CS selector */
69 andl $0x0000FFFF, %ebx
72 movb $KernelMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
75 movb $UserMode, %ss:KTHREAD_PREVIOUS_MODE(%esi)
78 /* Save other registers */
91 pushl $0 /* XXX: TempESP */
92 pushl $0 /* XXX: TempCS */
93 pushl $0 /* XXX: DebugPointer */
94 pushl $0 /* XXX: DebugArgMark */
96 pushl %ebx /* DebugEIP */
97 pushl %ebp /* DebugEBP */
99 /* Load the segment registers */
100 movl $KERNEL_DS, %ebx
106 * Save the old trap frame pointer over where we would save the EDX
109 movl KTHREAD_TRAP_FRAME(%esi), %ebx
110 movl %ebx, 0x3C(%esp)
112 /* Save a pointer to the trap frame in the TCB */
113 movl %esp, KTHREAD_TRAP_FRAME(%esi)
115 /* Set ES to kernel segment */
119 /* Allocate new Kernel stack frame */
122 /* Users's current stack frame pointer is source */
125 /* Determine system service table to use */
127 ja new_useShadowTable
129 /* Check to see if EAX is valid/inrange */
130 cmpl %es:_KeServiceDescriptorTable + 8, %eax
131 jbe new_serviceInRange
132 movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
133 jmp KeReturnFromSystemCall
137 /* Allocate room for argument list from kernel stack */
138 movl %es:_KeServiceDescriptorTable + 12, %ecx
139 movl %es:(%ecx, %eax, 4), %ecx
142 /* Copy the arguments from the user stack to the kernel stack */
147 /* DS is now also kernel segment */
150 /* Call system call hook */
152 call _KiSystemCallHook
155 /* Make the system service call */
156 movl %es:_KeServiceDescriptorTable, %ecx
157 movl %es:(%ecx, %eax, 4), %eax
161 /* Bump Service Counter */
164 /* Deallocate the kernel stack frame */
167 /* Call the post system call hook and deliver any pending APCs */
170 call _KiAfterSystemCallHook
173 jmp KeReturnFromSystemCall
179 /* Check to see if EAX is valid/inrange */
180 cmpl %es:_KeServiceDescriptorTableShadow + 24, %eax
181 jbe new_shadowServiceInRange
182 movl $STATUS_INVALID_SYSTEM_SERVICE, %eax
183 jmp KeReturnFromSystemCall
185 new_shadowServiceInRange:
187 /* Allocate room for argument list from kernel stack */
188 movl %es:_KeServiceDescriptorTableShadow + 28, %ecx
189 movl %es:(%ecx, %eax, 4), %ecx
192 /* Copy the arguments from the user stack to the kernel stack */
197 /* DS is now also kernel segment */
200 /* Call system call hook */
202 // call _KiSystemCallHook
205 /* Call service check routine */
210 /* Make the system service call */
211 movl %es:_KeServiceDescriptorTableShadow + 16, %ecx
212 movl %es:(%ecx, %eax, 4), %eax
216 /* Bump Service Counter */
219 /* Deallocate the kernel stack frame */
222 KeReturnFromSystemCallWithHook:
223 /* Call the post system call hook and deliver any pending APCs */
226 call _KiAfterSystemCallHook
229 KeReturnFromSystemCall:
231 /* Restore the user context */
232 /* Get a pointer to the current thread */
235 /* Restore the old trap frame pointer */
236 movl 0x3c(%esp), %ebx
237 movl %ebx, KTHREAD_TRAP_FRAME(%esi)
239 /* Skip debug information and unsaved registers */
246 addl $0x4, %esp /* Don't restore eax */
248 /* Restore the old previous mode */
250 movb %bl, %ss:KTHREAD_PREVIOUS_MODE(%esi)
252 /* Restore the old exception handler list */
254 movl %ebx, %fs:KPCR_EXCEPTION_LIST
261 addl $0x4, %esp /* Ignore error code */