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 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 * Copyright (C) 2001 MIPS Technologies, Inc.
9 */
10#include <linux/config.h>
11#include <asm/asm.h>
12#include <linux/errno.h>
13#include <asm/current.h>
14#include <asm/mipsregs.h>
15#include <asm/regdef.h>
16#include <asm/stackframe.h>
17#include <asm/unistd.h>
18
19/* This duplicates the definition from <linux/sched.h> */
20#define PT_TRACESYS	0x00000002	/* tracing system calls */
21
22/* This duplicates the definition from <asm/signal.h> */
23#define SIGILL		4		/* Illegal instruction (ANSI).  */
24
25#ifndef CONFIG_MIPS32_O32
26/* No O32, so define handle_sys here */
27#define handle_sysn32 handle_sys
28#endif
29
30	.align  5
31NESTED(handle_sysn32, PT_SIZE, sp)
32#ifndef CONFIG_MIPS32_O32
33	.set	noat
34	SAVE_SOME
35	STI
36	.set	at
37#endif
38
39	subu	t0, v0, __NR_N32_Linux	# check syscall number
40	sltiu	t0, t0,	__NR_N32_Linux_syscalls + 1
41
42#ifndef CONFIG_MIPS32_O32
43	ld	t1, PT_EPC(sp)		# skip syscall on return
44	daddiu	t1, 4			# skip to next instruction
45	sd	t1, PT_EPC(sp)
46#endif
47	beqz	t0, not_n32_scall
48
49	dsll	t0, v0, 3		# offset into table
50	ld	t2, (sysn32_call_table - (__NR_N32_Linux * 8))(t0)
51
52	sd	a3, PT_R26(sp)		# save a3 for syscall restarting
53
54	ld	t0, TASK_PTRACE($28)	# syscall tracing enabled?
55	andi	t0, PT_TRACESYS
56	bnez	t0, trace_a_syscall
57
58	jalr	t2			# Do The Real Thing (TM)
59
60	li	t0, -EMAXERRNO - 1	# error?
61	sltu	t0, t0, v0
62	sd	t0, PT_R7(sp)		# set error flag
63	beqz	t0, 1f
64
65	negu	v0			# error
66	sd	v0, PT_R0(sp)		# set flag for syscall restarting
671:	sd	v0, PT_R2(sp)		# result
68
69ret_from_sys_call:
70	mfc0	t0, CP0_STATUS
71	xori	t0, t0, 1
72	ori	t0, t0, 1
73	mtc0	t0, CP0_STATUS
74
75	ld	t2, TASK_NEED_RESCHED($28)
76	bnez	t2, n32_reschedule
77	lw	v0, TASK_SIGPENDING($28)
78	bnez	v0, signal_return
79
80restore_all:
81	RESTORE_SOME
82	RESTORE_SP
83	eret
84
85/* Put this behind restore_all for the sake of the branch prediction.  */
86signal_return:
87	.type	signal_return, @function
88
89	mfc0	t0, CP0_STATUS
90	ori	t0, t0, 1
91	mtc0	t0, CP0_STATUS
92
93	SAVE_STATIC
94	move	a0, zero
95	move	a1, sp
96	jal	do_signal
97	RESTORE_STATIC
98	b	restore_all
99
100n32_reschedule:
101	SAVE_STATIC
102	jal	schedule
103	b	ret_from_sys_call
104
105/* ------------------------------------------------------------------------ */
106
107trace_a_syscall:
108	SAVE_STATIC
109	sd	t2,PT_R1(sp)
110	jal	syscall_trace
111	ld	t2,PT_R1(sp)
112
113	ld	a0, PT_R4(sp)		# Restore argument registers
114	ld	a1, PT_R5(sp)
115	ld	a2, PT_R6(sp)
116	ld	a3, PT_R7(sp)
117	jalr	t2
118
119	li	t0, -EMAXERRNO - 1	# error?
120	sltu	t0, t0, v0
121	sd	t0, PT_R7(sp)		# set error flag
122	beqz	t0, 1f
123
124	negu	v0			# error
125	sd	v0, PT_R0(sp)		# set flag for syscall restarting
1261:	sd	v0, PT_R2(sp)		# result
127
128	jal	syscall_trace
129	j	ret_from_sys_call
130
131not_n32_scall:
132	/* This is not an n32 compatibility syscall, pass it on to
133	   the n64 syscall handlers.  */
134	j	handle_sys64
135
136	END(handle_sysn32)
137
138EXPORT(sysn32_call_table)
139	PTR	sys_read			/* 6000 */
140	PTR	sys_write
141	PTR	sys_open
142	PTR	sys_close
143	PTR	sys_newstat
144	PTR	sys_newfstat			/* 6005 */
145	PTR	sys_newlstat
146	PTR	sys_poll
147	PTR	sys_lseek
148	PTR	sys_mmap
149	PTR	sys_mprotect			/* 6010 */
150	PTR	sys_munmap
151	PTR	sys_brk
152	PTR	sys32_rt_sigaction
153	PTR	sys32_rt_sigprocmask
154	PTR	sys32_ioctl			/* 6015 */
155	PTR	sys_pread
156	PTR	sys_pwrite
157	PTR	sys32_readv
158	PTR	sys32_writev
159	PTR	sys_access			/* 6020 */
160	PTR	sys_pipe
161	PTR	sys32_select
162	PTR	sys_sched_yield
163	PTR	sys_mremap
164	PTR	sys_msync			/* 6025 */
165	PTR	sys_mincore
166	PTR	sys_madvise
167	PTR	sys_shmget
168	PTR	sys_shmat
169	PTR	sys_shmctl			/* 6030 */
170	PTR	sys_dup
171	PTR	sys_dup2
172	PTR	sys_pause
173	PTR	sys32_nanosleep
174	PTR	sys32_getitimer			/* 6035 */
175	PTR	sys32_setitimer
176	PTR	sys_alarm
177	PTR	sys_getpid
178	PTR	sys32_sendfile
179	PTR	sys_socket			/* 6040 */
180	PTR	sys_connect
181	PTR	sys_accept
182	PTR	sys_sendto
183	PTR	sys_recvfrom
184	PTR	sys32_sendmsg			/* 6045 */
185	PTR	sys32_recvmsg
186	PTR	sys_shutdown
187	PTR	sys_bind
188	PTR	sys_listen
189	PTR	sys_getsockname			/* 6050 */
190	PTR	sys_getpeername
191	PTR	sys_socketpair
192	PTR	sys32_setsockopt
193	PTR	sys_getsockopt
194	PTR	sys_clone			/* 6055 */
195	PTR	sys_fork
196	PTR	sys32_execve
197	PTR	sys_exit
198	PTR	sys32_wait4
199	PTR	sys_kill			/* 6060 */
200	PTR	sys32_newuname
201	PTR	sys_semget
202	PTR	sys_semop
203	PTR	sys_semctl
204	PTR	sys_shmdt			/* 6065 */
205	PTR	sys_msgget
206	PTR	sys_msgsnd
207	PTR	sys_msgrcv
208	PTR	sys_msgctl
209	PTR	sys32_fcntl			/* 6070 */
210	PTR	sys_flock
211	PTR	sys_fsync
212	PTR	sys_fdatasync
213	PTR	sys_truncate
214	PTR	sys_ftruncate			/* 6075 */
215	PTR	sys32_getdents
216	PTR	sys_getcwd
217	PTR	sys_chdir
218	PTR	sys_fchdir
219	PTR	sys_rename			/* 6080 */
220	PTR	sys_mkdir
221	PTR	sys_rmdir
222	PTR	sys_creat
223	PTR	sys_link
224	PTR	sys_unlink			/* 6085 */
225	PTR	sys_symlink
226	PTR	sys_readlink
227	PTR	sys_chmod
228	PTR	sys_fchmod
229	PTR	sys_chown			/* 6090 */
230	PTR	sys_fchown
231	PTR	sys_lchown
232	PTR	sys_umask
233	PTR	sys32_gettimeofday
234	PTR	sys32_getrlimit			/* 6095 */
235	PTR	sys32_getrusage
236	PTR	sys32_sysinfo
237	PTR	sys32_times
238	PTR	sys_ptrace
239	PTR	sys_getuid			/* 6100 */
240	PTR	sys_syslog
241	PTR	sys_getgid
242	PTR	sys_setuid
243	PTR	sys_setgid
244	PTR	sys_geteuid			/* 6105 */
245	PTR	sys_getegid
246	PTR	sys_setpgid
247	PTR	sys_getppid
248	PTR	sys_getpgrp
249	PTR	sys_setsid			/* 6110 */
250	PTR	sys_setreuid
251	PTR	sys_setregid
252	PTR	sys_getgroups
253	PTR	sys_setgroups
254	PTR	sys_setresuid			/* 6115 */
255	PTR	sys_getresuid
256	PTR	sys_setresgid
257	PTR	sys_getresgid
258	PTR	sys_getpgid
259	PTR	sys_setfsuid			/* 6120 */
260	PTR	sys_setfsgid
261	PTR	sys_getsid
262	PTR	sys_capget
263	PTR	sys_capset
264	PTR	sys32_rt_sigpending		/* 6125 */
265	PTR	sys32_rt_sigtimedwait
266	PTR	sys32_rt_sigqueueinfo
267	PTR	sys32_rt_sigsuspend
268	PTR	sys32_sigaltstack
269	PTR	sys32_utime			/* 6130 */
270	PTR	sys_mknod
271	PTR	sys32_personality
272	PTR	sys_ustat
273	PTR	sys32_statfs
274	PTR	sys32_fstatfs			/* 6135 */
275	PTR	sys_sysfs
276	PTR	sys_getpriority
277	PTR	sys_setpriority
278	PTR	sys_sched_setparam
279	PTR	sys_sched_getparam		/* 6140 */
280	PTR	sys_sched_setscheduler
281	PTR	sys_sched_getscheduler
282	PTR	sys_sched_get_priority_max
283	PTR	sys_sched_get_priority_min
284	PTR	sys32_sched_rr_get_interval	/* 6145 */
285	PTR	sys_mlock
286	PTR	sys_munlock
287	PTR	sys_mlockall
288	PTR	sys_munlockall
289	PTR	sys_vhangup			/* 6150 */
290	PTR	sys_pivot_root
291	PTR	sys32_sysctl
292	PTR	sys_prctl
293	PTR	sys32_adjtimex
294	PTR	sys32_setrlimit			/* 6155 */
295	PTR	sys_chroot
296	PTR	sys_sync
297	PTR	sys_acct
298	PTR	sys32_settimeofday
299	PTR	sys_mount			/* 6160 */
300	PTR	sys_umount
301	PTR	sys_swapon
302	PTR	sys_swapoff
303	PTR	sys_reboot
304	PTR	sys_sethostname			/* 6165 */
305	PTR	sys_setdomainname
306	PTR	sys32_create_module
307	PTR	sys32_init_module
308	PTR	sys32_delete_module
309	PTR	sys32_get_kernel_syms		/* 6170 */
310	PTR	sys32_query_module
311	PTR	sys_quotactl
312	PTR	sys_nfsservctl
313	PTR	sys_ni_syscall			/* res. for getpmsg */
314	PTR	sys_ni_syscall			/* 6175  for putpmsg */
315	PTR	sys_ni_syscall			/* res. for afs_syscall */
316	PTR	sys_ni_syscall			/* res. for security */
317	PTR	sys_gettid
318	PTR	sys32_readahead
319	PTR	sys_setxattr			/* 6180 */
320	PTR	sys_lsetxattr
321	PTR	sys_fsetxattr
322	PTR	sys_getxattr
323	PTR	sys_lgetxattr
324	PTR	sys_fgetxattr			/* 6185 */
325	PTR	sys_listxattr
326	PTR	sys_llistxattr
327	PTR	sys_flistxattr
328	PTR	sys_removexattr
329	PTR	sys_lremovexattr		/* 6190 */
330	PTR	sys_fremovexattr
331	PTR	sys_tkill
332	PTR	sys_ni_syscall
333	PTR	sys_ni_syscall			/* res. for futex */
334	PTR	sys_ni_syscall			/* 6195 rs. sched_setaffinity */
335	PTR	sys_ni_syscall			/* res. f. sched_getaffinity */
336	PTR	sys_cacheflush
337	PTR	sys_cachectl
338	PTR	sys_sysmips
339	PTR	sys_ni_syscall			/* 6200 */
340	PTR	sys_ni_syscall
341	PTR	sys_ni_syscall
342	PTR	sys_ni_syscall
343	PTR	sys_ni_syscall
344	PTR	sys_ni_syscall			/* 6205 */
345	PTR	sys_ni_syscall
346	PTR	sys_ni_syscall
347	PTR	sys_ni_syscall
348	PTR	sys_ni_syscall
349	PTR	sys_ni_syscall			/* 6210 */
350	PTR	sysn32_rt_sigreturn
351	PTR	sys_fcntl
352	PTR	sys_ni_syscall
353	PTR	sys_ni_syscall
354	PTR	sys_semtimedop			/* 6215 */
355	PTR	sys_ni_syscall
356	PTR	sys_ni_syscall
357	PTR	sys_ni_syscall
358	PTR	sys_sendfile64
359