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, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
7 * Copyright (C) 2001 MIPS Technologies, Inc.
9 #include <linux/config.h>
10 #include <linux/errno.h>
12 #include <asm/asmmacro.h>
13 #include <asm/mipsregs.h>
14 #include <asm/regdef.h>
15 #include <asm/stackframe.h>
16 #include <asm/isadep.h>
17 #include <asm/sysmips.h>
18 #include <asm/thread_info.h>
19 #include <asm/unistd.h>
21 #include <asm/offset.h>
23 /* Highest syscall used of any syscall flavour */
24 #define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
27 NESTED(handle_sys, PT_SIZE, sp)
33 lw t1, PT_EPC(sp) # skip syscall on return
35 sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
36 addiu t1, 4 # skip to next instruction
38 beqz t0, illegal_syscall
40 /* XXX Put both in one cacheline, should save a bit. */
42 lw t2, sys_call_table(t0) # syscall routine
43 lbu t3, sys_narg_table(v0) # number of arguments
44 beqz t2, illegal_syscall;
46 subu t0, t3, 5 # 5 or more arguments?
47 sw a3, PT_R26(sp) # save a3 for syscall restarting
51 sw a3, PT_R26(sp) # save for syscall restart
52 LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
53 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
55 bnez t0, syscall_trace_entry # -> yes
57 jalr t2 # Do The Real Thing (TM)
59 li t0, -EMAXERRNO - 1 # error?
61 sw t0, PT_R7(sp) # set error flag
65 sw v0, PT_R0(sp) # set flag for syscall
67 1: sw v0, PT_R2(sp) # result
69 EXPORT(o32_syscall_exit)
70 local_irq_disable # make sure need_resched and
71 # signals dont change between
73 LONG_L a2, TI_FLAGS($28) # current->work
74 li t0, _TIF_ALLWORK_MASK
76 bnez t0, o32_syscall_exit_work
80 o32_syscall_exit_work:
81 j syscall_exit_work_partial
83 /* ------------------------------------------------------------------------ */
93 lw a0, PT_R4(sp) # Restore argument registers
99 li t0, -EMAXERRNO - 1 # error?
101 sw t0, PT_R7(sp) # set error flag
105 sw v0, PT_R0(sp) # set flag for syscall
107 1: sw v0, PT_R2(sp) # result
111 /* ------------------------------------------------------------------------ */
114 * More than four arguments. Try to deal with it by copying the
115 * stack arguments from the user stack to the kernel stack.
119 lw t0, PT_R29(sp) # get old user stack pointer
121 sll t1, t3, 2 # stack valid?
123 addu t1, t0 # end address
125 bltz t0, bad_stack # -> sp is bad
127 lw t0, PT_R29(sp) # get old user stack pointer
128 PTR_LA t1, 4f # copy 1 to 3 arguments
133 /* Ok, copy the args from the luser stack to the kernel stack */
135 * I know Ralf doesn't like nops but this avoids code
136 * duplication for R3000 targets (and this is the
137 * only place where ".set reorder" doesn't help).
143 1: lw t1, 24(t0) # argument #7 from usp
147 2: lw t1, 20(t0) # argument #5 from usp
151 3: lw t1, 16(t0) # argument #5 from usp
157 j stack_done # go back
159 .section __ex_table,"a"
166 * The stackpointer for a call with more than 4 arguments is bad.
167 * We probably should handle this case a bit more drastic.
173 li t0, 1 # set error flag
178 * The system call does not exist in this kernel
181 li v0, ENOSYS # error
183 li t0, 1 # set error flag
188 LEAF(mips_atomic_set)
189 andi v0, a1, 3 # must be word aligned
190 bnez v0, bad_alignment
192 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
198 #ifdef CONFIG_CPU_HAS_LLSC
199 /* Ok, this is the ll/sc case. World is sane :-) */
209 .section __ex_table,"a"
226 * At this point the page should be readable and writable unless
227 * there was no more memory available.
232 .section __ex_table,"a"
238 sw zero, PT_R7(sp) # success
239 sw v0, PT_R2(sp) # result
241 /* Success, so skip usual error handling garbage. */
242 LONG_L a2, TI_FLAGS($28) # syscall tracing enabled?
243 li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
255 no_mem: li v0, -ENOMEM
268 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
273 lw t0, PT_R29(sp) # user sp
275 sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
280 lw t2, sys_call_table(v0) # function pointer
281 lbu t4, sys_narg_table(a0) # number of arguments
284 beq t2, v1, out # do not recurse
286 beqz t2, enosys # null function pointer?
288 andi v0, t0, 0x3 # unaligned stack pointer?
291 addu v0, t0, 16 # v0 = usp + 16
292 addu t1, v0, 12 # 3 32-bit arguments
293 lw v1, TI_ADDR_LIMIT($28)
298 move a0, a1 # shift argument registers
306 .section __ex_table, "a"
312 sw t3, 16(sp) # put into new stackframe
315 bnez t4, 1f # zero arguments?
316 addu a0, sp, 32 # then pass sp in a0
324 enosys: li v0, -ENOSYS
333 efault: li v0, -EFAULT
338 .macro fifty ptr, nargs, from=1, to=50
341 fifty \ptr,\nargs,"(\from+1)",\to
345 .macro mille ptr, nargs, from=1, to=20
348 mille \ptr,\nargs,"(\from+1)",\to
353 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
354 #include "irix5sys.h" /* 1000 - 1999 32-bit IRIX */
355 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
356 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
358 sys sys_syscall 0 /* 4000 */
363 sys sys_open 3 /* 4005 */
368 sys sys_unlink 1 /* 4010 */
373 sys sys_chmod 2 /* 4015 */
376 sys sys_ni_syscall 0 /* was sys_stat */
378 sys sys_getpid 0 /* 4020 */
383 sys sys_stime 1 /* 4025 */
386 sys sys_ni_syscall 0 /* was sys_fstat */
388 sys sys_utime 2 /* 4030 */
393 sys sys_ni_syscall 0 /* 4035 */
398 sys sys_rmdir 1 /* 4040 */
403 sys sys_brk 1 /* 4045 */
406 sys sys_ni_syscall 0 /* was signal(2) */
408 sys sys_getegid 0 /* 4050 */
413 sys sys_fcntl 3 /* 4055 */
418 sys sys_umask 1 /* 4060 */
423 sys sys_getpgrp 0 /* 4065 */
428 sys sys_setreuid 2 /* 4070 */
432 sys sys_sethostname 2
433 sys sys_setrlimit 2 /* 4075 */
436 sys sys_gettimeofday 2
437 sys sys_settimeofday 2
438 sys sys_getgroups 2 /* 4080 */
440 sys sys_ni_syscall 0 /* old_select */
442 sys sys_ni_syscall 0 /* was sys_lstat */
443 sys sys_readlink 3 /* 4085 */
448 sys old_mmap 6 /* 4090 */
453 sys sys_fchown 3 /* 4095 */
454 sys sys_getpriority 2
455 sys sys_setpriority 3
458 sys sys_fstatfs 2 /* 4100 */
459 sys sys_ni_syscall 0 /* was ioperm(2) */
463 sys sys_getitimer 2 /* 4105 */
468 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
470 sys sys_ni_syscall 0 /* was sys_idle() */
471 sys sys_ni_syscall 0 /* was sys_vm86 */
473 sys sys_swapoff 1 /* 4115 */
478 sys sys_clone 0 /* 4120 */
479 sys sys_setdomainname 2
481 sys sys_ni_syscall 0 /* sys_modify_ldt */
483 sys sys_mprotect 3 /* 4125 */
484 sys sys_sigprocmask 3
485 sys sys_ni_syscall 0 /* was create_module */
486 sys sys_init_module 5
487 sys sys_delete_module 1
488 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
493 sys sys_sysfs 3 /* 4135 */
494 sys sys_personality 1
495 sys sys_ni_syscall 0 /* for afs_syscall */
498 sys sys_llseek 5 /* 4140 */
503 sys sys_readv 3 /* 4145 */
508 sys sys_ni_syscall 0 /* 4150 */
513 sys sys_munlock 2 /* 4155 */
516 sys sys_sched_setparam 2
517 sys sys_sched_getparam 2
518 sys sys_sched_setscheduler 3 /* 4160 */
519 sys sys_sched_getscheduler 1
520 sys sys_sched_yield 0
521 sys sys_sched_get_priority_max 1
522 sys sys_sched_get_priority_min 1
523 sys sys_sched_rr_get_interval 2 /* 4165 */
528 sys sys_connect 3 /* 4170 */
529 sys sys_getpeername 3
530 sys sys_getsockname 3
533 sys sys_recv 4 /* 4175 */
538 sys sys_sendto 6 /* 4180 */
543 sys sys_setresuid 3 /* 4185 */
545 sys sys_ni_syscall 0 /* was sys_query_module */
548 sys sys_setresgid 3 /* 4190 */
551 sys sys_rt_sigreturn 0
552 sys sys_rt_sigaction 4
553 sys sys_rt_sigprocmask 4 /* 4195 */
554 sys sys_rt_sigpending 2
555 sys sys_rt_sigtimedwait 4
556 sys sys_rt_sigqueueinfo 3
557 sys sys_rt_sigsuspend 0
558 sys sys_pread64 6 /* 4200 */
563 sys sys_capset 2 /* 4205 */
564 sys sys_sigaltstack 0
568 sys sys_mmap2 6 /* 4210 */
570 sys sys_ftruncate64 4
573 sys sys_fstat64 2 /* 4215 */
578 sys sys_fcntl64 3 /* 4220 */
583 sys sys_lsetxattr 5 /* 4225 */
588 sys sys_listxattr 3 /* 4230 */
591 sys sys_removexattr 2
592 sys sys_lremovexattr 2
593 sys sys_fremovexattr 2 /* 4235 */
597 sys sys_sched_setaffinity 3
598 sys sys_sched_getaffinity 3 /* 4240 */
601 sys sys_io_getevents 5
603 sys sys_io_cancel 3 /* 4245 */
605 sys sys_lookup_dcookie 3
606 sys sys_epoll_create 1
608 sys sys_epoll_wait 3 /* 4250 */
609 sys sys_remap_file_pages 5
610 sys sys_set_tid_address 1
611 sys sys_restart_syscall 0
612 sys sys_fadvise64_64 7
613 sys sys_statfs64 3 /* 4255 */
615 sys sys_timer_create 3
616 sys sys_timer_settime 4
617 sys sys_timer_gettime 2
618 sys sys_timer_getoverrun 1 /* 4260 */
619 sys sys_timer_delete 1
620 sys sys_clock_settime 2
621 sys sys_clock_gettime 2
622 sys sys_clock_getres 2
623 sys sys_clock_nanosleep 4 /* 4265 */
626 sys sys_ni_syscall 0 /* sys_mbind */
627 sys sys_ni_syscall 0 /* sys_get_mempolicy */
628 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
631 sys sys_mq_timedsend 5
632 sys sys_mq_timedreceive 5
633 sys sys_mq_notify 2 /* 4275 */
634 sys sys_mq_getsetattr 3
635 sys sys_ni_syscall 0 /* sys_vserver */
639 .macro sys function, nargs
646 .size sys_call_table, . - sys_call_table
648 .macro sys function, nargs
654 .size sys_narg_table, . - sys_narg_table