1/* $NetBSD: osf1_syscall.c,v 1.33 2010/12/20 00:25:24 matt Exp $ */
2
3/*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, and by Charles M. Hannum.
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 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33/*
34 * Copyright (c) 1999 Christopher G. Demetriou.  All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 *    notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 *    notice, this list of conditions and the following disclaimer in the
43 *    documentation and/or other materials provided with the distribution.
44 * 3. All advertising materials mentioning features or use of this software
45 *    must display the following acknowledgement:
46 *      This product includes software developed by Christopher G. Demetriou
47 *	for the NetBSD Project.
48 * 4. The name of the author may not be used to endorse or promote products
49 *    derived from this software without specific prior written permission
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
52 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
53 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
54 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
55 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
56 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
60 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 */
62
63/*
64 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
65 * All rights reserved.
66 *
67 * Author: Chris G. Demetriou
68 *
69 * Permission to use, copy, modify and distribute this software and
70 * its documentation is hereby granted, provided that both the copyright
71 * notice and this permission notice appear in all copies of the
72 * software, derivative works or modified versions, and any portions
73 * thereof, and that both notices appear in supporting documentation.
74 *
75 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
76 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
77 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
78 *
79 * Carnegie Mellon requests users of this software to return to
80 *
81 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
82 *  School of Computer Science
83 *  Carnegie Mellon University
84 *  Pittsburgh PA 15213-3890
85 *
86 * any improvements or extensions that they make and grant Carnegie the
87 * rights to redistribute these changes.
88 */
89
90#include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
91
92__KERNEL_RCSID(0, "$NetBSD: osf1_syscall.c,v 1.33 2010/12/20 00:25:24 matt Exp $");
93
94#include <sys/param.h>
95#include <sys/systm.h>
96#include <sys/proc.h>
97#include <sys/signal.h>
98#include <sys/syscall.h>
99#include <sys/syscallvar.h>
100
101#include <machine/cpu.h>
102#include <machine/reg.h>
103#include <machine/alpha.h>
104#include <machine/userret.h>
105
106#include <compat/osf1/osf1.h>
107#include <compat/osf1/osf1_cvt.h>
108#include <compat/osf1/osf1_syscall.h>
109
110void	osf1_syscall_intern(struct proc *);
111void	osf1_syscall_plain(struct lwp *, uint64_t, struct trapframe *);
112void	osf1_syscall_fancy(struct lwp *, uint64_t, struct trapframe *);
113
114void
115osf1_syscall_intern(struct proc *p)
116{
117
118	if (trace_is_enabled(p))
119		p->p_md.md_syscall = osf1_syscall_fancy;
120	else
121		p->p_md.md_syscall = osf1_syscall_plain;
122}
123
124/*
125 * Process a system call.
126 *
127 * System calls are strange beasts.  They are passed the syscall number
128 * in v0, and the arguments in the registers (as normal).  They return
129 * an error flag in a3 (if a3 != 0 on return, the syscall had an error),
130 * and the return value (if any) in v0.
131 *
132 * The assembly stub takes care of moving the call number into a register
133 * we can get to, and moves all of the argument registers into their places
134 * in the trap frame.  On return, it restores the callee-saved registers,
135 * a3, and v0 from the frame before returning to the user process.
136 */
137void
138osf1_syscall_plain(struct lwp *l, uint64_t code, struct trapframe *framep)
139{
140	const struct sysent *callp;
141	int error;
142	uint64_t rval[2];
143	uint64_t *args, copyargs[10];				/* XXX */
144	u_int hidden, nargs;
145	struct proc *p = l->l_proc;
146
147	LWP_CACHE_CREDS(l, p);
148
149	curcpu()->ci_data.cpu_nsyscall++;
150	l->l_md.md_tf = framep;
151
152	callp = p->p_emul->e_sysent;
153
154	switch (code) {
155	case OSF1_SYS_syscall:
156		/* OSF/1 syscall() */
157		code = framep->tf_regs[FRAME_A0];
158		hidden = 1;
159		break;
160	default:
161		hidden = 0;
162		break;
163	}
164
165	code &= (OSF1_SYS_NSYSENT - 1);
166	callp += code;
167
168	nargs = callp->sy_narg + hidden;
169	switch (nargs) {
170	default:
171		error = copyin((void *)alpha_pal_rdusp(), &copyargs[6],
172		    (nargs - 6) * sizeof(uint64_t));
173		if (error)
174			goto bad;
175	case 6:
176		copyargs[5] = framep->tf_regs[FRAME_A5];
177	case 5:
178		copyargs[4] = framep->tf_regs[FRAME_A4];
179	case 4:
180		copyargs[3] = framep->tf_regs[FRAME_A3];
181		copyargs[2] = framep->tf_regs[FRAME_A2];
182		copyargs[1] = framep->tf_regs[FRAME_A1];
183		copyargs[0] = framep->tf_regs[FRAME_A0];
184		args = copyargs;
185		break;
186	case 3:
187	case 2:
188	case 1:
189	case 0:
190		args = &framep->tf_regs[FRAME_A0];
191		break;
192	}
193	args += hidden;
194
195	rval[0] = 0;
196	rval[1] = 0;
197	error = sy_call(callp, l, args, rval);
198
199	switch (error) {
200	case 0:
201		framep->tf_regs[FRAME_V0] = rval[0];
202		framep->tf_regs[FRAME_A4] = rval[1];
203		framep->tf_regs[FRAME_A3] = 0;
204		break;
205	case ERESTART:
206		framep->tf_regs[FRAME_PC] -= 4;
207		break;
208	case EJUSTRETURN:
209		break;
210	default:
211	bad:
212		error = native_to_osf1_errno[error];
213		framep->tf_regs[FRAME_V0] = error;
214		framep->tf_regs[FRAME_A3] = 1;
215		break;
216	}
217
218	userret(l);
219}
220
221void
222osf1_syscall_fancy(struct lwp *l, uint64_t code, struct trapframe *framep)
223{
224	const struct sysent *callp;
225	int error;
226	uint64_t rval[2];
227	uint64_t *args, copyargs[10];
228	u_int hidden, nargs;
229	struct proc *p = l->l_proc;
230
231	LWP_CACHE_CREDS(l, p);
232
233	curcpu()->ci_data.cpu_nsyscall++;
234	l->l_md.md_tf = framep;
235
236	callp = p->p_emul->e_sysent;
237
238	switch (code) {
239	case OSF1_SYS_syscall:
240		/* OSF/1 syscall() */
241		code = framep->tf_regs[FRAME_A0];
242		hidden = 1;
243		break;
244	default:
245		hidden = 0;
246		break;
247	}
248
249	code &= (OSF1_SYS_NSYSENT - 1);
250	callp += code;
251
252	nargs = callp->sy_narg + hidden;
253	switch (nargs) {
254	default:
255		error = copyin((void *)alpha_pal_rdusp(), &copyargs[6],
256		    (nargs - 6) * sizeof(uint64_t));
257		if (error) {
258			args = copyargs;
259			goto bad;
260		}
261	case 6:
262		copyargs[5] = framep->tf_regs[FRAME_A5];
263	case 5:
264		copyargs[4] = framep->tf_regs[FRAME_A4];
265	case 4:
266		copyargs[3] = framep->tf_regs[FRAME_A3];
267		copyargs[2] = framep->tf_regs[FRAME_A2];
268		copyargs[1] = framep->tf_regs[FRAME_A1];
269		copyargs[0] = framep->tf_regs[FRAME_A0];
270		args = copyargs;
271		break;
272	case 3:
273	case 2:
274	case 1:
275	case 0:
276		args = &framep->tf_regs[FRAME_A0];
277		break;
278	}
279	args += hidden;
280
281	if ((error = trace_enter(code, args, callp->sy_narg)) != 0)
282		goto out;
283
284	rval[0] = 0;
285	rval[1] = 0;
286	error = sy_call(callp, l, args, rval);
287out:
288	switch (error) {
289	case 0:
290		framep->tf_regs[FRAME_V0] = rval[0];
291		framep->tf_regs[FRAME_A4] = rval[1];
292		framep->tf_regs[FRAME_A3] = 0;
293		break;
294	case ERESTART:
295		framep->tf_regs[FRAME_PC] -= 4;
296		break;
297	case EJUSTRETURN:
298		break;
299	default:
300	bad:
301		error = native_to_osf1_errno[error];
302		framep->tf_regs[FRAME_V0] = error;
303		framep->tf_regs[FRAME_A3] = 1;
304		break;
305	}
306
307	trace_exit(code, rval, error);
308
309	userret(l);
310}
311