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(), ©args[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(), ©args[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