1/*	$OpenBSD: syscall.c,v 1.14 2024/01/11 19:16:27 miod Exp $	*/
2
3/*
4 * Copyright (c) 2015 Dale Rahn <drahn@dalerahn.com>
5 * Copyright (c) 2020 Mark Kettenis <kettenis@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <sys/param.h>
21#include <sys/systm.h>
22#include <sys/proc.h>
23#include <sys/user.h>
24#include <sys/syscall.h>
25#include <sys/syscall_mi.h>
26
27void
28syscall(struct trapframe *frame)
29{
30	struct proc *p = curproc;
31	const struct sysent *callp = sysent;
32	int code, error = ENOSYS;
33	register_t *args, rval[2];
34
35	code = frame->fixreg[0];
36	if (code <= 0 || code >= SYS_MAXSYSCALL)
37		goto bad;
38
39	callp += code;
40
41	args = &frame->fixreg[3];
42
43	rval[0] = 0;
44	rval[1] = 0;
45
46	error = mi_syscall(p, code, callp, args, rval);
47
48	switch (error) {
49	case 0:
50		frame->fixreg[0] = 0;
51		frame->fixreg[3] = rval[0];
52		frame->cr &= ~0x10000000;
53		break;
54	case ERESTART:
55		frame->srr0 -= 4;
56		break;
57	case EJUSTRETURN:
58		/* nothing to do */
59		break;
60	default:
61	bad:
62		frame->fixreg[0] = error;
63		frame->cr |= 0x10000000;
64		break;
65	}
66
67	mi_syscall_return(p, code, error, rval);
68}
69
70void
71child_return(void *arg)
72{
73	struct proc *p = (struct proc *)arg;
74	struct trapframe *frame = p->p_md.md_regs;
75
76	frame->fixreg[0] = 0;
77	frame->fixreg[3] = 0;
78	frame->cr &= ~0x10000000;
79
80	KERNEL_UNLOCK();
81
82	mi_child_return(p);
83}
84