1 /* $NetBSD: syscall.c,v 1.15 2013/06/26 16:28:51 matt 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 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 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; /* fuword(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 /* fuword(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