1129198Scognet/*	$NetBSD: fault.c,v 1.45 2003/11/20 14:44:36 scw Exp $	*/
2129198Scognet
3139735Simp/*-
4129198Scognet * Copyright 2004 Olivier Houchard
5129198Scognet * Copyright 2003 Wasabi Systems, Inc.
6129198Scognet * All rights reserved.
7129198Scognet *
8129198Scognet * Written by Steve C. Woodford for Wasabi Systems, Inc.
9129198Scognet *
10129198Scognet * Redistribution and use in source and binary forms, with or without
11129198Scognet * modification, are permitted provided that the following conditions
12129198Scognet * are met:
13129198Scognet * 1. Redistributions of source code must retain the above copyright
14129198Scognet *    notice, this list of conditions and the following disclaimer.
15129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
16129198Scognet *    notice, this list of conditions and the following disclaimer in the
17129198Scognet *    documentation and/or other materials provided with the distribution.
18129198Scognet * 3. All advertising materials mentioning features or use of this software
19129198Scognet *    must display the following acknowledgement:
20129198Scognet *      This product includes software developed for the NetBSD Project by
21129198Scognet *      Wasabi Systems, Inc.
22129198Scognet * 4. The name of Wasabi Systems, Inc. may not be used to endorse
23129198Scognet *    or promote products derived from this software without specific prior
24129198Scognet *    written permission.
25129198Scognet *
26129198Scognet * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
27129198Scognet * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28129198Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29129198Scognet * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
30129198Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31129198Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32129198Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33129198Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34129198Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35129198Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36129198Scognet * POSSIBILITY OF SUCH DAMAGE.
37129198Scognet */
38139735Simp/*-
39129198Scognet * Copyright (c) 1994-1997 Mark Brinicombe.
40129198Scognet * Copyright (c) 1994 Brini.
41129198Scognet * All rights reserved.
42129198Scognet *
43129198Scognet * This code is derived from software written for Brini by Mark Brinicombe
44129198Scognet *
45129198Scognet * Redistribution and use in source and binary forms, with or without
46129198Scognet * modification, are permitted provided that the following conditions
47129198Scognet * are met:
48129198Scognet * 1. Redistributions of source code must retain the above copyright
49129198Scognet *    notice, this list of conditions and the following disclaimer.
50129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
51129198Scognet *    notice, this list of conditions and the following disclaimer in the
52129198Scognet *    documentation and/or other materials provided with the distribution.
53129198Scognet * 3. All advertising materials mentioning features or use of this software
54129198Scognet *    must display the following acknowledgement:
55129198Scognet *	This product includes software developed by Brini.
56129198Scognet * 4. The name of the company nor the name of the author may be used to
57129198Scognet *    endorse or promote products derived from this software without specific
58129198Scognet *    prior written permission.
59129198Scognet *
60129198Scognet * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
61129198Scognet * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
62129198Scognet * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
63129198Scognet * IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
64129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
65129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
66129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
67129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
68129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
69129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
70129198Scognet * SUCH DAMAGE.
71129198Scognet *
72129198Scognet * RiscBSD kernel project
73129198Scognet *
74129198Scognet * fault.c
75129198Scognet *
76129198Scognet * Fault handlers
77129198Scognet *
78129198Scognet * Created      : 28/11/94
79129198Scognet */
80129198Scognet
81129198Scognet
82129198Scognet#include <sys/cdefs.h>
83129198Scognet__FBSDID("$FreeBSD: stable/11/sys/arm/arm/syscall.c 321343 2017-07-21 18:06:57Z kib $");
84129198Scognet
85129198Scognet#include <sys/param.h>
86129198Scognet#include <sys/systm.h>
87275639Sandrew#include <sys/kernel.h>
88129198Scognet#include <sys/proc.h>
89129198Scognet#include <sys/lock.h>
90129198Scognet#include <sys/mutex.h>
91129198Scognet#include <sys/syscall.h>
92129198Scognet#include <sys/sysent.h>
93138328Scognet#include <sys/signalvar.h>
94140001Scognet#include <sys/ptrace.h>
95140001Scognet#include <sys/pioctl.h>
96129198Scognet
97129198Scognet#include <machine/frame.h>
98147544Scognet
99257217Sianvoid swi_handler(struct trapframe *);
100129198Scognet
101129198Scognetint
102321343Skibcpu_fetch_syscall_args(struct thread *td)
103225973Skib{
104225973Skib	struct proc *p;
105225973Skib	register_t *ap;
106321343Skib	struct syscall_args *sa;
107225973Skib	int error;
108225973Skib
109321343Skib	sa = &td->td_sa;
110245551Sandrew	sa->code = td->td_frame->tf_r7;
111225973Skib	ap = &td->td_frame->tf_r0;
112225973Skib	if (sa->code == SYS_syscall) {
113225973Skib		sa->code = *ap++;
114225973Skib		sa->nap--;
115225973Skib	} else if (sa->code == SYS___syscall) {
116225973Skib		sa->code = ap[_QUAD_LOWWORD];
117225973Skib		sa->nap -= 2;
118225973Skib		ap += 2;
119225973Skib	}
120225973Skib	p = td->td_proc;
121225973Skib	if (p->p_sysent->sv_mask)
122225973Skib		sa->code &= p->p_sysent->sv_mask;
123225973Skib	if (sa->code >= p->p_sysent->sv_size)
124225973Skib		sa->callp = &p->p_sysent->sv_table[0];
125225973Skib	else
126225973Skib		sa->callp = &p->p_sysent->sv_table[sa->code];
127225973Skib	sa->narg = sa->callp->sy_narg;
128225973Skib	error = 0;
129225973Skib	memcpy(sa->args, ap, sa->nap * sizeof(register_t));
130225973Skib	if (sa->narg > sa->nap) {
131225973Skib		error = copyin((void *)td->td_frame->tf_usr_sp, sa->args +
132225973Skib		    sa->nap, (sa->narg - sa->nap) * sizeof(register_t));
133225973Skib	}
134225973Skib	if (error == 0) {
135225973Skib		td->td_retval[0] = 0;
136225973Skib		td->td_retval[1] = 0;
137225973Skib	}
138225973Skib	return (error);
139225973Skib}
140225973Skib
141225973Skib#include "../../kern/subr_syscall.c"
142225973Skib
143129198Scognetstatic void
144257217Siansyscall(struct thread *td, struct trapframe *frame)
145129198Scognet{
146225973Skib	int error;
147129198Scognet
148321343Skib	td->td_sa.nap = 4;
149160773Sjhb
150321343Skib	error = syscallenter(td);
151225973Skib	KASSERT(error != 0 || td->td_ar == NULL,
152225973Skib	    ("returning from syscall with td_ar set!"));
153321343Skib	syscallret(td, error);
154129198Scognet}
155129198Scognet
156129198Scognetvoid
157257217Sianswi_handler(struct trapframe *frame)
158129198Scognet{
159129198Scognet	struct thread *td = curthread;
160129198Scognet
161137275Scognet	td->td_frame = frame;
162253142Sray
163155455Sphk	td->td_pticks = 0;
164282779Sandrew
165129198Scognet	/*
166137275Scognet	 * Enable interrupts if they were enabled before the exception.
167137275Scognet	 * Since all syscalls *should* come from user mode it will always
168236991Simp	 * be safe to enable them, but check anyway.
169236991Simp	 */
170157616Scognet	if (td->td_md.md_spinlock_count == 0) {
171271398Sandrew		if (__predict_true(frame->tf_spsr & PSR_I) == 0)
172271398Sandrew			enable_interrupts(PSR_I);
173271398Sandrew		if (__predict_true(frame->tf_spsr & PSR_F) == 0)
174271398Sandrew			enable_interrupts(PSR_F);
175157616Scognet	}
176236991Simp
177239191Sandrew	syscall(td, frame);
178129198Scognet}
179