2 ** Copyright 2001-2004, Travis Geiselbrecht. All rights reserved.
3 ** Copyright 2002, Michael Noisternig. All rights reserved.
4 ** Distributed under the terms of the NewOS License.
7 #include <kernel/arch/x86_64/descriptors.h>
8 #include <kernel/arch/x86_64/kernel.h>
10 #define FUNCTION(x) .global x; .type x,@function; x
14 #define TRAP_ERRC(name, vector) \
22 #define TRAP(name, vector) \
79 /* push all the GP regs except rsp */
100 call x86_64_handle_trap
124 /* syscall entry point. arg passing is as follows:
126 * ecx: number of words on stack
127 * edx: pointer to args on user stack
129 * algorithm: push all registers, copy arguments to kernel stack, indirect
130 * jump through syscall_table (in kernel/syscalls.c).
133 FUNCTION(x86_64_syscall_vector):
134 #warning implement x86_64_syscall_vector
136 /* push a standard iframe to the stack */
137 pushl $0 // error code 0
138 pushl $99 // vector 99 (syscall)
146 movl $KERNEL_DATA_SEG,%ebx
151 /* save the current kernel stack, so we can restore to here in case of any error */
155 /* print the syscall */
156 push num_syscall_table_entries
163 push $syscall_entry_msg
172 /* sanity check vector number */
174 js syscall_vector_error
175 cmp num_syscall_table_entries,%eax
176 jge syscall_vector_error
178 /* sanity check number of args (must be 0-15) */
179 test $0xfffffff0,%ecx
180 jnz syscall_vector_error
182 /* check to make sure the args pointer is not inside kernel space */
183 test $KERNEL_ADDR_MASK,%edx
184 jnz syscall_vector_error
186 /* if the syscall has no args, fast path over the arg copy code */
190 /* set the fault handler in case we get an error copying data from the user stack */
191 movl %dr3,%ebx // get the current thread structure
192 mov fault_handler_offset,%esi // get the offset into the thread structure that fault_handler is
194 mov $syscall_vector_error,%esi
195 mov %esi,(%ebx) // stick the error handler into t->fault_handler
197 /* copy the appropriate number of args to the stack */
199 sub %ecx,%esp // move the stack pointer down by the amount we are about to dump on it
202 mov %edx,%esi // source is user space stack
203 mov %esp,%edi // dest is kernel stack
207 movl $0,(%ebx) // unset the error handler
210 movl %eax,%esi // move the vector number over to %esi
212 /* push the current iframe into the iframe stack */
214 call x86_64_push_frame
217 /* do kernel work upon entry */
218 call thread_atkernel_entry
220 /* load the syscall vector table */
221 movl $syscall_table,%ebx
224 /* save the return code into the iframe */
228 /* do any cleanup work when leaving the kernel */
229 call thread_atkernel_exit
231 call x86_64_pop_iframe
234 /* put the kernel stack back where it was before we pushed the args */
237 /* restore saved regs */
243 /* reverse the pusha from above */
245 addl $16,%esp // no need to pop orig_eax,orig_edx,vector,error_code
248 syscall_vector_error:
249 xorl $0xffffffff,%edx
252 jmp syscall_vector_exit
255 .ascii "syscall tid 0x%x eax %d ecx %d edx 0x%x max syscall 0x%x\n\0"
257 .ascii "here 0x%x\n\0"
262 #warning make sure this matches the syscall mechanism
263 FUNCTION(x86_64_return_from_signal):
264 add $12, %rsp // Flushes the 3 arguments to sa_handler
265 mov $81, %rax // This syscall will restore the cpu context to the
266 mov $0, %rcx // one existing before calling the signal handler
269 FUNCTION(x86_64_end_return_from_signal):