xref: /freebsd/sys/arm/arm/syscall.c (revision 95d7f8aa40198f5e8f6aefbe4f03204ddd9ae133)
1293b5c22SAndrew Turner /*	$NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $	*/
2293b5c22SAndrew Turner 
3293b5c22SAndrew Turner /*-
4293b5c22SAndrew Turner  * Copyright 2004 Olivier Houchard
5293b5c22SAndrew Turner  * Copyright 2003 Wasabi Systems, Inc.
6293b5c22SAndrew Turner  * All rights reserved.
7293b5c22SAndrew Turner  *
8293b5c22SAndrew Turner  * Written by Steve C. Woodford for Wasabi Systems, Inc.
9293b5c22SAndrew Turner  *
10293b5c22SAndrew Turner  * Redistribution and use in source and binary forms, with or without
11293b5c22SAndrew Turner  * modification, are permitted provided that the following conditions
12293b5c22SAndrew Turner  * are met:
13293b5c22SAndrew Turner  * 1. Redistributions of source code must retain the above copyright
14293b5c22SAndrew Turner  *    notice, this list of conditions and the following disclaimer.
15293b5c22SAndrew Turner  * 2. Redistributions in binary form must reproduce the above copyright
16293b5c22SAndrew Turner  *    notice, this list of conditions and the following disclaimer in the
17293b5c22SAndrew Turner  *    documentation and/or other materials provided with the distribution.
18293b5c22SAndrew Turner  * 3. All advertising materials mentioning features or use of this software
19293b5c22SAndrew Turner  *    must display the following acknowledgement:
20293b5c22SAndrew Turner  *      This product includes software developed for the NetBSD Project by
21293b5c22SAndrew Turner  *      Wasabi Systems, Inc.
22293b5c22SAndrew Turner  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23293b5c22SAndrew Turner  *    or promote products derived from this software without specific prior
24293b5c22SAndrew Turner  *    written permission.
25293b5c22SAndrew Turner  *
26293b5c22SAndrew Turner  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27293b5c22SAndrew Turner  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28293b5c22SAndrew Turner  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29293b5c22SAndrew Turner  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
30293b5c22SAndrew Turner  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31293b5c22SAndrew Turner  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32293b5c22SAndrew Turner  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33293b5c22SAndrew Turner  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34293b5c22SAndrew Turner  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35293b5c22SAndrew Turner  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36293b5c22SAndrew Turner  * POSSIBILITY OF SUCH DAMAGE.
37293b5c22SAndrew Turner  */
38293b5c22SAndrew Turner /*-
39293b5c22SAndrew Turner  * Copyright (c) 1994-1997 Mark Brinicombe.
40293b5c22SAndrew Turner  * Copyright (c) 1994 Brini.
41293b5c22SAndrew Turner  * All rights reserved.
42293b5c22SAndrew Turner  *
43293b5c22SAndrew Turner  * This code is derived from software written for Brini by Mark Brinicombe
44293b5c22SAndrew Turner  *
45293b5c22SAndrew Turner  * Redistribution and use in source and binary forms, with or without
46293b5c22SAndrew Turner  * modification, are permitted provided that the following conditions
47293b5c22SAndrew Turner  * are met:
48293b5c22SAndrew Turner  * 1. Redistributions of source code must retain the above copyright
49293b5c22SAndrew Turner  *    notice, this list of conditions and the following disclaimer.
50293b5c22SAndrew Turner  * 2. Redistributions in binary form must reproduce the above copyright
51293b5c22SAndrew Turner  *    notice, this list of conditions and the following disclaimer in the
52293b5c22SAndrew Turner  *    documentation and/or other materials provided with the distribution.
53293b5c22SAndrew Turner  * 3. All advertising materials mentioning features or use of this software
54293b5c22SAndrew Turner  *    must display the following acknowledgement:
55293b5c22SAndrew Turner  *	This product includes software developed by Brini.
56293b5c22SAndrew Turner  * 4. The name of the company nor the name of the author may be used to
57293b5c22SAndrew Turner  *    endorse or promote products derived from this software without specific
58293b5c22SAndrew Turner  *    prior written permission.
59293b5c22SAndrew Turner  *
60293b5c22SAndrew Turner  * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
61293b5c22SAndrew Turner  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62293b5c22SAndrew Turner  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
63293b5c22SAndrew Turner  * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
64293b5c22SAndrew Turner  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65293b5c22SAndrew Turner  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
66293b5c22SAndrew Turner  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67293b5c22SAndrew Turner  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68293b5c22SAndrew Turner  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69293b5c22SAndrew Turner  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70293b5c22SAndrew Turner  * SUCH DAMAGE.
71293b5c22SAndrew Turner  *
72293b5c22SAndrew Turner  * RiscBSD kernel project
73293b5c22SAndrew Turner  *
74293b5c22SAndrew Turner  * fault.c
75293b5c22SAndrew Turner  *
76293b5c22SAndrew Turner  * Fault handlers
77293b5c22SAndrew Turner  *
78293b5c22SAndrew Turner  * Created      : 28/11/94
79293b5c22SAndrew Turner  */
80293b5c22SAndrew Turner 
81293b5c22SAndrew Turner 
82293b5c22SAndrew Turner #include <sys/cdefs.h>
83293b5c22SAndrew Turner __FBSDID("$FreeBSD$");
84293b5c22SAndrew Turner 
85293b5c22SAndrew Turner #include <sys/param.h>
86293b5c22SAndrew Turner #include <sys/systm.h>
87*95d7f8aaSAndrew Turner #include <sys/kernel.h>
88293b5c22SAndrew Turner #include <sys/proc.h>
89293b5c22SAndrew Turner #include <sys/lock.h>
90293b5c22SAndrew Turner #include <sys/mutex.h>
91293b5c22SAndrew Turner #include <sys/syscall.h>
92293b5c22SAndrew Turner #include <sys/sysent.h>
93293b5c22SAndrew Turner #include <sys/signalvar.h>
94293b5c22SAndrew Turner #include <sys/ptrace.h>
95293b5c22SAndrew Turner #include <sys/pioctl.h>
96293b5c22SAndrew Turner 
97293b5c22SAndrew Turner #include <machine/frame.h>
98293b5c22SAndrew Turner 
99293b5c22SAndrew Turner void swi_handler(struct trapframe *);
100293b5c22SAndrew Turner 
101293b5c22SAndrew Turner static __inline void
102293b5c22SAndrew Turner call_trapsignal(struct thread *td, int sig, u_long code)
103293b5c22SAndrew Turner {
104293b5c22SAndrew Turner 	ksiginfo_t ksi;
105293b5c22SAndrew Turner 
106293b5c22SAndrew Turner 	ksiginfo_init_trap(&ksi);
107293b5c22SAndrew Turner 	ksi.ksi_signo = sig;
108293b5c22SAndrew Turner 	ksi.ksi_code = (int)code;
109293b5c22SAndrew Turner 	trapsignal(td, &ksi);
110293b5c22SAndrew Turner }
111293b5c22SAndrew Turner 
112293b5c22SAndrew Turner int
113293b5c22SAndrew Turner cpu_fetch_syscall_args(struct thread *td, struct syscall_args *sa)
114293b5c22SAndrew Turner {
115293b5c22SAndrew Turner 	struct proc *p;
116293b5c22SAndrew Turner 	register_t *ap;
117293b5c22SAndrew Turner 	int error;
118293b5c22SAndrew Turner 
119293b5c22SAndrew Turner 	sa->code = td->td_frame->tf_r7;
120293b5c22SAndrew Turner 	ap = &td->td_frame->tf_r0;
121293b5c22SAndrew Turner 	if (sa->code == SYS_syscall) {
122293b5c22SAndrew Turner 		sa->code = *ap++;
123293b5c22SAndrew Turner 		sa->nap--;
124293b5c22SAndrew Turner 	} else if (sa->code == SYS___syscall) {
125293b5c22SAndrew Turner 		sa->code = ap[_QUAD_LOWWORD];
126293b5c22SAndrew Turner 		sa->nap -= 2;
127293b5c22SAndrew Turner 		ap += 2;
128293b5c22SAndrew Turner 	}
129293b5c22SAndrew Turner 	p = td->td_proc;
130293b5c22SAndrew Turner 	if (p->p_sysent->sv_mask)
131293b5c22SAndrew Turner 		sa->code &= p->p_sysent->sv_mask;
132293b5c22SAndrew Turner 	if (sa->code >= p->p_sysent->sv_size)
133293b5c22SAndrew Turner 		sa->callp = &p->p_sysent->sv_table[0];
134293b5c22SAndrew Turner 	else
135293b5c22SAndrew Turner 		sa->callp = &p->p_sysent->sv_table[sa->code];
136293b5c22SAndrew Turner 	sa->narg = sa->callp->sy_narg;
137293b5c22SAndrew Turner 	error = 0;
138293b5c22SAndrew Turner 	memcpy(sa->args, ap, sa->nap * sizeof(register_t));
139293b5c22SAndrew Turner 	if (sa->narg > sa->nap) {
140293b5c22SAndrew Turner 		error = copyin((void *)td->td_frame->tf_usr_sp, sa->args +
141293b5c22SAndrew Turner 		    sa->nap, (sa->narg - sa->nap) * sizeof(register_t));
142293b5c22SAndrew Turner 	}
143293b5c22SAndrew Turner 	if (error == 0) {
144293b5c22SAndrew Turner 		td->td_retval[0] = 0;
145293b5c22SAndrew Turner 		td->td_retval[1] = 0;
146293b5c22SAndrew Turner 	}
147293b5c22SAndrew Turner 	return (error);
148293b5c22SAndrew Turner }
149293b5c22SAndrew Turner 
150293b5c22SAndrew Turner #include "../../kern/subr_syscall.c"
151293b5c22SAndrew Turner 
152293b5c22SAndrew Turner static void
153293b5c22SAndrew Turner syscall(struct thread *td, struct trapframe *frame)
154293b5c22SAndrew Turner {
155293b5c22SAndrew Turner 	struct syscall_args sa;
156293b5c22SAndrew Turner 	int error;
157293b5c22SAndrew Turner 
158293b5c22SAndrew Turner 	sa.nap = 4;
159293b5c22SAndrew Turner 
160293b5c22SAndrew Turner 	error = syscallenter(td, &sa);
161293b5c22SAndrew Turner 	KASSERT(error != 0 || td->td_ar == NULL,
162293b5c22SAndrew Turner 	    ("returning from syscall with td_ar set!"));
163293b5c22SAndrew Turner 	syscallret(td, error, &sa);
164293b5c22SAndrew Turner }
165293b5c22SAndrew Turner 
166293b5c22SAndrew Turner void
167293b5c22SAndrew Turner swi_handler(struct trapframe *frame)
168293b5c22SAndrew Turner {
169293b5c22SAndrew Turner 	struct thread *td = curthread;
170293b5c22SAndrew Turner 
171293b5c22SAndrew Turner 	td->td_frame = frame;
172293b5c22SAndrew Turner 
173293b5c22SAndrew Turner 	td->td_pticks = 0;
174293b5c22SAndrew Turner 	/*
175293b5c22SAndrew Turner 	 * Make sure the program counter is correctly aligned so we
176293b5c22SAndrew Turner 	 * don't take an alignment fault trying to read the opcode.
177293b5c22SAndrew Turner 	 * XXX: Fix for Thumb mode
178293b5c22SAndrew Turner 	 */
179293b5c22SAndrew Turner 	if (__predict_false(((frame->tf_pc - INSN_SIZE) & 3) != 0)) {
180293b5c22SAndrew Turner 		call_trapsignal(td, SIGILL, 0);
181293b5c22SAndrew Turner 		userret(td, frame);
182293b5c22SAndrew Turner 		return;
183293b5c22SAndrew Turner 	}
184293b5c22SAndrew Turner 	/*
185293b5c22SAndrew Turner 	 * Enable interrupts if they were enabled before the exception.
186293b5c22SAndrew Turner 	 * Since all syscalls *should* come from user mode it will always
187293b5c22SAndrew Turner 	 * be safe to enable them, but check anyway.
188293b5c22SAndrew Turner 	 */
189293b5c22SAndrew Turner 	if (td->td_md.md_spinlock_count == 0) {
190293b5c22SAndrew Turner 		if (__predict_true(frame->tf_spsr & PSR_I) == 0)
191293b5c22SAndrew Turner 			enable_interrupts(PSR_I);
192293b5c22SAndrew Turner 		if (__predict_true(frame->tf_spsr & PSR_F) == 0)
193293b5c22SAndrew Turner 			enable_interrupts(PSR_F);
194293b5c22SAndrew Turner 	}
195293b5c22SAndrew Turner 
196293b5c22SAndrew Turner 	syscall(td, frame);
197293b5c22SAndrew Turner }
198