#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
#include <sys/user.h>
#include <sys/vnode.h>
#include <sys/signal.h>
#include <sys/syscall.h>
#include <sys/syscall_mi.h>
#include <uvm/uvm_extern.h>
void
svc_handler(trapframe_t *frame)
{
struct proc *p = curproc;
const struct sysent *callp;
int code, error = ENOSYS;
register_t *args, rval[2];
atomic_inc_int(&uvmexp.syscalls);
if (__predict_true((frame->tf_spsr & I_bit) == 0))
intr_enable();
frame->tf_elr += 8;
code = frame->tf_x[8];
if (code <= 0 || code >= SYS_MAXSYSCALL)
goto bad;
callp = sysent + code;
args = &frame->tf_x[0];
rval[0] = 0;
rval[1] = 0;
error = mi_syscall(p, code, callp, args, rval);
switch (error) {
case 0:
frame->tf_x[0] = rval[0];
frame->tf_spsr &= ~PSR_C;
break;
case ERESTART:
frame->tf_elr -= 12;
break;
case EJUSTRETURN:
break;
default:
bad:
frame->tf_x[0] = error;
frame->tf_spsr |= PSR_C;
break;
}
mi_syscall_return(p, code, error, rval);
}
void
child_return(void *arg)
{
struct proc *p = arg;
struct trapframe *frame = p->p_addr->u_pcb.pcb_tf;
frame->tf_x[0] = 0;
frame->tf_spsr &= ~PSR_C;
KERNEL_UNLOCK();
mi_child_return(p);
}