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
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 /* ------------------------------------------------------------------------ */
92 lw a0, PT_R4(sp) # Restore argument registers
98 li t0, -EMAXERRNO - 1 # error?
100 sw t0, PT_R7(sp) # set error flag
104 sw v0, PT_R0(sp) # set flag for syscall
106 1: sw v0, PT_R2(sp) # result
110 /* ------------------------------------------------------------------------ */
113 * More than four arguments. Try to deal with it by copying the
114 * stack arguments from the user stack to the kernel stack.
118 lw t0, PT_R29(sp) # get old user stack pointer
120 sll t1, t3, 2 # stack valid?
122 addu t1, t0 # end address
124 bltz t0, bad_stack # -> sp is bad
126 lw t0, PT_R29(sp) # get old user stack pointer
127 PTR_LA t1, 4f # copy 1 to 3 arguments
132 /* Ok, copy the args from the luser stack to the kernel stack */
134 * I know Ralf doesn't like nops but this avoids code
135 * duplication for R3000 targets (and this is the
136 * only place where ".set reorder" doesn't help).
142 1: lw t1, 24(t0) # argument #7 from usp
146 2: lw t1, 20(t0) # argument #5 from usp
150 3: lw t1, 16(t0) # argument #5 from usp
156 j stack_done # go back
158 .section __ex_table,"a"
165 * The stackpointer for a call with more than 4 arguments is bad.
166 * We probably should handle this case a bit more drastic.
172 li t0, 1 # set error flag
177 * The system call does not exist in this kernel
180 li v0, ENOSYS # error
182 li t0, 1 # set error flag
187 LEAF(mips_atomic_set)
188 andi v0, a1, 3 # must be word aligned
189 bnez v0, bad_alignment
191 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
197 #ifdef CONFIG_CPU_HAS_LLSC
198 /* Ok, this is the ll/sc case. World is sane :-) */
208 .section __ex_table,"a"
225 * At this point the page should be readable and writable unless
226 * there was no more memory available.
231 .section __ex_table,"a"
237 sw zero, PT_R7(sp) # success
238 sw v0, PT_R2(sp) # result
240 /* Success, so skip usual error handling garbage. */
241 LONG_L a2, TI_FLAGS($28) # syscall tracing enabled?
242 li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
254 no_mem: li v0, -ENOMEM
267 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
272 lw t0, PT_R29(sp) # user sp
274 sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
279 lw t2, sys_call_table(v0) # function pointer
280 lbu t4, sys_narg_table(a0) # number of arguments
283 beq t2, v1, out # do not recurse
285 beqz t2, enosys # null function pointer?
287 andi v0, t0, 0x3 # unaligned stack pointer?
290 addu v0, t0, 16 # v0 = usp + 16
291 addu t1, v0, 12 # 3 32-bit arguments
292 lw v1, TI_ADDR_LIMIT($28)
297 move a0, a1 # shift argument registers
305 .section __ex_table, "a"
311 sw t3, 16(sp) # put into new stackframe
314 bnez t4, 1f # zero arguments?
315 addu a0, sp, 32 # then pass sp in a0
323 enosys: li v0, -ENOSYS
332 efault: li v0, -EFAULT
337 .macro fifty ptr, nargs, from=1, to=50
340 fifty \ptr,\nargs,"(\from+1)",\to
344 .macro mille ptr, nargs, from=1, to=20
347 mille \ptr,\nargs,"(\from+1)",\to
352 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
353 #include "irix5sys.h" /* 1000 - 1999 32-bit IRIX */
354 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
355 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
357 sys sys_syscall 0 /* 4000 */
362 sys sys_open 3 /* 4005 */
367 sys sys_unlink 1 /* 4010 */
372 sys sys_chmod 2 /* 4015 */
375 sys sys_ni_syscall 0 /* was sys_stat */
377 sys sys_getpid 0 /* 4020 */
382 sys sys_stime 1 /* 4025 */
385 sys sys_ni_syscall 0 /* was sys_fstat */
387 sys sys_utime 2 /* 4030 */
392 sys sys_ni_syscall 0 /* 4035 */
397 sys sys_rmdir 1 /* 4040 */
402 sys sys_brk 1 /* 4045 */
405 sys sys_ni_syscall 0 /* was signal(2) */
407 sys sys_getegid 0 /* 4050 */
412 sys sys_fcntl 3 /* 4055 */
417 sys sys_umask 1 /* 4060 */
422 sys sys_getpgrp 0 /* 4065 */
427 sys sys_setreuid 2 /* 4070 */
431 sys sys_sethostname 2
432 sys sys_setrlimit 2 /* 4075 */
435 sys sys_gettimeofday 2
436 sys sys_settimeofday 2
437 sys sys_getgroups 2 /* 4080 */
439 sys sys_ni_syscall 0 /* old_select */
441 sys sys_ni_syscall 0 /* was sys_lstat */
442 sys sys_readlink 3 /* 4085 */
447 sys old_mmap 6 /* 4090 */
452 sys sys_fchown 3 /* 4095 */
453 sys sys_getpriority 2
454 sys sys_setpriority 3
457 sys sys_fstatfs 2 /* 4100 */
458 sys sys_ni_syscall 0 /* was ioperm(2) */
462 sys sys_getitimer 2 /* 4105 */
467 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
469 sys sys_ni_syscall 0 /* was sys_idle() */
470 sys sys_ni_syscall 0 /* was sys_vm86 */
472 sys sys_swapoff 1 /* 4115 */
477 sys sys_clone 0 /* 4120 */
478 sys sys_setdomainname 2
480 sys sys_ni_syscall 0 /* sys_modify_ldt */
482 sys sys_mprotect 3 /* 4125 */
483 sys sys_sigprocmask 3
484 sys sys_ni_syscall 0 /* was create_module */
485 sys sys_init_module 5
486 sys sys_delete_module 1
487 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
492 sys sys_sysfs 3 /* 4135 */
493 sys sys_personality 1
494 sys sys_ni_syscall 0 /* for afs_syscall */
497 sys sys_llseek 5 /* 4140 */
502 sys sys_readv 3 /* 4145 */
507 sys sys_ni_syscall 0 /* 4150 */
512 sys sys_munlock 2 /* 4155 */
515 sys sys_sched_setparam 2
516 sys sys_sched_getparam 2
517 sys sys_sched_setscheduler 3 /* 4160 */
518 sys sys_sched_getscheduler 1
519 sys sys_sched_yield 0
520 sys sys_sched_get_priority_max 1
521 sys sys_sched_get_priority_min 1
522 sys sys_sched_rr_get_interval 2 /* 4165 */
527 sys sys_connect 3 /* 4170 */
528 sys sys_getpeername 3
529 sys sys_getsockname 3
532 sys sys_recv 4 /* 4175 */
537 sys sys_sendto 6 /* 4180 */
542 sys sys_setresuid 3 /* 4185 */
544 sys sys_ni_syscall 0 /* was sys_query_module */
547 sys sys_setresgid 3 /* 4190 */
550 sys sys_rt_sigreturn 0
551 sys sys_rt_sigaction 4
552 sys sys_rt_sigprocmask 4 /* 4195 */
553 sys sys_rt_sigpending 2
554 sys sys_rt_sigtimedwait 4
555 sys sys_rt_sigqueueinfo 3
556 sys sys_rt_sigsuspend 0
557 sys sys_pread64 6 /* 4200 */
562 sys sys_capset 2 /* 4205 */
563 sys sys_sigaltstack 0
567 sys sys_mmap2 6 /* 4210 */
569 sys sys_ftruncate64 4
572 sys sys_fstat64 2 /* 4215 */
577 sys sys_fcntl64 3 /* 4220 */
582 sys sys_lsetxattr 5 /* 4225 */
587 sys sys_listxattr 3 /* 4230 */
590 sys sys_removexattr 2
591 sys sys_lremovexattr 2
592 sys sys_fremovexattr 2 /* 4235 */
596 sys sys_sched_setaffinity 3
597 sys sys_sched_getaffinity 3 /* 4240 */
600 sys sys_io_getevents 5
602 sys sys_io_cancel 3 /* 4245 */
604 sys sys_lookup_dcookie 3
605 sys sys_epoll_create 1
607 sys sys_epoll_wait 3 /* 4250 */
608 sys sys_remap_file_pages 5
609 sys sys_set_tid_address 1
610 sys sys_restart_syscall 0
611 sys sys_fadvise64_64 7
612 sys sys_statfs64 3 /* 4255 */
614 sys sys_timer_create 3
615 sys sys_timer_settime 4
616 sys sys_timer_gettime 2
617 sys sys_timer_getoverrun 1 /* 4260 */
618 sys sys_timer_delete 1
619 sys sys_clock_settime 2
620 sys sys_clock_gettime 2
621 sys sys_clock_getres 2
622 sys sys_clock_nanosleep 4 /* 4265 */
626 sys sys_ni_syscall 0 /* sys_get_mempolicy */
627 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
630 sys sys_mq_timedsend 5
631 sys sys_mq_timedreceive 5
632 sys sys_mq_notify 2 /* 4275 */
633 sys sys_mq_getsetattr 3
634 sys sys_ni_syscall 0 /* sys_vserver */
636 sys sys_ni_syscall 0 /* available, was setaltroot */
638 sys sys_request_key 4
643 .macro sys function, nargs
650 .size sys_call_table, . - sys_call_table
652 .macro sys function, nargs
658 .size sys_narg_table, . - sys_narg_table