kbuild: mips use generic asm-offsets.h support
[linux-2.6] / arch / mips / kernel / scall32-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, 96, 97, 98, 99, 2000, 01, 02 by Ralf Baechle
7  * Copyright (C) 2001 MIPS Technologies, Inc.
8  * Copyright (C) 2004 Thiemo Seufer
9  */
10 #include <linux/config.h>
11 #include <linux/errno.h>
12 #include <asm/asm.h>
13 #include <asm/asmmacro.h>
14 #include <asm/mipsregs.h>
15 #include <asm/regdef.h>
16 #include <asm/stackframe.h>
17 #include <asm/isadep.h>
18 #include <asm/sysmips.h>
19 #include <asm/thread_info.h>
20 #include <asm/unistd.h>
21 #include <asm/war.h>
22 #include <asm/asm-offsets.h>
23
24 /* Highest syscall used of any syscall flavour */
25 #define MAX_SYSCALL_NO  __NR_O32_Linux + __NR_O32_Linux_syscalls
26
27         .align  5
28 NESTED(handle_sys, PT_SIZE, sp)
29         .set    noat
30         SAVE_SOME
31         STI
32         .set    at
33
34         lw      t1, PT_EPC(sp)          # skip syscall on return
35
36 #if defined(CONFIG_BINFMT_IRIX)
37         sltiu   t0, v0, MAX_SYSCALL_NO + 1 # check syscall number
38 #else
39         subu    v0, v0, __NR_O32_Linux  # check syscall number
40         sltiu   t0, v0, __NR_O32_Linux_syscalls + 1
41 #endif
42         addiu   t1, 4                   # skip to next instruction
43         sw      t1, PT_EPC(sp)
44         beqz    t0, illegal_syscall
45
46         sll     t0, v0, 3
47         la      t1, sys_call_table
48         addu    t1, t0
49         lw      t2, (t1)                # syscall routine
50         lw      t3, 4(t1)               # >= 0 if we need stack arguments
51         beqz    t2, illegal_syscall
52
53         sw      a3, PT_R26(sp)          # save a3 for syscall restarting
54         bgez    t3, stackargs
55
56 stack_done:
57         lw      t0, TI_FLAGS($28)       # syscall tracing enabled?
58         li      t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
59         and     t0, t1
60         bnez    t0, syscall_trace_entry # -> yes
61
62         jalr    t2                      # Do The Real Thing (TM)
63
64         li      t0, -EMAXERRNO - 1      # error?
65         sltu    t0, t0, v0
66         sw      t0, PT_R7(sp)           # set error flag
67         beqz    t0, 1f
68
69         negu    v0                      # error
70         sw      v0, PT_R0(sp)           # set flag for syscall
71                                         # restarting
72 1:      sw      v0, PT_R2(sp)           # result
73
74 o32_syscall_exit:
75         local_irq_disable               # make sure need_resched and
76                                         # signals dont change between
77                                         # sampling and return
78         lw      a2, TI_FLAGS($28)       # current->work
79         li      t0, _TIF_ALLWORK_MASK
80         and     t0, a2
81         bnez    t0, o32_syscall_exit_work
82
83         j       restore_partial
84
85 o32_syscall_exit_work:
86         j       syscall_exit_work_partial
87
88 /* ------------------------------------------------------------------------ */
89
90 syscall_trace_entry:
91         SAVE_STATIC
92         move    s0, t2
93         move    a0, sp
94         li      a1, 0
95         jal     do_syscall_trace
96
97         lw      a0, PT_R4(sp)           # Restore argument registers
98         lw      a1, PT_R5(sp)
99         lw      a2, PT_R6(sp)
100         lw      a3, PT_R7(sp)
101         jalr    s0
102
103         li      t0, -EMAXERRNO - 1      # error?
104         sltu    t0, t0, v0
105         sw      t0, PT_R7(sp)           # set error flag
106         beqz    t0, 1f
107
108         negu    v0                      # error
109         sw      v0, PT_R0(sp)           # set flag for syscall
110                                         # restarting
111 1:      sw      v0, PT_R2(sp)           # result
112
113         j       syscall_exit
114
115 /* ------------------------------------------------------------------------ */
116
117         /*
118          * More than four arguments.  Try to deal with it by copying the
119          * stack arguments from the user stack to the kernel stack.
120          * This Sucks (TM).
121          */
122 stackargs:
123         lw      t0, PT_R29(sp)          # get old user stack pointer
124
125         /*
126          * We intentionally keep the kernel stack a little below the top of
127          * userspace so we don't have to do a slower byte accurate check here.
128          */
129         lw      t5, TI_ADDR_LIMIT($28)
130         addu    t4, t0, 32
131         and     t5, t4
132         bltz    t5, bad_stack           # -> sp is bad
133
134         /* Ok, copy the args from the luser stack to the kernel stack.
135          * t3 is the precomputed number of instruction bytes needed to
136          * load or store arguments 6-8.
137          */
138
139         la      t1, 5f                  # load up to 3 arguments
140         subu    t1, t3
141 1:      lw      t5, 16(t0)              # argument #5 from usp
142         .set    push
143         .set    noreorder
144         .set    nomacro
145         jr      t1
146          addiu  t1, 6f - 5f
147
148 2:      lw      t8, 28(t0)              # argument #8 from usp
149 3:      lw      t7, 24(t0)              # argument #7 from usp
150 4:      lw      t6, 20(t0)              # argument #6 from usp
151 5:      jr      t1
152          sw     t5, 16(sp)              # argument #5 to ksp
153
154         sw      t8, 28(sp)              # argument #8 to ksp
155         sw      t7, 24(sp)              # argument #7 to ksp
156         sw      t6, 20(sp)              # argument #6 to ksp
157 6:      j       stack_done              # go back
158          nop
159         .set    pop
160
161         .section __ex_table,"a"
162         PTR     1b,bad_stack
163         PTR     2b,bad_stack
164         PTR     3b,bad_stack
165         PTR     4b,bad_stack
166         .previous
167
168         /*
169          * The stackpointer for a call with more than 4 arguments is bad.
170          * We probably should handle this case a bit more drastic.
171          */
172 bad_stack:
173         negu    v0                              # error
174         sw      v0, PT_R0(sp)
175         sw      v0, PT_R2(sp)
176         li      t0, 1                           # set error flag
177         sw      t0, PT_R7(sp)
178         j       o32_syscall_exit
179
180         /*
181          * The system call does not exist in this kernel
182          */
183 illegal_syscall:
184         li      v0, -ENOSYS                     # error
185         sw      v0, PT_R2(sp)
186         li      t0, 1                           # set error flag
187         sw      t0, PT_R7(sp)
188         j       o32_syscall_exit
189         END(handle_sys)
190
191         LEAF(mips_atomic_set)
192         andi    v0, a1, 3                       # must be word aligned
193         bnez    v0, bad_alignment
194
195         lw      v1, TI_ADDR_LIMIT($28)          # in legal address range?
196         addiu   a0, a1, 4
197         or      a0, a0, a1
198         and     a0, a0, v1
199         bltz    a0, bad_address
200
201 #ifdef CONFIG_CPU_HAS_LLSC
202         /* Ok, this is the ll/sc case.  World is sane :-)  */
203 1:      ll      v0, (a1)
204         move    a0, a2
205 2:      sc      a0, (a1)
206 #if R10000_LLSC_WAR
207         beqzl   a0, 1b
208 #else
209         beqz    a0, 1b
210 #endif
211
212         .section __ex_table,"a"
213         PTR     1b, bad_stack
214         PTR     2b, bad_stack
215         .previous
216 #else
217         sw      a1, 16(sp)
218         sw      a2, 20(sp)
219
220         move    a0, sp
221         move    a2, a1
222         li      a1, 1
223         jal     do_page_fault
224
225         lw      a1, 16(sp)
226         lw      a2, 20(sp)
227
228         /*
229          * At this point the page should be readable and writable unless
230          * there was no more memory available.
231          */
232 1:      lw      v0, (a1)
233 2:      sw      a2, (a1)
234
235         .section __ex_table,"a"
236         PTR     1b, no_mem
237         PTR     2b, no_mem
238         .previous
239 #endif
240
241         sw      zero, PT_R7(sp)         # success
242         sw      v0, PT_R2(sp)           # result
243
244         /* Success, so skip usual error handling garbage.  */
245         lw      a2, TI_FLAGS($28)       # syscall tracing enabled?
246         li      t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
247         and     t0, a2, t0
248         bnez    t0, 1f
249
250         j       o32_syscall_exit
251
252 1:      SAVE_STATIC
253         move    a0, sp
254         li      a1, 1
255         jal     do_syscall_trace
256         j       syscall_exit
257
258 no_mem: li      v0, -ENOMEM
259         jr      ra
260
261 bad_address:
262         li      v0, -EFAULT
263         jr      ra
264
265 bad_alignment:
266         li      v0, -EINVAL
267         jr      ra
268         END(mips_atomic_set)
269
270         LEAF(sys_sysmips)
271         beq     a0, MIPS_ATOMIC_SET, mips_atomic_set
272         j       _sys_sysmips
273         END(sys_sysmips)
274
275         LEAF(sys_syscall)
276 #if defined(CONFIG_BINFMT_IRIX)
277         sltiu   v0, a0, MAX_SYSCALL_NO + 1 # check syscall number
278 #else
279         subu    t0, a0, __NR_O32_Linux  # check syscall number
280         sltiu   v0, t0, __NR_O32_Linux_syscalls + 1
281 #endif
282         sll     t1, t0, 3
283         beqz    v0, einval
284
285         lw      t2, sys_call_table(t1)          # syscall routine
286
287 #if defined(CONFIG_BINFMT_IRIX)
288         li      v1, 4000                        # nr of sys_syscall
289 #else
290         li      v1, 4000 - __NR_O32_Linux       # index of sys_syscall
291 #endif
292         beq     t0, v1, einval                  # do not recurse
293
294         /* Some syscalls like execve get their arguments from struct pt_regs
295            and claim zero arguments in the syscall table. Thus we have to
296            assume the worst case and shuffle around all potential arguments.
297            If you want performance, don't use indirect syscalls. */
298
299         move    a0, a1                          # shift argument registers
300         move    a1, a2
301         move    a2, a3
302         lw      a3, 16(sp)
303         lw      t4, 20(sp)
304         lw      t5, 24(sp)
305         lw      t6, 28(sp)
306         sw      t4, 16(sp)
307         sw      t5, 20(sp)
308         sw      t6, 24(sp)
309         sw      a0, PT_R4(sp)                   # .. and push back a0 - a3, some
310         sw      a1, PT_R5(sp)                   # syscalls expect them there
311         sw      a2, PT_R6(sp)
312         sw      a3, PT_R7(sp)
313         sw      a3, PT_R26(sp)                  # update a3 for syscall restarting
314         jr      t2
315         /* Unreached */
316
317 einval: li      v0, -EINVAL
318         jr      ra
319         END(sys_syscall)
320
321         .macro  fifty ptr, nargs, from=1, to=50
322         sys     \ptr            \nargs
323         .if     \to-\from
324         fifty   \ptr,\nargs,"(\from+1)",\to
325         .endif
326         .endm
327
328         .macro  mille ptr, nargs, from=1, to=20
329         fifty   \ptr,\nargs
330         .if     \to-\from
331         mille   \ptr,\nargs,"(\from+1)",\to
332         .endif
333         .endm
334
335         .macro  syscalltable
336 #if defined(CONFIG_BINFMT_IRIX)
337         mille   sys_ni_syscall          0       /*    0 -  999 SVR4 flavour */
338         mille   sys_ni_syscall          0       /* 1000 - 1999 32-bit IRIX */
339         mille   sys_ni_syscall          0       /* 2000 - 2999 BSD43 flavour */
340         mille   sys_ni_syscall          0       /* 3000 - 3999 POSIX flavour */
341 #endif
342
343         sys     sys_syscall             8       /* 4000 */
344         sys     sys_exit                1
345         sys     sys_fork                0
346         sys     sys_read                3
347         sys     sys_write               3
348         sys     sys_open                3       /* 4005 */
349         sys     sys_close               1
350         sys     sys_waitpid             3
351         sys     sys_creat               2
352         sys     sys_link                2
353         sys     sys_unlink              1       /* 4010 */
354         sys     sys_execve              0
355         sys     sys_chdir               1
356         sys     sys_time                1
357         sys     sys_mknod               3
358         sys     sys_chmod               2       /* 4015 */
359         sys     sys_lchown              3
360         sys     sys_ni_syscall          0
361         sys     sys_ni_syscall          0       /* was sys_stat */
362         sys     sys_lseek               3
363         sys     sys_getpid              0       /* 4020 */
364         sys     sys_mount               5
365         sys     sys_oldumount           1
366         sys     sys_setuid              1
367         sys     sys_getuid              0
368         sys     sys_stime               1       /* 4025 */
369         sys     sys_ptrace              4
370         sys     sys_alarm               1
371         sys     sys_ni_syscall          0       /* was sys_fstat */
372         sys     sys_pause               0
373         sys     sys_utime               2       /* 4030 */
374         sys     sys_ni_syscall          0
375         sys     sys_ni_syscall          0
376         sys     sys_access              2
377         sys     sys_nice                1
378         sys     sys_ni_syscall          0       /* 4035 */
379         sys     sys_sync                0
380         sys     sys_kill                2
381         sys     sys_rename              2
382         sys     sys_mkdir               2
383         sys     sys_rmdir               1       /* 4040 */
384         sys     sys_dup                 1
385         sys     sys_pipe                0
386         sys     sys_times               1
387         sys     sys_ni_syscall          0
388         sys     sys_brk                 1       /* 4045 */
389         sys     sys_setgid              1
390         sys     sys_getgid              0
391         sys     sys_ni_syscall          0       /* was signal(2) */
392         sys     sys_geteuid             0
393         sys     sys_getegid             0       /* 4050 */
394         sys     sys_acct                1
395         sys     sys_umount              2
396         sys     sys_ni_syscall          0
397         sys     sys_ioctl               3
398         sys     sys_fcntl               3       /* 4055 */
399         sys     sys_ni_syscall          2
400         sys     sys_setpgid             2
401         sys     sys_ni_syscall          0
402         sys     sys_olduname            1
403         sys     sys_umask               1       /* 4060 */
404         sys     sys_chroot              1
405         sys     sys_ustat               2
406         sys     sys_dup2                2
407         sys     sys_getppid             0
408         sys     sys_getpgrp             0       /* 4065 */
409         sys     sys_setsid              0
410         sys     sys_sigaction           3
411         sys     sys_sgetmask            0
412         sys     sys_ssetmask            1
413         sys     sys_setreuid            2       /* 4070 */
414         sys     sys_setregid            2
415         sys     sys_sigsuspend          0
416         sys     sys_sigpending          1
417         sys     sys_sethostname         2
418         sys     sys_setrlimit           2       /* 4075 */
419         sys     sys_getrlimit           2
420         sys     sys_getrusage           2
421         sys     sys_gettimeofday        2
422         sys     sys_settimeofday        2
423         sys     sys_getgroups           2       /* 4080 */
424         sys     sys_setgroups           2
425         sys     sys_ni_syscall          0       /* old_select */
426         sys     sys_symlink             2
427         sys     sys_ni_syscall          0       /* was sys_lstat */
428         sys     sys_readlink            3       /* 4085 */
429         sys     sys_uselib              1
430         sys     sys_swapon              2
431         sys     sys_reboot              3
432         sys     old_readdir             3
433         sys     old_mmap                6       /* 4090 */
434         sys     sys_munmap              2
435         sys     sys_truncate            2
436         sys     sys_ftruncate           2
437         sys     sys_fchmod              2
438         sys     sys_fchown              3       /* 4095 */
439         sys     sys_getpriority         2
440         sys     sys_setpriority         3
441         sys     sys_ni_syscall          0
442         sys     sys_statfs              2
443         sys     sys_fstatfs             2       /* 4100 */
444         sys     sys_ni_syscall          0       /* was ioperm(2) */
445         sys     sys_socketcall          2
446         sys     sys_syslog              3
447         sys     sys_setitimer           3
448         sys     sys_getitimer           2       /* 4105 */
449         sys     sys_newstat             2
450         sys     sys_newlstat            2
451         sys     sys_newfstat            2
452         sys     sys_uname               1
453         sys     sys_ni_syscall          0       /* 4110 was iopl(2) */
454         sys     sys_vhangup             0
455         sys     sys_ni_syscall          0       /* was sys_idle() */
456         sys     sys_ni_syscall          0       /* was sys_vm86 */
457         sys     sys_wait4               4
458         sys     sys_swapoff             1       /* 4115 */
459         sys     sys_sysinfo             1
460         sys     sys_ipc                 6
461         sys     sys_fsync               1
462         sys     sys_sigreturn           0
463         sys     sys_clone               0       /* 4120 */
464         sys     sys_setdomainname       2
465         sys     sys_newuname            1
466         sys     sys_ni_syscall          0       /* sys_modify_ldt */
467         sys     sys_adjtimex            1
468         sys     sys_mprotect            3       /* 4125 */
469         sys     sys_sigprocmask         3
470         sys     sys_ni_syscall          0       /* was create_module */
471         sys     sys_init_module         5
472         sys     sys_delete_module       1
473         sys     sys_ni_syscall          0       /* 4130 was get_kernel_syms */
474         sys     sys_quotactl            4
475         sys     sys_getpgid             1
476         sys     sys_fchdir              1
477         sys     sys_bdflush             2
478         sys     sys_sysfs               3       /* 4135 */
479         sys     sys_personality         1
480         sys     sys_ni_syscall          0       /* for afs_syscall */
481         sys     sys_setfsuid            1
482         sys     sys_setfsgid            1
483         sys     sys_llseek              5       /* 4140 */
484         sys     sys_getdents            3
485         sys     sys_select              5
486         sys     sys_flock               2
487         sys     sys_msync               3
488         sys     sys_readv               3       /* 4145 */
489         sys     sys_writev              3
490         sys     sys_cacheflush          3
491         sys     sys_cachectl            3
492         sys     sys_sysmips             4
493         sys     sys_ni_syscall          0       /* 4150 */
494         sys     sys_getsid              1
495         sys     sys_fdatasync           1
496         sys     sys_sysctl              1
497         sys     sys_mlock               2
498         sys     sys_munlock             2       /* 4155 */
499         sys     sys_mlockall            1
500         sys     sys_munlockall          0
501         sys     sys_sched_setparam      2
502         sys     sys_sched_getparam      2
503         sys     sys_sched_setscheduler  3       /* 4160 */
504         sys     sys_sched_getscheduler  1
505         sys     sys_sched_yield         0
506         sys     sys_sched_get_priority_max 1
507         sys     sys_sched_get_priority_min 1
508         sys     sys_sched_rr_get_interval 2     /* 4165 */
509         sys     sys_nanosleep,          2
510         sys     sys_mremap,             4
511         sys     sys_accept              3
512         sys     sys_bind                3
513         sys     sys_connect             3       /* 4170 */
514         sys     sys_getpeername         3
515         sys     sys_getsockname         3
516         sys     sys_getsockopt          5
517         sys     sys_listen              2
518         sys     sys_recv                4       /* 4175 */
519         sys     sys_recvfrom            6
520         sys     sys_recvmsg             3
521         sys     sys_send                4
522         sys     sys_sendmsg             3
523         sys     sys_sendto              6       /* 4180 */
524         sys     sys_setsockopt          5
525         sys     sys_shutdown            2
526         sys     sys_socket              3
527         sys     sys_socketpair          4
528         sys     sys_setresuid           3       /* 4185 */
529         sys     sys_getresuid           3
530         sys     sys_ni_syscall          0       /* was sys_query_module */
531         sys     sys_poll                3
532         sys     sys_nfsservctl          3
533         sys     sys_setresgid           3       /* 4190 */
534         sys     sys_getresgid           3
535         sys     sys_prctl               5
536         sys     sys_rt_sigreturn        0
537         sys     sys_rt_sigaction        4
538         sys     sys_rt_sigprocmask      4       /* 4195 */
539         sys     sys_rt_sigpending       2
540         sys     sys_rt_sigtimedwait     4
541         sys     sys_rt_sigqueueinfo     3
542         sys     sys_rt_sigsuspend       0
543         sys     sys_pread64             6       /* 4200 */
544         sys     sys_pwrite64            6
545         sys     sys_chown               3
546         sys     sys_getcwd              2
547         sys     sys_capget              2
548         sys     sys_capset              2       /* 4205 */
549         sys     sys_sigaltstack         0
550         sys     sys_sendfile            4
551         sys     sys_ni_syscall          0
552         sys     sys_ni_syscall          0
553         sys     sys_mmap2               6       /* 4210 */
554         sys     sys_truncate64          4
555         sys     sys_ftruncate64         4
556         sys     sys_stat64              2
557         sys     sys_lstat64             2
558         sys     sys_fstat64             2       /* 4215 */
559         sys     sys_pivot_root          2
560         sys     sys_mincore             3
561         sys     sys_madvise             3
562         sys     sys_getdents64          3
563         sys     sys_fcntl64             3       /* 4220 */
564         sys     sys_ni_syscall          0
565         sys     sys_gettid              0
566         sys     sys_readahead           5
567         sys     sys_setxattr            5
568         sys     sys_lsetxattr           5       /* 4225 */
569         sys     sys_fsetxattr           5
570         sys     sys_getxattr            4
571         sys     sys_lgetxattr           4
572         sys     sys_fgetxattr           4
573         sys     sys_listxattr           3       /* 4230 */
574         sys     sys_llistxattr          3
575         sys     sys_flistxattr          3
576         sys     sys_removexattr         2
577         sys     sys_lremovexattr        2
578         sys     sys_fremovexattr        2       /* 4235 */
579         sys     sys_tkill               2
580         sys     sys_sendfile64          5
581         sys     sys_futex               2
582         sys     sys_sched_setaffinity   3
583         sys     sys_sched_getaffinity   3       /* 4240 */
584         sys     sys_io_setup            2
585         sys     sys_io_destroy          1
586         sys     sys_io_getevents        5
587         sys     sys_io_submit           3
588         sys     sys_io_cancel           3       /* 4245 */
589         sys     sys_exit_group          1
590         sys     sys_lookup_dcookie      3
591         sys     sys_epoll_create        1
592         sys     sys_epoll_ctl           4
593         sys     sys_epoll_wait          3       /* 4250 */
594         sys     sys_remap_file_pages    5
595         sys     sys_set_tid_address     1
596         sys     sys_restart_syscall     0
597         sys     sys_fadvise64_64        7
598         sys     sys_statfs64            3       /* 4255 */
599         sys     sys_fstatfs64           2
600         sys     sys_timer_create        3
601         sys     sys_timer_settime       4
602         sys     sys_timer_gettime       2
603         sys     sys_timer_getoverrun    1       /* 4260 */
604         sys     sys_timer_delete        1
605         sys     sys_clock_settime       2
606         sys     sys_clock_gettime       2
607         sys     sys_clock_getres        2
608         sys     sys_clock_nanosleep     4       /* 4265 */
609         sys     sys_tgkill              3
610         sys     sys_utimes              2
611         sys     sys_mbind               4
612         sys     sys_ni_syscall          0       /* sys_get_mempolicy */
613         sys     sys_ni_syscall          0       /* 4270 sys_set_mempolicy */
614         sys     sys_mq_open             4
615         sys     sys_mq_unlink           1
616         sys     sys_mq_timedsend        5
617         sys     sys_mq_timedreceive     5
618         sys     sys_mq_notify           2       /* 4275 */
619         sys     sys_mq_getsetattr       3
620         sys     sys_ni_syscall          0       /* sys_vserver */
621         sys     sys_waitid              4
622         sys     sys_ni_syscall          0       /* available, was setaltroot */
623         sys     sys_add_key             5
624         sys     sys_request_key         4
625         sys     sys_keyctl              5
626
627         .endm
628
629         /* We pre-compute the number of _instruction_ bytes needed to
630            load or store the arguments 6-8. Negative values are ignored. */
631
632         .macro  sys function, nargs
633         PTR     \function
634         LONG    (\nargs << 2) - (5 << 2)
635         .endm
636
637         .align  3
638         .type   sys_call_table,@object
639 EXPORT(sys_call_table)
640         syscalltable
641         .size   sys_call_table, . - sys_call_table