2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2001 MIPS Technologies, Inc.
10 * Hairy, the userspace application uses a different argument passing
11 * convention than the kernel, so we have to translate things from o32
12 * to ABI64 calling convention. 64-bit syscalls are also processed
16 #include <linux/errno.h>
17 #include <asm/mipsregs.h>
18 #include <asm/regdef.h>
19 #include <asm/stackframe.h>
20 #include <asm/unistd.h>
21 #include <asm/sysmips.h>
24 NESTED(handle_sys, PT_SIZE, sp)
29 ld t1, PT_EPC(sp) # skip syscall on return
31 subu t0, v0, __NR_O32_Linux # check syscall number
32 sltiu t0, t0, __NR_O32_Linux_syscalls + 1
33 daddiu t1, 4 # skip to next instruction
34 beqz t0, not_o32_scall
48 /* XXX Put both in one cacheline, should save a bit. */
49 dsll t0, v0, 3 # offset into table
50 ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0)
51 lbu t3, (sys_narg_table - __NR_O32_Linux)(v0)
53 subu t0, t3, 5 # 5 or more arguments?
54 sd a3, PT_R26(sp) # save a3 for syscall restarting
58 LONG_L t0, TI_FLAGS($28)
59 # syscall tracing enabled?
60 bnez t0, trace_a_syscall
62 jalr t2 # Do The Real Thing (TM)
64 li t0, -EMAXERRNO - 1 # error?
66 sd t0, PT_R7(sp) # set error flag
70 sd v0, PT_R0(sp) # flag for syscall restarting
71 1: sd v0, PT_R2(sp) # result
73 FEXPORT(o32_syscall_exit)
74 mfc0 t0, CP0_STATUS # make need_resched and
75 ori t0, t0, 1 # signals dont change between
76 xori t0, t0, 1 # sampling and return
80 LONG_L a2, TI_FLAGS($28)
81 bnez a2, o32_syscall_exit_work
83 restore_all: RESTORE_SOME
87 o32_syscall_exit_work:
91 /* ------------------------------------------------------------------------ */
104 ld a0, PT_R4(sp) # Restore argument registers
113 li t0, -EMAXERRNO - 1 # error?
115 sd t0, PT_R7(sp) # set error flag
119 sd v0, PT_R0(sp) # set flag for syscall restarting
120 1: sd v0, PT_R2(sp) # result
124 /* ------------------------------------------------------------------------ */
127 * More than four arguments. Try to deal with it by copying the
128 * stack arguments from the user stack to the kernel stack.
132 ld t0, PT_R29(sp) # get old user stack pointer
134 sll t1, t3, 2 # stack valid?
136 addu t1, t0 # end address
138 bltz t0, bad_stack # -> sp is bad
140 ld t0, PT_R29(sp) # get old user stack pointer
141 PTR_LA t1, 3f # copy 1 to 2 arguments
146 /* Ok, copy the args from the luser stack to the kernel stack */
150 1: lw a5, 20(t0) # argument #6 from usp
151 2: lw a4, 16(t0) # argument #5 from usp
154 j stack_done # go back
156 .section __ex_table,"a"
162 * The stackpointer for a call with more than 4 arguments is bad.
168 li t0, 1 # set error flag
174 * This is not an o32 compatibility syscall, pass it on
175 * to the 64-bit syscall handlers.
177 #ifdef CONFIG_MIPS32_N32
184 /* This also isn't a 64-bit syscall, throw an error. */
185 li v0, ENOSYS # error
187 li t0, 1 # set error flag
192 LEAF(mips_atomic_set)
193 andi v0, a1, 3 # must be word aligned
194 bnez v0, bad_alignment
196 ld v1, TI_ADDR_LIMIT($28) # in legal address range?
202 /* Ok, this is the ll/sc case. World is sane :-) */
208 .section __ex_table,"a"
213 1: sd v0, PT_R2(sp) # result
215 /* Success, so skip usual error handling garbage. */
216 LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
235 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
240 ld t0, PT_R29(sp) # user sp
242 sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
246 dla v1, sys32_syscall
247 ld t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
248 lbu t3, (sys_narg_table - __NR_O32_Linux)(a0)
251 beq t2, v1, out # do not recurse
253 beqz t2, enosys # null function pointer?
255 andi v0, t0, 0x3 # unaligned stack pointer?
258 daddiu v0, t0, 16 # v0 = usp + 16
259 daddu t1, v0, 12 # 3 32-bit arguments
260 ld v1, TI_ADDR_LIMIT($28)
265 move a0, a1 # shift argument registers
273 .section __ex_table,"a"
279 sw t3, 16(sp) # put into new stackframe
282 bnez t1, 1f # zero arguments?
283 daddu a0, sp, 32 # then pass sp in a0
291 enosys: li v0, -ENOSYS
300 efault: li v0, -EFAULT
306 sys sys32_syscall 0 /* 4000 */
311 sys sys_open 3 /* 4005 */
316 sys sys_unlink 1 /* 4010 */
321 sys sys_chmod 2 /* 4015 */
324 sys sys_ni_syscall 0 /* was sys_stat */
326 sys sys_getpid 0 /* 4020 */
331 sys sys_stime 1 /* 4025 */
334 sys sys_ni_syscall 0 /* was sys_fstat */
336 sys sys32_utime 2 /* 4030 */
341 sys sys_ni_syscall 0 /* 4035 */
346 sys sys_rmdir 1 /* 4040 */
351 sys sys_brk 1 /* 4045 */
354 sys sys_ni_syscall 0 /* was signal 2 */
356 sys sys_getegid 0 /* 4050 */
361 sys sys32_fcntl 3 /* 4055 */
364 sys sys_ni_syscall, 0
365 sys sys_ni_syscall 0 /* was sys_olduname */
366 sys sys_umask 1 /* 4060 */
371 sys sys_getpgrp 0 /* 4065 */
373 sys sys32_sigaction 3
376 sys sys_setreuid 2 /* 4070 */
378 sys sys32_sigsuspend 0
379 sys sys32_sigpending 1
380 sys sys_sethostname 2
381 sys sys32_setrlimit 2 /* 4075 */
382 sys sys32_getrlimit 2
383 sys sys32_getrusage 2
384 sys sys32_gettimeofday 2
385 sys sys32_settimeofday 2
386 sys sys_getgroups 2 /* 4080 */
388 sys sys_ni_syscall 0 /* old_select */
390 sys sys_ni_syscall 0 /* was sys_lstat */
391 sys sys_readlink 3 /* 4085 */
396 sys sys_mmap 6 /* 4090 */
401 sys sys_fchown 3 /* 4095 */
402 sys sys_getpriority 2
403 sys sys_setpriority 3
406 sys sys32_fstatfs 2 /* 4100 */
407 sys sys_ni_syscall 0 /* sys_ioperm */
410 sys sys32_setitimer 3
411 sys sys32_getitimer 2 /* 4105 */
415 sys sys_ni_syscall 0 /* was sys_uname */
416 sys sys_ni_syscall 0 /* sys_ioperm *//* 4110 */
418 sys sys_ni_syscall 0 /* was sys_idle */
419 sys sys_ni_syscall 0 /* sys_vm86 */
421 sys sys_swapoff 1 /* 4115 */
425 sys sys32_sigreturn 0
426 sys sys_clone 0 /* 4120 */
427 sys sys_setdomainname 2
429 sys sys_ni_syscall 0 /* sys_modify_ldt */
431 sys sys_mprotect 3 /* 4125 */
432 sys sys32_sigprocmask 3
433 sys sys_ni_syscall 0 /* was creat_module */
434 sys sys_init_module 5
435 sys sys_delete_module 1
436 sys sys_ni_syscall 0 /* 4130, get_kernel_syms */
441 sys sys_sysfs 3 /* 4135 */
442 sys sys32_personality 1
443 sys sys_ni_syscall 0 /* for afs_syscall */
446 sys sys32_llseek 5 /* 4140 */
451 sys sys32_readv 3 /* 4145 */
456 sys sys_ni_syscall 0 /* 4150 */
461 sys sys_munlock 2 /* 4155 */
464 sys sys_sched_setparam 2
465 sys sys_sched_getparam 2
466 sys sys_sched_setscheduler 3 /* 4160 */
467 sys sys_sched_getscheduler 1
468 sys sys_sched_yield 0
469 sys sys_sched_get_priority_max 1
470 sys sys_sched_get_priority_min 1
471 sys sys32_sched_rr_get_interval 2 /* 4165 */
472 sys sys32_nanosleep 2
476 sys sys_connect 3 /* 4170 */
477 sys sys_getpeername 3
478 sys sys_getsockname 3
481 sys sys_recv 4 /* 4175 */
486 sys sys_sendto 6 /* 4180 */
487 sys sys32_setsockopt 5
491 sys sys_setresuid 3 /* 4185 */
493 sys sys_ni_syscall 0 /* was query_module */
496 sys sys_setresgid 3 /* 4190 */
499 sys sys32_rt_sigreturn 0
500 sys sys32_rt_sigaction 4
501 sys sys32_rt_sigprocmask 4 /* 4195 */
502 sys sys32_rt_sigpending 2
503 sys sys32_rt_sigtimedwait 4
504 sys sys32_rt_sigqueueinfo 3
505 sys sys32_rt_sigsuspend 0
506 sys sys32_pread 6 /* 4200 */
511 sys sys_capset 2 /* 4205 */
512 sys sys32_sigaltstack 0
516 sys sys32_mmap2 6 /* 4210 */
517 sys sys32_truncate64 4
518 sys sys32_ftruncate64 4
521 sys sys_newfstat 2 /* 4215 */
526 sys sys32_fcntl64 3 /* 4220 */
529 sys sys32_readahead 5
531 sys sys_lsetxattr 5 /* 4225 */
536 sys sys_listxattr 3 /* 4230 */
539 sys sys_removexattr 2
540 sys sys_lremovexattr 2
541 sys sys_fremovexattr 2 /* 4235 */
545 sys sys32_sched_setaffinity 3
546 sys sys32_sched_getaffinity 3 /* 4240 */
549 sys sys_io_getevents 5
551 sys sys_io_cancel 3 /* 4245 */
553 sys sys_lookup_dcookie 3
554 sys sys_epoll_create 1
556 sys sys_epoll_wait 3 /* 4250 */
557 sys sys_remap_file_pages 5
558 sys sys_set_tid_address 1
561 .macro sys function, nargs
569 .macro sys function, nargs