xref: /netbsd-src/sys/arch/sh3/sh3/syscall.c (revision 91bfaeb6759937927739ef3693f1c0059f6796f8)
1 /*	$NetBSD: syscall.c,v 1.16 2019/04/06 03:06:27 thorpej Exp $	*/
2 
3 /*-
4  * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
5  * Copyright (c) 1990 The Regents of the University of California.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the University of Utah, and William Jolitz.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)trap.c	7.4 (Berkeley) 5/13/91
36  */
37 
38 /*-
39  * Copyright (c) 1995 Charles M. Hannum.  All rights reserved.
40  *
41  * This code is derived from software contributed to Berkeley by
42  * the University of Utah, and William Jolitz.
43  *
44  * Redistribution and use in source and binary forms, with or without
45  * modification, are permitted provided that the following conditions
46  * are met:
47  * 1. Redistributions of source code must retain the above copyright
48  *    notice, this list of conditions and the following disclaimer.
49  * 2. Redistributions in binary form must reproduce the above copyright
50  *    notice, this list of conditions and the following disclaimer in the
51  *    documentation and/or other materials provided with the distribution.
52  * 3. All advertising materials mentioning features or use of this software
53  *    must display the following acknowledgement:
54  *	This product includes software developed by the University of
55  *	California, Berkeley and its contributors.
56  * 4. Neither the name of the University nor the names of its contributors
57  *    may be used to endorse or promote products derived from this software
58  *    without specific prior written permission.
59  *
60  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
61  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
62  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
63  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
64  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
65  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
66  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70  * SUCH DAMAGE.
71  *
72  *	@(#)trap.c	7.4 (Berkeley) 5/13/91
73  */
74 
75 /*
76  * SH3 Trap and System call handling
77  *
78  * T.Horiuchi 1998.06.8
79  */
80 
81 #include <sys/param.h>
82 #include <sys/systm.h>
83 #include <sys/proc.h>
84 #include <sys/syscall.h>
85 #include <sys/syscallvar.h>
86 
87 #include <sh3/userret.h>
88 
89 #include <uvm/uvm_extern.h>
90 
91 static void syscall(struct lwp *, struct trapframe *);
92 
93 void
syscall_intern(struct proc * p)94 syscall_intern(struct proc *p)
95 {
96 
97 	p->p_trace_enabled = trace_is_enabled(p);
98 	p->p_md.md_syscall = syscall;
99 }
100 
101 
102 /*
103  * System call request from POSIX system call gate interface to kernel.
104  *	l  ... curlwp when trap occurs.
105  *	tf ... full user context.
106  */
107 static void
syscall(struct lwp * l,struct trapframe * tf)108 syscall(struct lwp *l, struct trapframe *tf)
109 {
110 	struct proc *p = l->l_proc;
111 	void *params;
112 	const struct sysent *callp;
113 	int error, opc, nsys;
114 	size_t argsize;
115 	register_t code, args[8], rval[2], ocode;
116 
117 	curcpu()->ci_data.cpu_nsyscall++;
118 
119 	opc = tf->tf_spc;
120 	ocode = code = tf->tf_r0;
121 
122 	nsys = p->p_emul->e_nsysent;
123 	callp = p->p_emul->e_sysent;
124 	params = (void *)tf->tf_r15;
125 
126 	switch (code) {
127 	case SYS_syscall:
128 		/*
129 		 * Code is first argument, followed by actual args.
130 		 */
131 	        code = tf->tf_r4;  /* ufetch_int(params); */
132 		/* params += sizeof(int); */
133 		break;
134 	case SYS___syscall:
135 		/*
136 		 * Like syscall, but code is a quad, so as to maintain
137 		 * quad alignment for the rest of the arguments.
138 		 */
139 		if (callp != sysent)
140 			break;
141 		/* ufetch_int(params + _QUAD_LOWWORD * sizeof(int)); */
142 #if _BYTE_ORDER == BIG_ENDIAN
143 		code = tf->tf_r5;
144 #else
145 		code = tf->tf_r4;
146 #endif
147 		/* params += sizeof(quad_t); */
148 		break;
149 	default:
150 		break;
151 	}
152 	if (code < 0 || code >= nsys)
153 		callp += p->p_emul->e_nosys;		/* illegal */
154 	else
155 		callp += code;
156 	argsize = callp->sy_argsize;
157 
158 	if (ocode == SYS_syscall) {
159 		if (argsize) {
160 			args[0] = tf->tf_r5;
161 			args[1] = tf->tf_r6;
162 			args[2] = tf->tf_r7;
163 			if (argsize > 3 * sizeof(int)) {
164 				argsize -= 3 * sizeof(int);
165 				error = copyin(params, (void *)&args[3],
166 					       argsize);
167 			} else
168 				error = 0;
169 		} else
170 			error = 0;
171 	}
172 	else if (ocode == SYS___syscall) {
173 		if (argsize) {
174 			args[0] = tf->tf_r6;
175 			args[1] = tf->tf_r7;
176 			if (argsize > 2 * sizeof(int)) {
177 				argsize -= 2 * sizeof(int);
178 				error = copyin(params, (void *)&args[2],
179 					       argsize);
180 			} else
181 				error = 0;
182 		} else
183 			error = 0;
184 	} else {
185 		if (argsize) {
186 			args[0] = tf->tf_r4;
187 			args[1] = tf->tf_r5;
188 			args[2] = tf->tf_r6;
189 			args[3] = tf->tf_r7;
190 			if (argsize > 4 * sizeof(int)) {
191 				argsize -= 4 * sizeof(int);
192 				error = copyin(params, (void *)&args[4],
193 					       argsize);
194 			} else
195 				error = 0;
196 		} else
197 			error = 0;
198 	}
199 
200 	if (error)
201 		goto bad;
202 
203 	rval[0] = 0;
204 	rval[1] = tf->tf_r1;
205 	error = sy_invoke(callp, l, args, rval, code);
206 
207 	switch (error) {
208 	case 0:
209 		tf->tf_r0 = rval[0];
210 		tf->tf_r1 = rval[1];
211 		tf->tf_ssr |= PSL_TBIT;	/* T bit */
212 
213 		break;
214 	case ERESTART:
215 		/* 2 = TRAPA instruction size */
216 		tf->tf_spc = opc - 2;
217 
218 		break;
219 	case EJUSTRETURN:
220 		/* nothing to do */
221 		break;
222 	default:
223 	bad:
224 		if (p->p_emul->e_errno)
225 			error = p->p_emul->e_errno[error];
226 		tf->tf_r0 = error;
227 		tf->tf_ssr &= ~PSL_TBIT;	/* T bit */
228 
229 		break;
230 	}
231 
232 	userret(l);
233 }
234 
235