1 /* $NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $ */ 2 3 /*- 4 * Copyright 2004 Olivier Houchard 5 * Copyright 2003 Wasabi Systems, Inc. 6 * All rights reserved. 7 * 8 * Written by Steve C. Woodford for Wasabi Systems, Inc. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. All advertising materials mentioning features or use of this software 19 * must display the following acknowledgement: 20 * This product includes software developed for the NetBSD Project by 21 * Wasabi Systems, Inc. 22 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 23 * or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 /*- 39 * Copyright (c) 1994-1997 Mark Brinicombe. 40 * Copyright (c) 1994 Brini. 41 * All rights reserved. 42 * 43 * This code is derived from software written for Brini by Mark Brinicombe 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * This product includes software developed by Brini. 56 * 4. The name of the company nor the name of the author may be used to 57 * endorse or promote products derived from this software without specific 58 * prior written permission. 59 * 60 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED 61 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 62 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 63 * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 64 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 65 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 66 * 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 * RiscBSD kernel project 73 * 74 * fault.c 75 * 76 * Fault handlers 77 * 78 * Created : 28/11/94 79 */ 80 81 82 #include <sys/cdefs.h> 83 __FBSDID("$FreeBSD$"); 84 85 #include <sys/param.h> 86 #include <sys/systm.h> 87 #include <sys/kernel.h> 88 #include <sys/proc.h> 89 #include <sys/lock.h> 90 #include <sys/mutex.h> 91 #include <sys/syscall.h> 92 #include <sys/sysent.h> 93 #include <sys/signalvar.h> 94 #include <sys/ptrace.h> 95 #include <sys/pioctl.h> 96 97 #include <machine/frame.h> 98 99 void swi_handler(struct trapframe *); 100 101 int 102 cpu_fetch_syscall_args(struct thread *td) 103 { 104 struct proc *p; 105 register_t *ap; 106 struct syscall_args *sa; 107 int error; 108 109 sa = &td->td_sa; 110 sa->code = td->td_frame->tf_r7; 111 ap = &td->td_frame->tf_r0; 112 if (sa->code == SYS_syscall) { 113 sa->code = *ap++; 114 sa->nap--; 115 } else if (sa->code == SYS___syscall) { 116 sa->code = ap[_QUAD_LOWWORD]; 117 sa->nap -= 2; 118 ap += 2; 119 } 120 p = td->td_proc; 121 if (p->p_sysent->sv_mask) 122 sa->code &= p->p_sysent->sv_mask; 123 if (sa->code >= p->p_sysent->sv_size) 124 sa->callp = &p->p_sysent->sv_table[0]; 125 else 126 sa->callp = &p->p_sysent->sv_table[sa->code]; 127 sa->narg = sa->callp->sy_narg; 128 error = 0; 129 memcpy(sa->args, ap, sa->nap * sizeof(register_t)); 130 if (sa->narg > sa->nap) { 131 error = copyin((void *)td->td_frame->tf_usr_sp, sa->args + 132 sa->nap, (sa->narg - sa->nap) * sizeof(register_t)); 133 } 134 if (error == 0) { 135 td->td_retval[0] = 0; 136 td->td_retval[1] = 0; 137 } 138 return (error); 139 } 140 141 #include "../../kern/subr_syscall.c" 142 143 static void 144 syscall(struct thread *td, struct trapframe *frame) 145 { 146 int error; 147 148 td->td_sa.nap = 4; 149 150 error = syscallenter(td); 151 KASSERT(error != 0 || td->td_ar == NULL, 152 ("returning from syscall with td_ar set!")); 153 syscallret(td, error); 154 } 155 156 void 157 swi_handler(struct trapframe *frame) 158 { 159 struct thread *td = curthread; 160 161 td->td_frame = frame; 162 163 td->td_pticks = 0; 164 165 /* 166 * Enable interrupts if they were enabled before the exception. 167 * Since all syscalls *should* come from user mode it will always 168 * be safe to enable them, but check anyway. 169 */ 170 if (td->td_md.md_spinlock_count == 0) { 171 if (__predict_true(frame->tf_spsr & PSR_I) == 0) 172 enable_interrupts(PSR_I); 173 if (__predict_true(frame->tf_spsr & PSR_F) == 0) 174 enable_interrupts(PSR_F); 175 } 176 177 syscall(td, frame); 178 } 179