xref: /freebsd/sys/arm/arm/syscall.c (revision fcb560670601b2a4d87bb31d7531c8dcc37ee71b)
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 static __inline void
102 call_trapsignal(struct thread *td, int sig, u_long code)
103 {
104 	ksiginfo_t ksi;
105 
106 	ksiginfo_init_trap(&ksi);
107 	ksi.ksi_signo = sig;
108 	ksi.ksi_code = (int)code;
109 	trapsignal(td, &ksi);
110 }
111 
112 int
113 cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
114 {
115 	struct proc *p;
116 	register_t *ap;
117 	int error;
118 
119 	sa->code = td->td_frame->tf_r7;
120 	ap = &td->td_frame->tf_r0;
121 	if (sa->code == SYS_syscall) {
122 		sa->code = *ap++;
123 		sa->nap--;
124 	} else if (sa->code == SYS___syscall) {
125 		sa->code = ap[_QUAD_LOWWORD];
126 		sa->nap -= 2;
127 		ap += 2;
128 	}
129 	p = td->td_proc;
130 	if (p->p_sysent->sv_mask)
131 		sa->code &= p->p_sysent->sv_mask;
132 	if (sa->code >= p->p_sysent->sv_size)
133 		sa->callp = &p->p_sysent->sv_table[0];
134 	else
135 		sa->callp = &p->p_sysent->sv_table[sa->code];
136 	sa->narg = sa->callp->sy_narg;
137 	error = 0;
138 	memcpy(sa->args, ap, sa->nap * sizeof(register_t));
139 	if (sa->narg > sa->nap) {
140 		error = copyin((void *)td->td_frame->tf_usr_sp, sa->args +
141 		    sa->nap, (sa->narg - sa->nap) * sizeof(register_t));
142 	}
143 	if (error == 0) {
144 		td->td_retval[0] = 0;
145 		td->td_retval[1] = 0;
146 	}
147 	return (error);
148 }
149 
150 #include "../../kern/subr_syscall.c"
151 
152 static void
153 syscall(struct thread *td, struct trapframe *frame)
154 {
155 	struct syscall_args sa;
156 	int error;
157 
158 	sa.nap = 4;
159 
160 	error = syscallenter(td, &sa);
161 	KASSERT(error != 0 || td->td_ar == NULL,
162 	    ("returning from syscall with td_ar set!"));
163 	syscallret(td, error, &sa);
164 }
165 
166 void
167 swi_handler(struct trapframe *frame)
168 {
169 	struct thread *td = curthread;
170 
171 	td->td_frame = frame;
172 
173 	td->td_pticks = 0;
174 	/*
175 	 * Make sure the program counter is correctly aligned so we
176 	 * don't take an alignment fault trying to read the opcode.
177 	 * XXX: Fix for Thumb mode
178 	 */
179 	if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
180 		call_trapsignal(td, SIGILL, 0);
181 		userret(td, frame);
182 		return;
183 	}
184 	/*
185 	 * Enable interrupts if they were enabled before the exception.
186 	 * Since all syscalls *should* come from user mode it will always
187 	 * be safe to enable them, but check anyway.
188 	 */
189 	if (td->td_md.md_spinlock_count == 0) {
190 		if (__predict_true(frame->tf_spsr & PSR_I) == 0)
191 			enable_interrupts(PSR_I);
192 		if (__predict_true(frame->tf_spsr & PSR_F) == 0)
193 			enable_interrupts(PSR_F);
194 	}
195 
196 	syscall(td, frame);
197 }
198