diff options
author | kib <kib@FreeBSD.org> | 2009-11-10 11:43:07 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2009-11-10 11:43:07 +0000 |
commit | 3cf53f181e7360f48fecc50a925d46029888af1d (patch) | |
tree | bba1aed931ce7ad22617119eb8a0f3b4e1652845 /sys/arm | |
parent | e256ac508b1a8eb7aedb8f720f3e650ecd273b53 (diff) | |
download | FreeBSD-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/arm')
-rw-r--r-- | sys/arm/arm/trap.c | 37 | ||||
-rw-r--r-- | sys/arm/arm/vm_machdep.c | 53 |
2 files changed, 54 insertions, 36 deletions
diff --git a/sys/arm/arm/trap.c b/sys/arm/arm/trap.c index e6150c0..348ec5a 100644 --- a/sys/arm/arm/trap.c +++ b/sys/arm/arm/trap.c @@ -932,43 +932,8 @@ syscall(struct thread *td, trapframe_t *frame, u_int32_t insn) KASSERT(td->td_ar == NULL, ("returning from syscall with td_ar set!")); } - switch (error) { - case 0: -#ifdef __ARMEB__ - if ((insn & 0x000fffff) == SYS___syscall && - code != SYS_freebsd6_lseek && code != SYS_lseek) { - /* - * 64-bit return, 32-bit syscall. Fixup byte order - */ - frame->tf_r0 = 0; - frame->tf_r1 = td->td_retval[0]; - } else { - frame->tf_r0 = td->td_retval[0]; - frame->tf_r1 = td->td_retval[1]; - } -#else - frame->tf_r0 = td->td_retval[0]; - frame->tf_r1 = td->td_retval[1]; -#endif - - frame->tf_spsr &= ~PSR_C_bit; /* carry bit */ - break; - - case ERESTART: - /* - * Reconstruct the pc to point at the swi. - */ - frame->tf_pc -= INSN_SIZE; - break; - case EJUSTRETURN: - /* nothing to do */ - break; - default: bad: - frame->tf_r0 = error; - frame->tf_spsr |= PSR_C_bit; /* carry bit */ - break; - } + cpu_set_syscall_retval(td, error); WITNESS_WARN(WARN_PANIC, NULL, "System call %s returning", (code >= 0 && code < SYS_MAXSYSCALL) ? syscallnames[code] : "???"); diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index 6bd5799..95b9ca8 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/socketvar.h> #include <sys/sf_buf.h> +#include <sys/syscall.h> +#include <sys/sysent.h> #include <sys/unistd.h> #include <machine/cpu.h> #include <machine/pcb.h> @@ -261,6 +263,57 @@ done: #endif } +void +cpu_set_syscall_retval(struct thread *td, int error) +{ + trapframe_t *frame; + int fixup; +#ifdef __ARMEB__ + uint32_t insn; +#endif + + frame = td->td_frame; + fixup = 0; + +#ifdef __ARMEB__ + insn = *(u_int32_t *)(frame->tf_pc - INSN_SIZE); + if ((insn & 0x000fffff) == SYS___syscall) { + register_t *ap = &frame->tf_r0; + register_t code = ap[_QUAD_LOWWORD]; + if (td->td_proc->p_sysent->sv_mask) + code &= td->td_proc->p_sysent->sv_mask; + fixup = (code != SYS_freebsd6_lseek && code != SYS_lseek) + ? 1 : 0; + } +#endif + + switch (error) { + case 0: + if (fixup) { + frame->tf_r0 = 0; + frame->tf_r1 = td->td_retval[0]; + } else { + frame->tf_r0 = td->td_retval[0]; + frame->tf_r1 = td->td_retval[1]; + } + frame->tf_spsr &= ~PSR_C_bit; /* carry bit */ + break; + case ERESTART: + /* + * Reconstruct the pc to point at the swi. + */ + frame->tf_pc -= INSN_SIZE; + break; + case EJUSTRETURN: + /* nothing to do */ + break; + default: + frame->tf_r0 = error; + frame->tf_spsr |= PSR_C_bit; /* carry bit */ + break; + } +} + /* * Initialize machine state (pcb and trap frame) for a new thread about to * upcall. Put enough state in the new thread's PCB to get it to go back |