ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / mips / kernel / scall64-o32.S
1 /*
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
4  * for more details.
5  *
6  * Copyright (C) 1995 - 2000, 2001 by Ralf Baechle
7  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8  * Copyright (C) 2001 MIPS Technologies, Inc.
9  *
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
13  * here for now.
14  */
15 #include <linux/config.h>
16 #include <linux/errno.h>
17 #include <asm/asm.h>
18 #include <asm/asmmacro.h>
19 #include <asm/mipsregs.h>
20 #include <asm/regdef.h>
21 #include <asm/stackframe.h>
22 #include <asm/thread_info.h>
23 #include <asm/unistd.h>
24 #include <asm/sysmips.h>
25
26         .align  5
27 NESTED(handle_sys, PT_SIZE, sp)
28         .set    noat
29         SAVE_SOME
30         STI
31         .set    at
32         ld      t1, PT_EPC(sp)          # skip syscall on return
33
34         subu    t0, v0, __NR_O32_Linux  # check syscall number
35         sltiu   t0, t0, __NR_O32_Linux_syscalls + 1
36         daddiu  t1, 4                   # skip to next instruction
37         beqz    t0, not_o32_scall
38         sd      t1, PT_EPC(sp)
39 #if 0
40  SAVE_ALL
41  move a1, v0
42  PRINT("Scall %ld\n")
43  RESTORE_ALL
44 #endif
45
46         sll     a0, a0, 0
47         sll     a1, a1, 0
48         sll     a2, a2, 0
49         sll     a3, a3, 0
50
51         /* XXX Put both in one cacheline, should save a bit. */
52         dsll    t0, v0, 3               # offset into table
53         ld      t2, (sys_call_table - (__NR_O32_Linux * 8))(t0)
54         lbu     t3, (sys_narg_table - __NR_O32_Linux)(v0)
55
56         subu    t0, t3, 5               # 5 or more arguments?
57         sd      a3, PT_R26(sp)          # save a3 for syscall restarting
58         bgez    t0, stackargs
59
60 stack_done:
61         LONG_L  t0, TI_FLAGS($28)
62                                         # syscall tracing enabled?
63         bnez    t0, trace_a_syscall
64
65         jalr    t2                      # Do The Real Thing (TM)
66
67         li      t0, -EMAXERRNO - 1      # error?
68         sltu    t0, t0, v0
69         sd      t0, PT_R7(sp)           # set error flag
70         beqz    t0, 1f
71
72         negu    v0                      # error
73         sd      v0, PT_R0(sp)           # flag for syscall restarting
74 1:      sd      v0, PT_R2(sp)           # result
75
76 FEXPORT(o32_syscall_exit)
77         local_irq_disable               # make need_resched and
78                                         # signals dont change between
79                                         # sampling and return
80         LONG_L  a2, TI_FLAGS($28)
81         li      t0, _TIF_ALLWORK_MASK
82         and     t0, a2, t0
83         bnez    t0, o32_syscall_exit_work
84
85         j       restore_partial
86
87 o32_syscall_exit_work:
88         j       syscall_exit_work_partial
89
90 /* ------------------------------------------------------------------------ */
91
92 trace_a_syscall:
93         SAVE_STATIC
94         sd      a4, PT_R8(sp)
95         sd      a5, PT_R9(sp)
96         sd      a6, PT_R10(sp)
97         sd      a7, PT_R11(sp)
98
99         sd      t2,PT_R1(sp)
100         jal     do_syscall_trace
101         ld      t2,PT_R1(sp)
102
103         ld      a0, PT_R4(sp)           # Restore argument registers
104         ld      a1, PT_R5(sp)
105         ld      a2, PT_R6(sp)
106         ld      a3, PT_R7(sp)
107         ld      a4, PT_R8(sp)
108         ld      a5, PT_R9(sp)
109
110         jalr    t2
111
112         li      t0, -EMAXERRNO - 1      # error?
113         sltu    t0, t0, v0
114         sd      t0, PT_R7(sp)           # set error flag
115         beqz    t0, 1f
116
117         negu    v0                      # error
118         sd      v0, PT_R0(sp)           # set flag for syscall restarting
119 1:      sd      v0, PT_R2(sp)           # result
120
121         j       syscall_exit
122
123 /* ------------------------------------------------------------------------ */
124
125         /*
126          * More than four arguments.  Try to deal with it by copying the
127          * stack arguments from the user stack to the kernel stack.
128          * This Sucks (TM).
129          */
130 stackargs:
131         ld      t0, PT_R29(sp)          # get old user stack pointer
132         subu    t3, 4
133         sll     t1, t3, 2               # stack valid?
134
135         addu    t1, t0                  # end address
136         or      t0, t1
137         bltz    t0, bad_stack           # -> sp is bad
138
139         ld      t0, PT_R29(sp)          # get old user stack pointer
140         PTR_LA  t1, 3f                  # copy 1 to 2 arguments
141         sll     t3, t3, 2
142         subu    t1, t3
143         jr      t1
144
145         /* Ok, copy the args from the luser stack to the kernel stack */
146         .set    push
147         .set    noreorder
148         .set    nomacro
149 1:      lw      a5, 20(t0)              # argument #6 from usp
150 2:      lw      a4, 16(t0)              # argument #5 from usp
151 3:      .set    pop
152
153         j       stack_done              # go back
154
155         .section __ex_table,"a"
156         PTR     1b, bad_stack
157         PTR     2b, bad_stack
158         .previous
159
160         /*
161          * The stackpointer for a call with more than 4 arguments is bad.
162          */
163 bad_stack:
164         negu    v0                      # error
165         sd      v0, PT_R0(sp)
166         sd      v0, PT_R2(sp)
167         li      t0, 1                   # set error flag
168         sd      t0, PT_R7(sp)
169         j       o32_syscall_exit
170
171 not_o32_scall:
172         /*
173          * This is not an o32 compatibility syscall, pass it on
174          * to the 64-bit syscall handlers.
175          */
176 #ifdef CONFIG_MIPS32_N32
177         j       handle_sysn32
178 #else
179         j       handle_sys64
180 #endif
181
182 illegal_syscall:
183         /* This also isn't a 64-bit syscall, throw an error.  */
184         li      v0, ENOSYS              # error
185         sd      v0, PT_R2(sp)
186         li      t0, 1                   # set error flag
187         sd      t0, PT_R7(sp)
188         j       o32_syscall_exit
189         END(handle_sys)
190
191 LEAF(sys32_syscall)
192         ld      t0, PT_R29(sp)          # user sp
193
194         sltu    v0, a0, __NR_O32_Linux + __NR_O32_Linux_syscalls + 1
195         beqz    v0, enosys
196
197         dsll    v0, a0, 3
198         dla     v1, sys32_syscall
199         ld      t2, (sys_call_table - (__NR_O32_Linux * 8))(v0)
200         lbu     t3, (sys_narg_table - __NR_O32_Linux)(a0)
201
202         li      v0, -EINVAL
203         beq     t2, v1, out             # do not recurse
204
205         beqz    t2, enosys              # null function pointer?
206
207         andi    v0, t0, 0x3             # unaligned stack pointer?
208         bnez    v0, sigsegv
209
210         daddiu  v0, t0, 16              # v0 = usp + 16
211         daddu   t1, v0, 12              # 3 32-bit arguments
212         ld      v1, TI_ADDR_LIMIT($28)
213         or      v0, v0, t1
214         and     v1, v1, v0
215         bnez    v1, efault
216
217         move    a0, a1                  # shift argument registers
218         move    a1, a2
219         move    a2, a3
220
221 1:      lw      a3, 16(t0)
222 2:      lw      t3, 20(t0)
223 3:      lw      t1, 24(t0)
224
225         .section __ex_table,"a"
226         PTR     1b, efault
227         PTR     2b, efault
228         PTR     3b, efault
229         .previous
230
231         sw      t3, 16(sp)              # put into new stackframe
232         sw      t1, 20(sp)
233
234         bnez    t1, 1f                  # zero arguments?
235         daddu   a0, sp, 32              # then pass sp in a0
236 1:
237
238         sw      t3, 16(sp)
239         sw      v1, 20(sp)
240         jr      t2
241         /* Unreached */
242
243 enosys: li      v0, -ENOSYS
244         b       out
245
246 sigsegv:
247         li      a0, _SIGSEGV
248         move    a1, $28
249         jal     force_sig
250         /* Fall through */
251
252 efault: li      v0, -EFAULT
253
254 out:    jr      ra
255         END(sys32_syscall)
256
257         .macro  syscalltable
258         sys     sys32_syscall   0                       /* 4000 */
259         sys     sys_exit        1
260         sys     sys_fork        0
261         sys     sys_read        3
262         sys     sys_write       3
263         sys     sys_open        3                       /* 4005 */
264         sys     sys_close       1
265         sys     sys_waitpid     3
266         sys     sys_creat       2
267         sys     sys_link        2
268         sys     sys_unlink      1                       /* 4010 */
269         sys     sys32_execve    0
270         sys     sys_chdir       1
271         sys     sys_time        1
272         sys     sys_mknod       3
273         sys     sys_chmod       2                       /* 4015 */
274         sys     sys_lchown      3
275         sys     sys_ni_syscall  0
276         sys     sys_ni_syscall  0                       /* was sys_stat */
277         sys     sys_lseek       3
278         sys     sys_getpid      0                       /* 4020 */
279         sys     sys_mount       5
280         sys     sys_oldumount   1
281         sys     sys_setuid      1
282         sys     sys_getuid      0
283         sys     sys_stime       1                       /* 4025 */
284         sys     sys32_ptrace    4
285         sys     sys_alarm       1
286         sys     sys_ni_syscall  0                       /* was sys_fstat */
287         sys     sys_pause       0
288         sys     compat_sys_utime        2                       /* 4030 */
289         sys     sys_ni_syscall  0
290         sys     sys_ni_syscall  0
291         sys     sys_access      2
292         sys     sys_nice        1
293         sys     sys_ni_syscall  0                       /* 4035 */
294         sys     sys_sync        0
295         sys     sys_kill        2
296         sys     sys_rename      2
297         sys     sys_mkdir       2
298         sys     sys_rmdir       1                       /* 4040 */
299         sys     sys_dup         1
300         sys     sys_pipe        0
301         sys     compat_sys_times        1
302         sys     sys_ni_syscall  0
303         sys     sys_brk         1                       /* 4045 */
304         sys     sys_setgid      1
305         sys     sys_getgid      0
306         sys     sys_ni_syscall  0       /* was signal   2 */
307         sys     sys_geteuid     0
308         sys     sys_getegid     0                       /* 4050 */
309         sys     sys_acct        0
310         sys     sys_umount      2
311         sys     sys_ni_syscall  0
312         sys     compat_sys_ioctl        3
313         sys     compat_sys_fcntl        3               /* 4055 */
314         sys     sys_ni_syscall  2
315         sys     sys_setpgid     2
316         sys     sys_ni_syscall, 0
317         sys     sys_olduname    1
318         sys     sys_umask       1                       /* 4060 */
319         sys     sys_chroot      1
320         sys     sys32_ustat     2
321         sys     sys_dup2        2
322         sys     sys_getppid     0
323         sys     sys_getpgrp     0                       /* 4065 */
324         sys     sys_setsid      0
325         sys     sys32_sigaction 3
326         sys     sys_sgetmask    0
327         sys     sys_ssetmask    1
328         sys     sys_setreuid    2                       /* 4070 */
329         sys     sys_setregid    2
330         sys     sys32_sigsuspend        0
331         sys     compat_sys_sigpending   1
332         sys     sys_sethostname 2
333         sys     compat_sys_setrlimit    2               /* 4075 */
334         sys     compat_sys_getrlimit    2
335         sys     compat_sys_getrusage    2
336         sys     sys32_gettimeofday 2
337         sys     sys32_settimeofday 2
338         sys     sys_getgroups   2                       /* 4080 */
339         sys     sys_setgroups   2
340         sys     sys_ni_syscall  0                       /* old_select */
341         sys     sys_symlink     2
342         sys     sys_ni_syscall  0                       /* was sys_lstat */
343         sys     sys_readlink    3                       /* 4085 */
344         sys     sys_uselib      1
345         sys     sys_swapon      2
346         sys     sys_reboot      3
347         sys     sys32_readdir   3
348         sys     old_mmap        6                       /* 4090 */
349         sys     sys_munmap      2
350         sys     sys_truncate    2
351         sys     sys_ftruncate   2
352         sys     sys_fchmod      2
353         sys     sys_fchown      3                       /* 4095 */
354         sys     sys_getpriority 2
355         sys     sys_setpriority 3
356         sys     sys_ni_syscall  0
357         sys     compat_sys_statfs       2
358         sys     compat_sys_fstatfs      2               /* 4100 */
359         sys     sys_ni_syscall          0               /* sys_ioperm */
360         sys     sys32_socketcall                2
361         sys     sys_syslog              3
362         sys     compat_sys_setitimer    3
363         sys     compat_sys_getitimer    2       /* 4105 */
364         sys     compat_sys_newstat      2
365         sys     compat_sys_newlstat     2
366         sys     compat_sys_newfstat     2
367         sys     sys_uname               1
368         sys     sys_ni_syscall          0       /* sys_ioperm  *//* 4110 */
369         sys     sys_vhangup             0
370         sys     sys_ni_syscall          0       /* was sys_idle  */
371         sys     sys_ni_syscall          0       /* sys_vm86 */
372         sys     sys32_wait4             4
373         sys     sys_swapoff             1       /* 4115 */
374         sys     sys32_sysinfo           1
375         sys     sys32_ipc               6
376         sys     sys_fsync       1
377         sys     sys32_sigreturn 0
378         sys     sys_clone       0                       /* 4120 */
379         sys     sys_setdomainname 2
380         sys     sys32_newuname  1
381         sys     sys_ni_syscall  0       /* sys_modify_ldt */
382         sys     sys32_adjtimex  1
383         sys     sys_mprotect    3                       /* 4125 */
384         sys     compat_sys_sigprocmask  3
385         sys     sys_ni_syscall  0                       /* was creat_module */
386         sys     sys_init_module 5
387         sys     sys_delete_module 1
388         sys     sys_ni_syscall  0               /* 4130, get_kernel_syms */
389         sys     sys_quotactl    0
390         sys     sys_getpgid     1
391         sys     sys_fchdir      1
392         sys     sys_bdflush     2
393         sys     sys_sysfs       3                       /* 4135 */
394         sys     sys32_personality       1
395         sys     sys_ni_syscall  0 /* for afs_syscall */
396         sys     sys_setfsuid    1
397         sys     sys_setfsgid    1
398         sys     sys32_llseek    5                       /* 4140 */
399         sys     sys32_getdents  3
400         sys     sys32_select    5
401         sys     sys_flock       2
402         sys     sys_msync       3
403         sys     sys32_readv     3                       /* 4145 */
404         sys     sys32_writev    3
405         sys     sys_cacheflush  3
406         sys     sys_cachectl    3
407         sys     sys_sysmips     4
408         sys     sys_ni_syscall  0                       /* 4150 */
409         sys     sys_getsid      1
410         sys     sys_fdatasync   0
411         sys     sys32_sysctl    1
412         sys     sys_mlock       2
413         sys     sys_munlock     2                       /* 4155 */
414         sys     sys_mlockall    1
415         sys     sys_munlockall  0
416         sys     sys_sched_setparam 2
417         sys     sys_sched_getparam 2
418         sys     sys_sched_setscheduler 3                /* 4160 */
419         sys     sys_sched_getscheduler 1
420         sys     sys_sched_yield 0
421         sys     sys_sched_get_priority_max 1
422         sys     sys_sched_get_priority_min 1
423         sys     sys32_sched_rr_get_interval 2           /* 4165 */
424         sys     compat_sys_nanosleep    2
425         sys     sys_mremap      4
426         sys     sys_accept      3
427         sys     sys_bind        3
428         sys     sys_connect     3                       /* 4170 */
429         sys     sys_getpeername 3
430         sys     sys_getsockname 3
431         sys     sys_getsockopt  5
432         sys     sys_listen      2
433         sys     sys_recv        4                       /* 4175 */
434         sys     sys_recvfrom    6
435         sys     compat_sys_recvmsg      3
436         sys     sys_send        4
437         sys     compat_sys_sendmsg      3
438         sys     sys_sendto      6                       /* 4180 */
439         sys     compat_sys_setsockopt   5
440         sys     sys_shutdown    2
441         sys     sys_socket      3
442         sys     sys_socketpair  4
443         sys     sys_setresuid   3                       /* 4185 */
444         sys     sys_getresuid   3
445         sys     sys_ni_syscall  0                       /* was query_module */
446         sys     sys_poll        3
447         sys     sys_nfsservctl  3
448         sys     sys_setresgid   3                       /* 4190 */
449         sys     sys_getresgid   3
450         sys     sys_prctl       5
451         sys     sys32_rt_sigreturn 0
452         sys     sys32_rt_sigaction 4
453         sys     sys32_rt_sigprocmask 4                  /* 4195 */
454         sys     sys32_rt_sigpending 2
455         sys     sys32_rt_sigtimedwait 4
456         sys     sys32_rt_sigqueueinfo 3
457         sys     sys32_rt_sigsuspend 0
458         sys     sys32_pread     6                       /* 4200 */
459         sys     sys32_pwrite    6
460         sys     sys_chown       3
461         sys     sys_getcwd      2
462         sys     sys_capget      2
463         sys     sys_capset      2                       /* 4205 */
464         sys     sys32_sigaltstack       0
465         sys     sys32_sendfile  4
466         sys     sys_ni_syscall  0
467         sys     sys_ni_syscall  0
468         sys     sys32_mmap2     6                       /* 4210 */
469         sys     sys32_truncate64        4
470         sys     sys32_ftruncate64       4
471         sys     sys_newstat     2
472         sys     sys_newlstat    2
473         sys     sys_newfstat    2                       /* 4215 */
474         sys     sys_pivot_root  2
475         sys     sys_mincore     3
476         sys     sys_madvise     3
477         sys     sys_getdents64  3
478         sys     compat_sys_fcntl64      3               /* 4220 */
479         sys     sys_ni_syscall  0
480         sys     sys_gettid      0
481         sys     sys32_readahead 5
482         sys     sys_setxattr    5
483         sys     sys_lsetxattr   5                       /* 4225 */
484         sys     sys_fsetxattr   5
485         sys     sys_getxattr    4
486         sys     sys_lgetxattr   4
487         sys     sys_fgetxattr   4
488         sys     sys_listxattr   3                       /* 4230 */
489         sys     sys_llistxattr  3
490         sys     sys_flistxattr  3
491         sys     sys_removexattr 2
492         sys     sys_lremovexattr        2
493         sys     sys_fremovexattr        2               /* 4235 */
494         sys     sys_tkill               2
495         sys     sys_sendfile64          5
496         sys     compat_sys_futex        5
497         sys     compat_sys_sched_setaffinity    3
498         sys     compat_sys_sched_getaffinity    3       /* 4240 */
499         sys     sys_io_setup            2
500         sys     sys_io_destroy          1
501         sys     sys_io_getevents        5
502         sys     sys_io_submit           3
503         sys     sys_io_cancel           3               /* 4245 */
504         sys     sys_exit_group          1
505         sys     sys_lookup_dcookie      3
506         sys     sys_epoll_create        1
507         sys     sys_epoll_ctl           4
508         sys     sys_epoll_wait          3               /* 4250 */
509         sys     sys_remap_file_pages    5
510         sys     sys_set_tid_address     1
511         sys     sys_restart_syscall     0
512         sys     sys_fadvise64_64        7
513         sys     sys_statfs64            3               /* 4255 */
514         sys     sys_fstatfs64           2
515         sys     sys_timer_create        3
516         sys     sys_timer_settime       4
517         sys     sys_timer_gettime       2
518         sys     sys_timer_getoverrun    1               /* 4260 */
519         sys     sys_timer_delete        1
520         sys     sys_clock_settime       2
521         sys     sys_clock_gettime       2
522         sys     sys_clock_getres        2
523         sys     sys_clock_nanosleep     4               /* 4265 */
524         sys     sys_tgkill              3
525         sys     compat_sys_utimes       2
526
527         .endm
528
529         .macro  sys function, nargs
530         PTR     \function
531         .endm
532
533         .align  3
534 sys_call_table:
535         syscalltable
536
537         .macro  sys function, nargs
538         .byte   \nargs
539         .endm
540
541 sys_narg_table:
542         syscalltable