Mon Dec 14 18:39:19 2009 UTC ()
Wrap comment.


(skrll)
diff -r1.39 -r1.40 src/sys/arch/mips/mips/syscall.c

cvs diff -r1.39 -r1.40 src/sys/arch/mips/mips/syscall.c (switch to unified diff)

--- src/sys/arch/mips/mips/syscall.c 2009/12/14 00:46:07 1.39
+++ src/sys/arch/mips/mips/syscall.c 2009/12/14 18:39:19 1.40
@@ -1,424 +1,425 @@ @@ -1,424 +1,425 @@
1/* $NetBSD: syscall.c,v 1.39 2009/12/14 00:46:07 matt Exp $ */ 1/* $NetBSD: syscall.c,v 1.40 2009/12/14 18:39:19 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe and by Charles M. Hannum. 8 * by Jason R. Thorpe and by Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1992, 1993 33 * Copyright (c) 1992, 1993
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * This code is derived from software contributed to Berkeley by 36 * This code is derived from software contributed to Berkeley by
37 * the Systems Programming Group of the University of Utah Computer 37 * the Systems Programming Group of the University of Utah Computer
38 * Science Department and Ralph Campbell. 38 * Science Department and Ralph Campbell.
39 * 39 *
40 * Redistribution and use in source and binary forms, with or without 40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions 41 * modification, are permitted provided that the following conditions
42 * are met: 42 * are met:
43 * 1. Redistributions of source code must retain the above copyright 43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer. 44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright 45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the 46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution. 47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors 48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software 49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission. 50 * without specific prior written permission.
51 * 51 *
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE. 62 * SUCH DAMAGE.
63 * 63 *
64 * from: Utah Hdr: trap.c 1.32 91/04/06 64 * from: Utah Hdr: trap.c 1.32 91/04/06
65 * 65 *
66 * @(#)trap.c 8.5 (Berkeley) 1/11/94 66 * @(#)trap.c 8.5 (Berkeley) 1/11/94
67 */ 67 */
68/* 68/*
69 * Copyright (c) 1988 University of Utah. 69 * Copyright (c) 1988 University of Utah.
70 * 70 *
71 * This code is derived from software contributed to Berkeley by 71 * This code is derived from software contributed to Berkeley by
72 * the Systems Programming Group of the University of Utah Computer 72 * the Systems Programming Group of the University of Utah Computer
73 * Science Department and Ralph Campbell. 73 * Science Department and Ralph Campbell.
74 * 74 *
75 * Redistribution and use in source and binary forms, with or without 75 * Redistribution and use in source and binary forms, with or without
76 * modification, are permitted provided that the following conditions 76 * modification, are permitted provided that the following conditions
77 * are met: 77 * are met:
78 * 1. Redistributions of source code must retain the above copyright 78 * 1. Redistributions of source code must retain the above copyright
79 * notice, this list of conditions and the following disclaimer. 79 * notice, this list of conditions and the following disclaimer.
80 * 2. Redistributions in binary form must reproduce the above copyright 80 * 2. Redistributions in binary form must reproduce the above copyright
81 * notice, this list of conditions and the following disclaimer in the 81 * notice, this list of conditions and the following disclaimer in the
82 * documentation and/or other materials provided with the distribution. 82 * documentation and/or other materials provided with the distribution.
83 * 3. All advertising materials mentioning features or use of this software 83 * 3. All advertising materials mentioning features or use of this software
84 * must display the following acknowledgement: 84 * must display the following acknowledgement:
85 * This product includes software developed by the University of 85 * This product includes software developed by the University of
86 * California, Berkeley and its contributors. 86 * California, Berkeley and its contributors.
87 * 4. Neither the name of the University nor the names of its contributors 87 * 4. Neither the name of the University nor the names of its contributors
88 * may be used to endorse or promote products derived from this software 88 * may be used to endorse or promote products derived from this software
89 * without specific prior written permission. 89 * without specific prior written permission.
90 * 90 *
91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
101 * SUCH DAMAGE. 101 * SUCH DAMAGE.
102 * 102 *
103 * from: Utah Hdr: trap.c 1.32 91/04/06 103 * from: Utah Hdr: trap.c 1.32 91/04/06
104 * 104 *
105 * @(#)trap.c 8.5 (Berkeley) 1/11/94 105 * @(#)trap.c 8.5 (Berkeley) 1/11/94
106 */ 106 */
107 107
108#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 108#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
109 109
110__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.39 2009/12/14 00:46:07 matt Exp $"); 110__KERNEL_RCSID(0, "$NetBSD: syscall.c,v 1.40 2009/12/14 18:39:19 skrll Exp $");
111 111
112#if defined(_KERNEL_OPT) 112#if defined(_KERNEL_OPT)
113#include "opt_sa.h" 113#include "opt_sa.h"
114#endif 114#endif
115 115
116#include <sys/param.h> 116#include <sys/param.h>
117#include <sys/systm.h> 117#include <sys/systm.h>
118#include <sys/endian.h> 118#include <sys/endian.h>
119#include <sys/proc.h> 119#include <sys/proc.h>
120#include <sys/signal.h> 120#include <sys/signal.h>
121#include <sys/syscall.h> 121#include <sys/syscall.h>
122#include <sys/syscallvar.h> 122#include <sys/syscallvar.h>
123#include <sys/sa.h> 123#include <sys/sa.h>
124#include <sys/savar.h> 124#include <sys/savar.h>
125 125
126#include <uvm/uvm_extern.h> 126#include <uvm/uvm_extern.h>
127 127
128#include <machine/cpu.h> 128#include <machine/cpu.h>
129#include <mips/trap.h> 129#include <mips/trap.h>
130#include <mips/reg.h> 130#include <mips/reg.h>
131#include <mips/regnum.h> /* symbolic register indices */ 131#include <mips/regnum.h> /* symbolic register indices */
132#include <mips/userret.h> 132#include <mips/userret.h>
133 133
134#ifndef EMULNAME 134#ifndef EMULNAME
135#define EMULNAME(x) (x) 135#define EMULNAME(x) (x)
136#endif 136#endif
137 137
138#ifndef SYSCALL_SHIFT 138#ifndef SYSCALL_SHIFT
139#define SYSCALL_SHIFT 0 139#define SYSCALL_SHIFT 0
140#endif 140#endif
141 141
142void EMULNAME(syscall_intern)(struct proc *); 142void EMULNAME(syscall_intern)(struct proc *);
143static void EMULNAME(syscall)(struct lwp *, uint32_t, uint32_t, vaddr_t); 143static void EMULNAME(syscall)(struct lwp *, uint32_t, uint32_t, vaddr_t);
144 144
145register_t MachEmulateBranch(struct frame *, register_t, u_int, int); 145register_t MachEmulateBranch(struct frame *, register_t, u_int, int);
146 146
147void 147void
148EMULNAME(syscall_intern)(struct proc *p) 148EMULNAME(syscall_intern)(struct proc *p)
149{ 149{
150 p->p_md.md_syscall = EMULNAME(syscall); 150 p->p_md.md_syscall = EMULNAME(syscall);
151} 151}
152 152
153/* 153/*
154 * Process a system call. 154 * Process a system call.
155 * 155 *
156 * System calls are strange beasts. They are passed the syscall number 156 * System calls are strange beasts. They are passed the syscall number
157 * in v0, and the arguments in the registers (as normal). They return 157 * in v0, and the arguments in the registers (as normal). They return
158 * an error flag in a3 (if a3 != 0 on return, the syscall had an error), 158 * an error flag in a3 (if a3 != 0 on return, the syscall had an error),
159 * and the return value (if any) in v0 and possibly v1. 159 * and the return value (if any) in v0 and possibly v1.
160 */ 160 */
161 161
162void 162void
163EMULNAME(syscall)(struct lwp *l, u_int status, u_int cause, vaddr_t opc) 163EMULNAME(syscall)(struct lwp *l, u_int status, u_int cause, vaddr_t opc)
164{ 164{
165 struct proc *p = l->l_proc; 165 struct proc *p = l->l_proc;
166 struct frame *frame = l->l_md.md_regs; 166 struct frame *frame = l->l_md.md_regs;
167 mips_reg_t *fargs = &frame->f_regs[_R_A0]; 167 mips_reg_t *fargs = &frame->f_regs[_R_A0];
168 register_t *args = NULL; 168 register_t *args = NULL;
169 register_t copyargs[2+SYS_MAXSYSARGS]; 169 register_t copyargs[2+SYS_MAXSYSARGS];
170 mips_reg_t saved_v0; 170 mips_reg_t saved_v0;
171 vaddr_t usp; 171 vaddr_t usp;
172 size_t nargs; 172 size_t nargs;
173 const struct sysent *callp; 173 const struct sysent *callp;
174 int code, error; 174 int code, error;
175#if defined(__mips_o32) 175#if defined(__mips_o32)
176 const int abi = _MIPS_BSD_API_O32; 176 const int abi = _MIPS_BSD_API_O32;
177 KASSERTMSG(p->p_md.md_abi != abi, ("pid %d(%p): md_abi(%d) != abi(%d)", p->p_pid, p, p->p_md.md_abi, abi)); 177 KASSERTMSG(p->p_md.md_abi != abi, ("pid %d(%p): md_abi(%d) != abi(%d)", p->p_pid, p, p->p_md.md_abi, abi));
178 size_t nregs = 4; 178 size_t nregs = 4;
179#else 179#else
180 const int abi = p->p_md.md_abi; 180 const int abi = p->p_md.md_abi;
181 size_t nregs = _MIPS_SIM_NEWABI_P(abi) ? 8 : 4; 181 size_t nregs = _MIPS_SIM_NEWABI_P(abi) ? 8 : 4;
182 size_t i; 182 size_t i;
183#endif 183#endif
184 184
185 LWP_CACHE_CREDS(l, p); 185 LWP_CACHE_CREDS(l, p);
186 186
187 uvmexp.syscalls++; 187 uvmexp.syscalls++;
188 188
189 if (cause & MIPS_CR_BR_DELAY) 189 if (cause & MIPS_CR_BR_DELAY)
190 frame->f_regs[_R_PC] = MachEmulateBranch(frame, opc, 0, 0); 190 frame->f_regs[_R_PC] = MachEmulateBranch(frame, opc, 0, 0);
191 else 191 else
192 frame->f_regs[_R_PC] = opc + sizeof(uint32_t); 192 frame->f_regs[_R_PC] = opc + sizeof(uint32_t);
193 193
194 callp = p->p_emul->e_sysent; 194 callp = p->p_emul->e_sysent;
195 saved_v0 = code = frame->f_regs[_R_V0]; 195 saved_v0 = code = frame->f_regs[_R_V0];
196 196
197 code -= SYSCALL_SHIFT; 197 code -= SYSCALL_SHIFT;
198 198
199#ifdef KERN_SA 199#ifdef KERN_SA
200 if (__predict_false((l->l_savp) 200 if (__predict_false((l->l_savp)
201 && (l->l_savp->savp_pflags & SAVP_FLAG_DELIVERING))) 201 && (l->l_savp->savp_pflags & SAVP_FLAG_DELIVERING)))
202 l->l_savp->savp_pflags &= ~SAVP_FLAG_DELIVERING; 202 l->l_savp->savp_pflags &= ~SAVP_FLAG_DELIVERING;
203#endif 203#endif
204 204
205 if (code == SYS_syscall 205 if (code == SYS_syscall
206 || (code == SYS___syscall && abi != _MIPS_BSD_API_O32)) { 206 || (code == SYS___syscall && abi != _MIPS_BSD_API_O32)) {
207 /* 207 /*
208 * Code is first argument, followed by actual args. 208 * Code is first argument, followed by actual args.
209 */ 209 */
210 code = *fargs++ - SYSCALL_SHIFT; 210 code = *fargs++ - SYSCALL_SHIFT;
211 nregs--; 211 nregs--;
212 } else if (code == SYS___syscall) { 212 } else if (code == SYS___syscall) {
213 /* 213 /*
214 * Like syscall, but code is a quad, so as to maintain 214 * Like syscall, but code is a quad, so as to maintain
215 * quad alignment for the rest of the arguments. 215 * quad alignment for the rest of the arguments.
216 */ 216 */
217 code = fargs[_QUAD_LOWWORD] - SYSCALL_SHIFT; 217 code = fargs[_QUAD_LOWWORD] - SYSCALL_SHIFT;
218 fargs += 2; 218 fargs += 2;
219 nregs -= 2; 219 nregs -= 2;
220 } 220 }
221 221
222 if (code >= p->p_emul->e_nsysent) 222 if (code >= p->p_emul->e_nsysent)
223 callp += p->p_emul->e_nosys; 223 callp += p->p_emul->e_nosys;
224 else 224 else
225 callp += code; 225 callp += code;
226 226
227 nargs = callp->sy_narg; 227 nargs = callp->sy_narg;
228 frame->f_regs[_R_V0] = 0; 228 frame->f_regs[_R_V0] = 0;
229#if !defined(__mips_o32) 229#if !defined(__mips_o32)
230 if (abi != _MIPS_BSD_API_O32) { 230 if (abi != _MIPS_BSD_API_O32) {
231#endif 231#endif
232 CTASSERT(sizeof(copyargs[0]) == sizeof(fargs[0])); 232 CTASSERT(sizeof(copyargs[0]) == sizeof(fargs[0]));
233 if (nargs <= nregs) { 233 if (nargs <= nregs) {
234 /* 234 /*
235 * Just use the frame for the source of arguments 235 * Just use the frame for the source of arguments
236 */ 236 */
237 args = fargs; 237 args = fargs;
238 } else { 238 } else {
239 const size_t nsaved = _MIPS_SIM_NEWABI_P(abi) ? 0 : 4; 239 const size_t nsaved = _MIPS_SIM_NEWABI_P(abi) ? 0 : 4;
240 KASSERT(nargs <= __arraycount(copyargs)); 240 KASSERT(nargs <= __arraycount(copyargs));
241 args = copyargs; 241 args = copyargs;
242 /* 242 /*
243 * Copy the arguments passed via register from the * trap frame to our argument array 243 * Copy the arguments passed via register from the
 244 * trap frame to our argument array
244 */ 245 */
245 memcpy(copyargs, fargs, nregs * sizeof(register_t)); 246 memcpy(copyargs, fargs, nregs * sizeof(register_t));
246 /* 247 /*
247 * Start copying args skipping the register slots 248 * Start copying args skipping the register slots
248 * slots on the stack. 249 * slots on the stack.
249 */ 250 */
250 usp = frame->f_regs[_R_SP] + nsaved*sizeof(register_t); 251 usp = frame->f_regs[_R_SP] + nsaved*sizeof(register_t);
251 error = copyin((register_t *)usp, &copyargs[nregs], 252 error = copyin((register_t *)usp, &copyargs[nregs],
252 (nargs - nregs) * sizeof(copyargs[0])); 253 (nargs - nregs) * sizeof(copyargs[0]));
253 if (error) 254 if (error)
254 goto bad; 255 goto bad;
255 } 256 }
256#if !defined(__mips_o32) 257#if !defined(__mips_o32)
257 } else do { 258 } else do {
258 /* 259 /*
259 * The only difference between O32 and N32 is the calling 260 * The only difference between O32 and N32 is the calling
260 * sequence. If you make O32  261 * sequence. If you make O32
261 */ 262 */
262 int32_t copy32args[SYS_MAXSYSARGS]; 263 int32_t copy32args[SYS_MAXSYSARGS];
263 int32_t *cargs = copy32args;  264 int32_t *cargs = copy32args;
264 unsigned int arg64mask = SYCALL_ARG_64_MASK(callp); 265 unsigned int arg64mask = SYCALL_ARG_64_MASK(callp);
265 bool doing_arg64; 266 bool doing_arg64;
266 size_t narg64 = SYCALL_NARGS64(callp); 267 size_t narg64 = SYCALL_NARGS64(callp);
267 /* 268 /*
268 * All arguments are 32bits wide and 64bit arguments use 269 * All arguments are 32bits wide and 64bit arguments use
269 * two 32bit registers or stack slots. We need to remarshall 270 * two 32bit registers or stack slots. We need to remarshall
270 * them into 64bit slots 271 * them into 64bit slots
271 */ 272 */
272 args = copyargs; 273 args = copyargs;
273 CTASSERT(sizeof(copy32args[0]) != sizeof(fargs[0])); 274 CTASSERT(sizeof(copy32args[0]) != sizeof(fargs[0]));
274 275
275 /* 276 /*
276 * If there are no 64bit arguments and all arguments were in 277 * If there are no 64bit arguments and all arguments were in
277 * registers, just use the frame for the source of arguments 278 * registers, just use the frame for the source of arguments
278 */ 279 */
279 if (nargs <= nregs && narg64 == 0) { 280 if (nargs <= nregs && narg64 == 0) {
280 args = fargs; 281 args = fargs;
281 break; 282 break;
282 } 283 }
283 284
284 if (nregs <= nargs + narg64) { 285 if (nregs <= nargs + narg64) {
285 /* 286 /*
286 * Grab the non-register arguments from the stack 287 * Grab the non-register arguments from the stack
287 * after skipping the slots for the 4 register passed 288 * after skipping the slots for the 4 register passed
288 * arguments. 289 * arguments.
289 */ 290 */
290 usp = frame->f_regs[_R_SP] + 4*sizeof(int32_t); 291 usp = frame->f_regs[_R_SP] + 4*sizeof(int32_t);
291 error = copyin((int32_t *)usp, copy32args, 292 error = copyin((int32_t *)usp, copy32args,
292 (nargs + narg64 - nregs) * sizeof(copy32args[0])); 293 (nargs + narg64 - nregs) * sizeof(copy32args[0]));
293 if (error) 294 if (error)
294 goto bad; 295 goto bad;
295 } 296 }
296 /* 297 /*
297 * Copy all the arguments to copyargs, starting with the ones 298 * Copy all the arguments to copyargs, starting with the ones
298 * in registers. Using the hints in the 64bit argmask, 299 * in registers. Using the hints in the 64bit argmask,
299 * we marshall the passed 32bit values into 64bit slots. If we 300 * we marshall the passed 32bit values into 64bit slots. If we
300 * encounter a 64 bit argument, we grab two adjacent 32bit 301 * encounter a 64 bit argument, we grab two adjacent 32bit
301 * values and synthesize the 64bit argument. 302 * values and synthesize the 64bit argument.
302 */ 303 */
303 for (i = 0, doing_arg64 = false; i < nargs + narg64;) { 304 for (i = 0, doing_arg64 = false; i < nargs + narg64;) {
304 register_t arg; 305 register_t arg;
305 if (nregs > 0) { 306 if (nregs > 0) {
306 arg = (int32_t) *fargs++;  307 arg = (int32_t) *fargs++;
307 nregs--; 308 nregs--;
308 } else { 309 } else {
309 arg = *cargs++; 310 arg = *cargs++;
310 } 311 }
311 if (__predict_true((arg64mask & 1) == 0)) { 312 if (__predict_true((arg64mask & 1) == 0)) {
312 /* 313 /*
313 * Just copy it with sign extension on 314 * Just copy it with sign extension on
314 */ 315 */
315 copyargs[i++] = (int32_t) arg; 316 copyargs[i++] = (int32_t) arg;
316 arg64mask >>= 1; 317 arg64mask >>= 1;
317 continue; 318 continue;
318 } 319 }
319 /* 320 /*
320 * 64bit arg. grab the low 32 bits, discard the high. 321 * 64bit arg. grab the low 32 bits, discard the high.
321 */ 322 */
322 arg = (uint32_t)arg; 323 arg = (uint32_t)arg;
323 if (!doing_arg64) { 324 if (!doing_arg64) {
324 /* 325 /*
325 * Pick up the 1st word of a 64bit arg. 326 * Pick up the 1st word of a 64bit arg.
326 * If lowword == 1 then highword == 0, 327 * If lowword == 1 then highword == 0,
327 * so this is the highword and thus 328 * so this is the highword and thus
328 * shifted left by 32, otherwise 329 * shifted left by 32, otherwise
329 * lowword == 0 and highword == 1 so 330 * lowword == 0 and highword == 1 so
330 * it isn't shifted at all. Remember 331 * it isn't shifted at all. Remember
331 * we still need another word. 332 * we still need another word.
332 */ 333 */
333 doing_arg64 = true; 334 doing_arg64 = true;
334 copyargs[i] = arg << (_QUAD_LOWWORD*32); 335 copyargs[i] = arg << (_QUAD_LOWWORD*32);
335 narg64--; /* one less 64bit arg */ 336 narg64--; /* one less 64bit arg */
336 } else { 337 } else {
337 /* 338 /*
338 * Pick up the 2nd word of a 64bit arg. 339 * Pick up the 2nd word of a 64bit arg.
339 * if highword == 1, it's shifted left 340 * if highword == 1, it's shifted left
340 * by 32, otherwise lowword == 1 and 341 * by 32, otherwise lowword == 1 and
341 * highword == 0 so it isn't shifted at 342 * highword == 0 so it isn't shifted at
342 * all. And now head to the next argument. 343 * all. And now head to the next argument.
343 */ 344 */
344 doing_arg64 = false; 345 doing_arg64 = false;
345 copyargs[i++] |= arg << (_QUAD_HIGHWORD*32); 346 copyargs[i++] |= arg << (_QUAD_HIGHWORD*32);
346 arg64mask >>= 1; 347 arg64mask >>= 1;
347 } 348 }
348 } 349 }
349 } while (/*CONSTCOND*/ 0); /* avoid a goto */ 350 } while (/*CONSTCOND*/ 0); /* avoid a goto */
350#endif 351#endif
351 352
352#ifdef MIPS_SYSCALL_DEBUG 353#ifdef MIPS_SYSCALL_DEBUG
353 if (p->p_emul->e_syscallnames) 354 if (p->p_emul->e_syscallnames)
354 printf("syscall %s:", p->p_emul->e_syscallnames[code]); 355 printf("syscall %s:", p->p_emul->e_syscallnames[code]);
355 else 356 else
356 printf("syscall %u:", code); 357 printf("syscall %u:", code);
357 if (nargs == 0) 358 if (nargs == 0)
358 printf(" <no args>"); 359 printf(" <no args>");
359 else for (size_t j = 0; j < nargs; j++) { 360 else for (size_t j = 0; j < nargs; j++) {
360 if (j == nregs) printf(" *"); 361 if (j == nregs) printf(" *");
361 printf(" [%s%zu]=%#"PRIxREGISTER, 362 printf(" [%s%zu]=%#"PRIxREGISTER,
362 SYCALL_ARG_64_P(callp, j) ? "+" : "", 363 SYCALL_ARG_64_P(callp, j) ? "+" : "",
363 j, args[j]); 364 j, args[j]);
364 } 365 }
365 printf("\n"); 366 printf("\n");
366#endif 367#endif
367 368
368 if (__predict_false(p->p_trace_enabled) 369 if (__predict_false(p->p_trace_enabled)
369 && (error = trace_enter(code, args, nargs)) != 0) 370 && (error = trace_enter(code, args, nargs)) != 0)
370 goto out; 371 goto out;
371 372
372 error = (*callp->sy_call)(l, args, &frame->f_regs[_R_V0]); 373 error = (*callp->sy_call)(l, args, &frame->f_regs[_R_V0]);
373 374
374 out: 375 out:
375 switch (error) { 376 switch (error) {
376 case 0: 377 case 0:
377#if !defined(__mips_o32) 378#if !defined(__mips_o32)
378 if (abi == _MIPS_BSD_API_O32 && SYCALL_RET_64_P(callp)) { 379 if (abi == _MIPS_BSD_API_O32 && SYCALL_RET_64_P(callp)) {
379 /* 380 /*
380 * If this is from O32 and it's a 64bit quantity, 381 * If this is from O32 and it's a 64bit quantity,
381 * split it into 2 32bit values in adjacent registers. 382 * split it into 2 32bit values in adjacent registers.
382 */ 383 */
383 mips_reg_t tmp = frame->f_regs[_R_V0]; 384 mips_reg_t tmp = frame->f_regs[_R_V0];
384 frame->f_regs[_R_V0 + _QUAD_LOWWORD] = (int32_t) tmp; 385 frame->f_regs[_R_V0 + _QUAD_LOWWORD] = (int32_t) tmp;
385 frame->f_regs[_R_V0 + _QUAD_HIGHWORD] = tmp >> 32;  386 frame->f_regs[_R_V0 + _QUAD_HIGHWORD] = tmp >> 32;
386 } 387 }
387#endif 388#endif
388#ifdef MIPS_SYSCALL_DEBUG 389#ifdef MIPS_SYSCALL_DEBUG
389 if (p->p_emul->e_syscallnames) 390 if (p->p_emul->e_syscallnames)
390 printf("syscall %s:", p->p_emul->e_syscallnames[code]); 391 printf("syscall %s:", p->p_emul->e_syscallnames[code]);
391 else 392 else
392 printf("syscall %u:", code); 393 printf("syscall %u:", code);
393 printf(" return v0=%#"PRIxREGISTER" v1=%#"PRIxREGISTER"\n", 394 printf(" return v0=%#"PRIxREGISTER" v1=%#"PRIxREGISTER"\n",
394 frame->f_regs[_R_V0], frame->f_regs[_R_V1]); 395 frame->f_regs[_R_V0], frame->f_regs[_R_V1]);
395#endif 396#endif
396 frame->f_regs[_R_A3] = 0; 397 frame->f_regs[_R_A3] = 0;
397 break; 398 break;
398 case ERESTART: 399 case ERESTART:
399 frame->f_regs[_R_V0] = saved_v0; /* restore syscall code */ 400 frame->f_regs[_R_V0] = saved_v0; /* restore syscall code */
400 frame->f_regs[_R_PC] = opc; 401 frame->f_regs[_R_PC] = opc;
401 break; 402 break;
402 case EJUSTRETURN: 403 case EJUSTRETURN:
403 break; /* nothing to do */ 404 break; /* nothing to do */
404 default: 405 default:
405 bad: 406 bad:
406 if (p->p_emul->e_errno) 407 if (p->p_emul->e_errno)
407 error = p->p_emul->e_errno[error]; 408 error = p->p_emul->e_errno[error];
408 frame->f_regs[_R_V0] = error; 409 frame->f_regs[_R_V0] = error;
409 frame->f_regs[_R_A3] = 1; 410 frame->f_regs[_R_A3] = 1;
410#ifdef MIPS_SYSCALL_DEBUG 411#ifdef MIPS_SYSCALL_DEBUG
411 if (p->p_emul->e_syscallnames) 412 if (p->p_emul->e_syscallnames)
412 printf("syscall %s:", p->p_emul->e_syscallnames[code]); 413 printf("syscall %s:", p->p_emul->e_syscallnames[code]);
413 else 414 else
414 printf("syscall %u:", code); 415 printf("syscall %u:", code);
415 printf(" return error=%d\n", error); 416 printf(" return error=%d\n", error);
416#endif 417#endif
417 break; 418 break;
418 } 419 }
419 420
420 if (__predict_false(p->p_trace_enabled)) 421 if (__predict_false(p->p_trace_enabled))
421 trace_exit(code, &frame->f_regs[_R_V0], error); 422 trace_exit(code, &frame->f_regs[_R_V0], error);
422 423
423 userret(l); 424 userret(l);
424} 425}