summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/include/pcb.h3
-rw-r--r--sys/sparc64/sparc64/trap.c37
-rw-r--r--sys/sparc64/sparc64/vm_machdep.c37
3 files changed, 41 insertions, 36 deletions
diff --git a/sys/sparc64/include/pcb.h b/sys/sparc64/include/pcb.h
index 7e8294a..f23c1f2 100644
--- a/sys/sparc64/include/pcb.h
+++ b/sys/sparc64/include/pcb.h
@@ -49,7 +49,8 @@ struct pcb {
uint64_t pcb_nsaved;
uint64_t pcb_pc;
uint64_t pcb_sp;
- uint64_t pcb_pad[4];
+ uint64_t pcb_tpc;
+ uint64_t pcb_pad[3];
} __aligned(64);
#ifdef _KERNEL
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index 702e4f1..0c07eaf 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -538,7 +538,6 @@ syscall(struct trapframe *tf)
register_t *argp;
struct proc *p;
u_long code;
- u_long tpc;
int reg;
int regcnt;
int narg;
@@ -562,7 +561,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;
@@ -626,39 +625,7 @@ syscall(struct trapframe *tf)
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);
/*
* Check for misbehavior.
diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c
index 76521a6..009f45d 100644
--- a/sys/sparc64/sparc64/vm_machdep.c
+++ b/sys/sparc64/sparc64/vm_machdep.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mbuf.h>
#include <sys/mutex.h>
#include <sys/proc.h>
+#include <sys/sysent.h>
#include <sys/sf_buf.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
@@ -166,6 +167,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;
OpenPOWER on IntegriCloud