From 3cf53f181e7360f48fecc50a925d46029888af1d Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 10 Nov 2009 11:43:07 +0000 Subject: 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 --- sys/arm/arm/trap.c | 37 +-------------------------------- sys/arm/arm/vm_machdep.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 36 deletions(-) (limited to 'sys/arm') 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 #include #include +#include +#include #include #include #include @@ -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 -- cgit v1.1