aboutsummaryrefslogtreecommitdiff
path: root/sys/sun4v
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2009-12-12 20:06:25 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2009-12-12 20:06:25 +0000
commitf0087a7a3c1f921606121c0e6435b72492574a1a (patch)
tree5a48dbed1f886938743e5605445c76a255c8c372 /sys/sun4v
parent9562e7e533674d982b203b3f55a75de351962a05 (diff)
Notes
Diffstat (limited to 'sys/sun4v')
-rw-r--r--sys/sun4v/sun4v/trap.c38
-rw-r--r--sys/sun4v/sun4v/vm_machdep.c37
2 files changed, 40 insertions, 35 deletions
diff --git a/sys/sun4v/sun4v/trap.c b/sys/sun4v/sun4v/trap.c
index ffa0e8ca633c..353462da7c3b 100644
--- a/sys/sun4v/sun4v/trap.c
+++ b/sys/sun4v/sun4v/trap.c
@@ -81,6 +81,7 @@
#include <machine/cpu.h>
#include <machine/frame.h>
#include <machine/intr_machdep.h>
+#include <machine/pcb.h>
#include <machine/smp.h>
#include <machine/trap.h>
#include <machine/tstate.h>
@@ -582,7 +583,6 @@ syscall(struct trapframe *tf)
register_t *argp;
struct proc *p;
u_long code;
- u_long tpc;
int reg;
int regcnt;
int narg;
@@ -606,7 +606,7 @@ syscall(struct trapframe *tf)
* For syscalls, we don't want to retry the faulting instruction
* (usually), instead we need to advance one instruction.
*/
- tpc = tf->tf_tpc;
+ td->td_pcb->pcb_tpc = tf->tf_tpc;
TF_DONE(tf);
reg = 0;
@@ -673,40 +673,8 @@ syscall(struct trapframe *tf)
error, syscallnames[code], td->td_retval[0],
td->td_retval[1]);
}
-
- /*
- * MP SAFE (we may or may not have the MP lock at this point)
- */
- switch (error) {
- case 0:
- tf->tf_out[0] = td->td_retval[0];
- tf->tf_out[1] = td->td_retval[1];
- tf->tf_tstate &= ~TSTATE_XCC_C;
- break;
-
- case ERESTART:
- /*
- * Undo the tpc advancement we have done above, we want to
- * reexecute the system call.
- */
- tf->tf_tpc = tpc;
- tf->tf_tnpc -= 4;
- break;
-
- case EJUSTRETURN:
- break;
- default:
- if (p->p_sysent->sv_errsize) {
- if (error >= p->p_sysent->sv_errsize)
- error = -1; /* XXX */
- else
- error = p->p_sysent->sv_errtbl[error];
- }
- tf->tf_out[0] = error;
- tf->tf_tstate |= TSTATE_XCC_C;
- break;
- }
+ cpu_set_syscall_retval(td, error);
/*
* Handle reschedule and other end-of-syscall issues
diff --git a/sys/sun4v/sun4v/vm_machdep.c b/sys/sun4v/sun4v/vm_machdep.c
index 63a002f5e50d..5e02aec29d2f 100644
--- a/sys/sun4v/sun4v/vm_machdep.c
+++ b/sys/sun4v/sun4v/vm_machdep.c
@@ -57,6 +57,7 @@
#include <sys/mutex.h>
#include <sys/sf_buf.h>
#include <sys/sysctl.h>
+#include <sys/sysent.h>
#include <sys/unistd.h>
#include <sys/vmmeter.h>
@@ -142,6 +143,42 @@ cpu_thread_swapout(struct thread *td)
}
void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+
+ switch (error) {
+ case 0:
+ td->td_frame->tf_out[0] = td->td_retval[0];
+ td->td_frame->tf_out[1] = td->td_retval[1];
+ td->td_frame->tf_tstate &= ~TSTATE_XCC_C;
+ break;
+
+ case ERESTART:
+ /*
+ * Undo the tpc advancement we have done on syscall
+ * enter, we want to reexecute the system call.
+ */
+ td->td_frame->tf_tpc = td->td_pcb->pcb_tpc;
+ td->td_frame->tf_tnpc -= 4;
+ break;
+
+ case EJUSTRETURN:
+ break;
+
+ default:
+ if (td->td_proc->p_sysent->sv_errsize) {
+ if (error >= td->td_proc->p_sysent->sv_errsize)
+ error = -1; /* XXX */
+ else
+ error = td->td_proc->p_sysent->sv_errtbl[error];
+ }
+ td->td_frame->tf_out[0] = error;
+ td->td_frame->tf_tstate |= TSTATE_XCC_C;
+ break;
+ }
+}
+
+void
cpu_set_upcall(struct thread *td, struct thread *td0)
{
struct trapframe *tf;