xref: /openbsd/sys/arch/arm/arm/syscall.c (revision cb0f97f9)
1 /*	$OpenBSD: syscall.c,v 1.28 2023/12/13 15:57:22 miod Exp $	*/
2 /*	$NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $	*/
3 
4 /*-
5  * Copyright (c) 2000, 2003 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * 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) 1994-1998 Mark Brinicombe.
35  * Copyright (c) 1994 Brini.
36  * All rights reserved.
37  *
38  * This code is derived from software written for Brini by Mark Brinicombe
39  *
40  * Redistribution and use in source and binary forms, with or without
41  * modification, are permitted provided that the following conditions
42  * are met:
43  * 1. Redistributions of source code must retain the above copyright
44  *    notice, this list of conditions and the following disclaimer.
45  * 2. Redistributions in binary form must reproduce the above copyright
46  *    notice, this list of conditions and the following disclaimer in the
47  *    documentation and/or other materials provided with the distribution.
48  * 3. All advertising materials mentioning features or use of this software
49  *    must display the following acknowledgement:
50  *	This product includes software developed by Mark Brinicombe
51  *	for the NetBSD Project.
52  * 4. The name of the company nor the name of the author may be used to
53  *    endorse or promote products derived from this software without specific
54  *    prior written permission.
55  *
56  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
57  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
58  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
59  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
60  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
61  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
62  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66  * SUCH DAMAGE.
67  *
68  * syscall entry handling
69  *
70  * Created      : 09/11/94
71  */
72 
73 #include <sys/param.h>
74 
75 #include <sys/errno.h>
76 #include <sys/kernel.h>
77 #include <sys/systm.h>
78 #include <sys/proc.h>
79 #include <sys/user.h>
80 #include <sys/syscall.h>
81 #include <sys/syscall_mi.h>
82 
83 #include <uvm/uvm_extern.h>
84 
85 #include <machine/cpu.h>
86 #include <machine/frame.h>
87 #include <machine/pcb.h>
88 #include <arm/vfp.h>
89 
90 #define MAXARGS 8
91 
92 void
swi_handler(trapframe_t * frame)93 swi_handler(trapframe_t *frame)
94 {
95 	struct proc *p = curproc;
96 	const struct sysent *callp = sysent;
97 	int code, error;
98 	u_int nap = 4, nargs;
99 	register_t *ap, *args, copyargs[MAXARGS], rval[2];
100 
101 	uvmexp.syscalls++;
102 
103 	/* Before enabling interrupts, save FPU state */
104 	vfp_save();
105 
106 	enable_interrupts(PSR_I);
107 
108 	p->p_addr->u_pcb.pcb_tf = frame;
109 
110 	/* Skip over speculation-blocking barrier. */
111 	frame->tf_pc += 8;
112 
113 	ap = &frame->tf_r0;
114 
115 	code = frame->tf_r12;
116 	// XXX out of range stays on syscall0, which we assume is enosys
117 	if (code > 0 && code < SYS_MAXSYSCALL)
118 		callp += code;
119 
120 	nargs = callp->sy_argsize / sizeof(register_t);
121 	if (nargs <= nap) {
122 		args = ap;
123 	} else {
124 		KASSERT(nargs <= MAXARGS);
125 		memcpy(copyargs, ap, nap * sizeof(register_t));
126 		if ((error = copyin((void *)frame->tf_usr_sp, copyargs + nap,
127 		    (nargs - nap) * sizeof(register_t))))
128 			goto bad;
129 		args = copyargs;
130 	}
131 
132 	rval[0] = 0;
133 	rval[1] = frame->tf_r1;
134 
135 	error = mi_syscall(p, code, callp, args, rval);
136 
137 	switch (error) {
138 	case 0:
139 		frame->tf_r0 = rval[0];
140 		frame->tf_r1 = rval[1];
141 		frame->tf_spsr &= ~PSR_C;	/* carry bit */
142 		break;
143 	case ERESTART:
144 		/*
145 		 * Reconstruct the pc to point at the swi.
146 		 */
147 		frame->tf_pc -= 12;
148 		break;
149 	case EJUSTRETURN:
150 		/* nothing to do */
151 		break;
152 	default:
153 	bad:
154 		frame->tf_r0 = error;
155 		frame->tf_spsr |= PSR_C;	/* carry bit */
156 		break;
157 	}
158 
159 	mi_syscall_return(p, code, error, rval);
160 }
161 
162 void
child_return(void * arg)163 child_return(void *arg)
164 {
165 	struct proc *p = arg;
166 	struct trapframe *frame = p->p_addr->u_pcb.pcb_tf;
167 
168 	frame->tf_r0 = 0;
169 	frame->tf_spsr &= ~PSR_C;	/* carry bit */
170 
171 	KERNEL_UNLOCK();
172 
173 	mi_child_return(p);
174 }
175