summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim/vm_machdep.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-11-10 11:43:07 +0000
committerkib <kib@FreeBSD.org>2009-11-10 11:43:07 +0000
commit3cf53f181e7360f48fecc50a925d46029888af1d (patch)
treebba1aed931ce7ad22617119eb8a0f3b4e1652845 /sys/powerpc/aim/vm_machdep.c
parente256ac508b1a8eb7aedb8f720f3e650ecd273b53 (diff)
downloadFreeBSD-src-3cf53f181e7360f48fecc50a925d46029888af1d.zip
FreeBSD-src-3cf53f181e7360f48fecc50a925d46029888af1d.tar.gz
Extract the code that records syscall results in the frame into MD
function cpu_set_syscall_retval(). Suggested by: marcel Reviewed by: marcel, davidxu PowerPC, ARM, ia64 changes: marcel Sparc64 tested and reviewed by: marius, also sunv reviewed MIPS tested by: gonzo MFC after: 1 month
Diffstat (limited to 'sys/powerpc/aim/vm_machdep.c')
-rw-r--r--sys/powerpc/aim/vm_machdep.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c
index af83854..3967176 100644
--- a/sys/powerpc/aim/vm_machdep.c
+++ b/sys/powerpc/aim/vm_machdep.c
@@ -81,7 +81,9 @@
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/sf_buf.h>
+#include <sys/syscall.h>
#include <sys/sysctl.h>
+#include <sys/sysent.h>
#include <sys/unistd.h>
#include <machine/cpu.h>
@@ -422,6 +424,59 @@ cpu_thread_swapout(struct thread *td)
}
void
+cpu_set_syscall_retval(struct thread *td, int error)
+{
+ struct proc *p;
+ struct trapframe *tf;
+ int fixup;
+
+ if (error == EJUSTRETURN)
+ return;
+
+ p = td->td_proc;
+ tf = td->td_frame;
+
+ if (tf->fixreg[0] == SYS___syscall) {
+ int code = tf->fixreg[FIRSTARG + 1];
+ if (p->p_sysent->sv_mask)
+ code &= p->p_sysent->sv_mask;
+ fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek) ?
+ 1 : 0;
+ } else
+ fixup = 0;
+
+ switch (error) {
+ case 0:
+ if (fixup) {
+ /*
+ * 64-bit return, 32-bit syscall. Fixup byte order
+ */
+ tf->fixreg[FIRSTARG] = 0;
+ tf->fixreg[FIRSTARG + 1] = td->td_retval[0];
+ } else {
+ tf->fixreg[FIRSTARG] = td->td_retval[0];
+ tf->fixreg[FIRSTARG + 1] = td->td_retval[1];
+ }
+ tf->cr &= ~0x10000000; /* XXX: Magic number */
+ break;
+ case ERESTART:
+ /*
+ * Set user's pc back to redo the system call.
+ */
+ tf->srr0 -= 4;
+ break;
+ default:
+ if (p->p_sysent->sv_errsize) {
+ error = (error < p->p_sysent->sv_errsize) ?
+ p->p_sysent->sv_errtbl[error] : -1;
+ }
+ tf->fixreg[FIRSTARG] = error;
+ tf->cr |= 0x10000000; /* XXX: Magic number */
+ break;
+ }
+}
+
+void
cpu_set_upcall(struct thread *td, struct thread *td0)
{
struct pcb *pcb2;
OpenPOWER on IntegriCloud