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
36 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
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 /* ------------------------------------------------------------------------ */
90 lw a0, PT_R4(sp) # Restore argument registers
96 li t0, -EMAXERRNO - 1 # error?
98 sw t0, PT_R7(sp) # set error flag
102 sw v0, PT_R0(sp) # set flag for syscall
104 1: sw v0, PT_R2(sp) # result
108 /* ------------------------------------------------------------------------ */
111 * More than four arguments. Try to deal with it by copying the
112 * stack arguments from the user stack to the kernel stack.
116 lw t0, PT_R29(sp) # get old user stack pointer
118 sll t1, t3, 2 # stack valid?
120 addu t1, t0 # end address
122 bltz t0, bad_stack # -> sp is bad
124 lw t0, PT_R29(sp) # get old user stack pointer
125 PTR_LA t1, 4f # copy 1 to 3 arguments
130 /* Ok, copy the args from the luser stack to the kernel stack */
132 * I know Ralf doesn't like nops but this avoids code
133 * duplication for R3000 targets (and this is the
134 * only place where ".set reorder" doesn't help).
140 1: lw t1, 24(t0) # argument #7 from usp
144 2: lw t1, 20(t0) # argument #5 from usp
148 3: lw t1, 16(t0) # argument #5 from usp
154 j stack_done # go back
156 .section __ex_table,"a"
163 * The stackpointer for a call with more than 4 arguments is bad.
164 * We probably should handle this case a bit more drastic.
170 li t0, 1 # set error flag
175 * The system call does not exist in this kernel
178 li v0, ENOSYS # error
180 li t0, 1 # set error flag
185 LEAF(mips_atomic_set)
186 andi v0, a1, 3 # must be word aligned
187 bnez v0, bad_alignment
189 lw v1, TI_ADDR_LIMIT($28) # in legal address range?
195 #ifdef CONFIG_CPU_HAS_LLSC
196 /* Ok, this is the ll/sc case. World is sane :-) */
202 .section __ex_table,"a"
219 * At this point the page should be readable and writable unless
220 * there was no more memory available.
225 .section __ex_table,"a"
231 sw zero, PT_R7(sp) # success
232 sw v0, PT_R2(sp) # result
234 /* Success, so skip usual error handling garbage. */
235 LONG_L a2, TI_FLAGS($28) # syscall tracing enabled?
236 li t0, _TIF_SYSCALL_TRACE
246 no_mem: li v0, -ENOMEM
259 beq a0, MIPS_ATOMIC_SET, mips_atomic_set
264 lw t0, PT_R29(sp) # user sp
266 sltu v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
271 lw t2, sys_call_table(v0) # function pointer
272 lbu t4, sys_narg_table(a0) # number of arguments
275 beq t2, v1, out # do not recurse
277 beqz t2, enosys # null function pointer?
279 andi v0, t0, 0x3 # unaligned stack pointer?
282 addu v0, t0, 16 # v0 = usp + 16
283 addu t1, v0, 12 # 3 32-bit arguments
284 lw v1, TI_ADDR_LIMIT($28)
289 move a0, a1 # shift argument registers
297 .section __ex_table, "a"
303 sw t3, 16(sp) # put into new stackframe
306 bnez t4, 1f # zero arguments?
307 addu a0, sp, 32 # then pass sp in a0
315 enosys: li v0, -ENOSYS
324 efault: li v0, -EFAULT
329 .macro fifty ptr, nargs, from=1, to=50
332 fifty \ptr,\nargs,"(\from+1)",\to
336 .macro mille ptr, nargs, from=1, to=20
339 mille \ptr,\nargs,"(\from+1)",\to
344 mille sys_ni_syscall 0 /* 0 - 999 SVR4 flavour */
345 #include "irix5sys.h" /* 1000 - 1999 32-bit IRIX */
346 mille sys_ni_syscall 0 /* 2000 - 2999 BSD43 flavour */
347 mille sys_ni_syscall 0 /* 3000 - 3999 POSIX flavour */
349 sys sys_syscall 0 /* 4000 */
354 sys sys_open 3 /* 4005 */
359 sys sys_unlink 1 /* 4010 */
364 sys sys_chmod 2 /* 4015 */
367 sys sys_ni_syscall 0 /* was sys_stat */
369 sys sys_getpid 0 /* 4020 */
374 sys sys_stime 1 /* 4025 */
377 sys sys_ni_syscall 0 /* was sys_fstat */
379 sys sys_utime 2 /* 4030 */
384 sys sys_ni_syscall 0 /* 4035 */
389 sys sys_rmdir 1 /* 4040 */
394 sys sys_brk 1 /* 4045 */
397 sys sys_ni_syscall 0 /* was signal(2) */
399 sys sys_getegid 0 /* 4050 */
404 sys sys_fcntl 3 /* 4055 */
409 sys sys_umask 1 /* 4060 */
414 sys sys_getpgrp 0 /* 4065 */
419 sys sys_setreuid 2 /* 4070 */
423 sys sys_sethostname 2
424 sys sys_setrlimit 2 /* 4075 */
427 sys sys_gettimeofday 2
428 sys sys_settimeofday 2
429 sys sys_getgroups 2 /* 4080 */
431 sys sys_ni_syscall 0 /* old_select */
433 sys sys_ni_syscall 0 /* was sys_lstat */
434 sys sys_readlink 3 /* 4085 */
439 sys old_mmap 6 /* 4090 */
444 sys sys_fchown 3 /* 4095 */
445 sys sys_getpriority 2
446 sys sys_setpriority 3
449 sys sys_fstatfs 2 /* 4100 */
450 sys sys_ni_syscall 0 /* was ioperm(2) */
454 sys sys_getitimer 2 /* 4105 */
459 sys sys_ni_syscall 0 /* 4110 was iopl(2) */
461 sys sys_ni_syscall 0 /* was sys_idle() */
462 sys sys_ni_syscall 0 /* was sys_vm86 */
464 sys sys_swapoff 1 /* 4115 */
469 sys sys_clone 0 /* 4120 */
470 sys sys_setdomainname 2
472 sys sys_ni_syscall 0 /* sys_modify_ldt */
474 sys sys_mprotect 3 /* 4125 */
475 sys sys_sigprocmask 3
476 sys sys_ni_syscall 0 /* was create_module */
477 sys sys_init_module 5
478 sys sys_delete_module 1
479 sys sys_ni_syscall 0 /* 4130 was get_kernel_syms */
484 sys sys_sysfs 3 /* 4135 */
485 sys sys_personality 1
486 sys sys_ni_syscall 0 /* for afs_syscall */
489 sys sys_llseek 5 /* 4140 */
494 sys sys_readv 3 /* 4145 */
499 sys sys_ni_syscall 0 /* 4150 */
504 sys sys_munlock 2 /* 4155 */
507 sys sys_sched_setparam 2
508 sys sys_sched_getparam 2
509 sys sys_sched_setscheduler 3 /* 4160 */
510 sys sys_sched_getscheduler 1
511 sys sys_sched_yield 0
512 sys sys_sched_get_priority_max 1
513 sys sys_sched_get_priority_min 1
514 sys sys_sched_rr_get_interval 2 /* 4165 */
519 sys sys_connect 3 /* 4170 */
520 sys sys_getpeername 3
521 sys sys_getsockname 3
524 sys sys_recv 4 /* 4175 */
529 sys sys_sendto 6 /* 4180 */
534 sys sys_setresuid 3 /* 4185 */
536 sys sys_ni_syscall 0 /* was sys_query_module */
539 sys sys_setresgid 3 /* 4190 */
542 sys sys_rt_sigreturn 0
543 sys sys_rt_sigaction 4
544 sys sys_rt_sigprocmask 4 /* 4195 */
545 sys sys_rt_sigpending 2
546 sys sys_rt_sigtimedwait 4
547 sys sys_rt_sigqueueinfo 3
548 sys sys_rt_sigsuspend 0
549 sys sys_pread64 6 /* 4200 */
554 sys sys_capset 2 /* 4205 */
555 sys sys_sigaltstack 0
559 sys sys_mmap2 6 /* 4210 */
561 sys sys_ftruncate64 4
564 sys sys_fstat64 2 /* 4215 */
569 sys sys_fcntl64 3 /* 4220 */
574 sys sys_lsetxattr 5 /* 4225 */
579 sys sys_listxattr 3 /* 4230 */
582 sys sys_removexattr 2
583 sys sys_lremovexattr 2
584 sys sys_fremovexattr 2 /* 4235 */
588 sys sys_sched_setaffinity 3
589 sys sys_sched_getaffinity 3 /* 4240 */
592 sys sys_io_getevents 5
594 sys sys_io_cancel 3 /* 4245 */
596 sys sys_lookup_dcookie 3
597 sys sys_epoll_create 1
599 sys sys_epoll_wait 3 /* 4250 */
600 sys sys_remap_file_pages 5
601 sys sys_set_tid_address 1
602 sys sys_restart_syscall 0
603 sys sys_fadvise64_64 7
604 sys sys_statfs64 3 /* 4255 */
606 sys sys_timer_create 3
607 sys sys_timer_settime 4
608 sys sys_timer_gettime 2
609 sys sys_timer_getoverrun 1 /* 4260 */
610 sys sys_timer_delete 1
611 sys sys_clock_settime 2
612 sys sys_clock_gettime 2
613 sys sys_clock_getres 2
614 sys sys_clock_nanosleep 4 /* 4265 */
620 .macro sys function, nargs
627 .size sys_call_table, . - sys_call_table
629 .macro sys function, nargs
635 .size sys_narg_table, . - sys_narg_table