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>
20 #include <asm/offset.h>
22 /* Highest syscall used of any syscall flavour */
23 #define MAX_SYSCALL_NO __NR_O32_Linux + __NR_O32_Linux_syscalls
26 NESTED(handle_sys, PT_SIZE, sp)
32 lw t1, PT_EPC(sp) # skip syscall on return
34 sltiu t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
35 addiu t1, 4 # skip to next instruction
37 beqz t0, illegal_syscall
39 /* XXX Put both in one cacheline, should save a bit. */
41 lw t2, sys_call_table(t0) # syscall routine
42 lbu t3, sys_narg_table(v0) # number of arguments
43 beqz t2, illegal_syscall;
45 subu t0, t3, 5 # 5 or more arguments?
46 sw a3, PT_R26(sp) # save a3 for syscall restarting
50 sw a3, PT_R26(sp) # save for syscall restart
51 LONG_L t0, TI_FLAGS($28) # syscall tracing enabled?
52 li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
54 bnez t0, syscall_trace_entry # -> yes
56 jalr t2 # Do The Real Thing (TM)
58 li t0, -EMAXERRNO - 1 # error?
60 sw t0, PT_R7(sp) # set error flag
64 sw v0, PT_R0(sp) # set flag for syscall
66 1: sw v0, PT_R2(sp) # result
68 EXPORT(o32_syscall_exit)
69 local_irq_disable # make sure need_resched and
70 # signals dont change between
72 LONG_L a2, TI_FLAGS($28) # current->work
73 li t0, _TIF_ALLWORK_MASK
75 bnez t0, o32_syscall_exit_work
79 o32_syscall_exit_work:
80 j syscall_exit_work_partial
82 /* ------------------------------------------------------------------------ */
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 :-) */
204 .section __ex_table,"a"
221 * At this point the page should be readable and writable unless
222 * there was no more memory available.
227 .section __ex_table,"a"
233 sw zero, PT_R7(sp) # success
234 sw v0, PT_R2(sp) # result
236 /* Success, so skip usual error handling garbage. */
237 LONG_L a2, TI_FLAGS($28) # syscall tracing enabled?
238 li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
250 no_mem: li v0, -ENOMEM
263 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
268 lw t0, PT_R29(sp) # user sp
270 sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
275 lw t2, sys_call_table(v0) # function pointer
276 lbu t4, sys_narg_table(a0) # number of arguments
279 beq t2, v1, out # do not recurse
281 beqz t2, enosys # null function pointer?
283 andi v0, t0, 0x3 # unaligned stack pointer?
286 addu v0, t0, 16 # v0 = usp + 16
287 addu t1, v0, 12 # 3 32-bit arguments
288 lw v1, TI_ADDR_LIMIT($28)
293 move a0, a1 # shift argument registers
301 .section __ex_table, "a"
307 sw t3, 16(sp) # put into new stackframe
310 bnez t4, 1f # zero arguments?
311 addu a0, sp, 32 # then pass sp in a0
319 enosys: li v0, -ENOSYS
328 efault: li v0, -EFAULT
333 .macro fifty ptr, nargs, from=1, to=50
336 fifty \ptr,\nargs,"(\from+1)",\to
340 .macro mille ptr, nargs, from=1, to=20
343 mille \ptr,\nargs,"(\from+1)",\to
348 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
349 #include "irix5sys.h" /* 1000 - 1999 32-bit IRIX */
350 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
351 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
353 sys sys_syscall 0 /* 4000 */
358 sys sys_open 3 /* 4005 */
363 sys sys_unlink 1 /* 4010 */
368 sys sys_chmod 2 /* 4015 */
371 sys sys_ni_syscall 0 /* was sys_stat */
373 sys sys_getpid 0 /* 4020 */
378 sys sys_stime 1 /* 4025 */
381 sys sys_ni_syscall 0 /* was sys_fstat */
383 sys sys_utime 2 /* 4030 */
388 sys sys_ni_syscall 0 /* 4035 */
393 sys sys_rmdir 1 /* 4040 */
398 sys sys_brk 1 /* 4045 */
401 sys sys_ni_syscall 0 /* was signal(2) */
403 sys sys_getegid 0 /* 4050 */
408 sys sys_fcntl 3 /* 4055 */
413 sys sys_umask 1 /* 4060 */
418 sys sys_getpgrp 0 /* 4065 */
423 sys sys_setreuid 2 /* 4070 */
427 sys sys_sethostname 2
428 sys sys_setrlimit 2 /* 4075 */
431 sys sys_gettimeofday 2
432 sys sys_settimeofday 2
433 sys sys_getgroups 2 /* 4080 */
435 sys sys_ni_syscall 0 /* old_select */
437 sys sys_ni_syscall 0 /* was sys_lstat */
438 sys sys_readlink 3 /* 4085 */
443 sys old_mmap 6 /* 4090 */
448 sys sys_fchown 3 /* 4095 */
449 sys sys_getpriority 2
450 sys sys_setpriority 3
453 sys sys_fstatfs 2 /* 4100 */
454 sys sys_ni_syscall 0 /* was ioperm(2) */
458 sys sys_getitimer 2 /* 4105 */
463 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
465 sys sys_ni_syscall 0 /* was sys_idle() */
466 sys sys_ni_syscall 0 /* was sys_vm86 */
468 sys sys_swapoff 1 /* 4115 */
473 sys sys_clone 0 /* 4120 */
474 sys sys_setdomainname 2
476 sys sys_ni_syscall 0 /* sys_modify_ldt */
478 sys sys_mprotect 3 /* 4125 */
479 sys sys_sigprocmask 3
480 sys sys_ni_syscall 0 /* was create_module */
481 sys sys_init_module 5
482 sys sys_delete_module 1
483 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
488 sys sys_sysfs 3 /* 4135 */
489 sys sys_personality 1
490 sys sys_ni_syscall 0 /* for afs_syscall */
493 sys sys_llseek 5 /* 4140 */
498 sys sys_readv 3 /* 4145 */
503 sys sys_ni_syscall 0 /* 4150 */
508 sys sys_munlock 2 /* 4155 */
511 sys sys_sched_setparam 2
512 sys sys_sched_getparam 2
513 sys sys_sched_setscheduler 3 /* 4160 */
514 sys sys_sched_getscheduler 1
515 sys sys_sched_yield 0
516 sys sys_sched_get_priority_max 1
517 sys sys_sched_get_priority_min 1
518 sys sys_sched_rr_get_interval 2 /* 4165 */
523 sys sys_connect 3 /* 4170 */
524 sys sys_getpeername 3
525 sys sys_getsockname 3
528 sys sys_recv 4 /* 4175 */
533 sys sys_sendto 6 /* 4180 */
538 sys sys_setresuid 3 /* 4185 */
540 sys sys_ni_syscall 0 /* was sys_query_module */
543 sys sys_setresgid 3 /* 4190 */
546 sys sys_rt_sigreturn 0
547 sys sys_rt_sigaction 4
548 sys sys_rt_sigprocmask 4 /* 4195 */
549 sys sys_rt_sigpending 2
550 sys sys_rt_sigtimedwait 4
551 sys sys_rt_sigqueueinfo 3
552 sys sys_rt_sigsuspend 0
553 sys sys_pread64 6 /* 4200 */
558 sys sys_capset 2 /* 4205 */
559 sys sys_sigaltstack 0
563 sys sys_mmap2 6 /* 4210 */
565 sys sys_ftruncate64 4
568 sys sys_fstat64 2 /* 4215 */
573 sys sys_fcntl64 3 /* 4220 */
578 sys sys_lsetxattr 5 /* 4225 */
583 sys sys_listxattr 3 /* 4230 */
586 sys sys_removexattr 2
587 sys sys_lremovexattr 2
588 sys sys_fremovexattr 2 /* 4235 */
592 sys sys_sched_setaffinity 3
593 sys sys_sched_getaffinity 3 /* 4240 */
596 sys sys_io_getevents 5
598 sys sys_io_cancel 3 /* 4245 */
600 sys sys_lookup_dcookie 3
601 sys sys_epoll_create 1
603 sys sys_epoll_wait 3 /* 4250 */
604 sys sys_remap_file_pages 5
605 sys sys_set_tid_address 1
606 sys sys_restart_syscall 0
607 sys sys_fadvise64_64 7
608 sys sys_statfs64 3 /* 4255 */
610 sys sys_timer_create 3
611 sys sys_timer_settime 4
612 sys sys_timer_gettime 2
613 sys sys_timer_getoverrun 1 /* 4260 */
614 sys sys_timer_delete 1
615 sys sys_clock_settime 2
616 sys sys_clock_gettime 2
617 sys sys_clock_getres 2
618 sys sys_clock_nanosleep 4 /* 4265 */
621 sys sys_ni_syscall 0 /* sys_mbind */
622 sys sys_ni_syscall 0 /* sys_get_mempolicy */
623 sys sys_ni_syscall 0 /* 4270 sys_set_mempolicy */
626 sys sys_mq_timedsend 5
627 sys sys_mq_timedreceive 5
628 sys sys_mq_notify 2 /* 4275 */
629 sys sys_mq_getsetattr 3
630 sys sys_ni_syscall 0 /* sys_vserver */
634 .macro sys function, nargs
641 .size sys_call_table, . - sys_call_table
643 .macro sys function, nargs
649 .size sys_narg_table, . - sys_narg_table