From 975ce6359486ec3d2905e57d11ef22088b04b85f Mon Sep 17 00:00:00 2001 From: "Steven J. Magnani" Date: Wed, 10 Nov 2010 19:30:02 +0100 Subject: microblaze: vfork/clone interface Fix the microblaze vfork() and clone() implementations. Add support for clone2(). Signed-off-by: Steven J. Magnani Signed-off-by: Bernhard Reutner-Fischer --- libc/sysdeps/linux/microblaze/clone.c | 71 ++++++++++++++++------------------- libc/sysdeps/linux/microblaze/vfork.S | 30 ++++++++------- 2 files changed, 49 insertions(+), 52 deletions(-) (limited to 'libc/sysdeps/linux/microblaze') diff --git a/libc/sysdeps/linux/microblaze/clone.c b/libc/sysdeps/linux/microblaze/clone.c index a47ee8c68..d92100865 100644 --- a/libc/sysdeps/linux/microblaze/clone.c +++ b/libc/sysdeps/linux/microblaze/clone.c @@ -1,52 +1,47 @@ /* - * libc/sysdeps/linux/microblaze/clone.c -- `clone' syscall for linux/microblaze + * Copyright (C) 2004 Atmel Corporation * - * Copyright (C) 2003 John Williams - * Copyright (C) 2002,03 NEC Electronics Corporation - * Copyright (C) 2002,03 Miles Bader - * - * This file is subject to the terms and conditions of the GNU Lesser - * General Public License. See the file COPYING.LIB in the main - * directory of this archive for more details. - * - * Written by Miles Bader - * Microblaze port by John Williams + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License. See the file "COPYING.LIB" in the main directory of this + * archive for more details. */ - +#include #include #include +#include -int -clone (int (*fn)(void *arg), void *child_stack, int flags, void *arg) +int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg, ...) { - register unsigned long rval __asm__ (SYSCALL_RET) = -EINVAL; + int rval = -EINVAL; + if (fn && child_stack) + rval = INTERNAL_SYSCALL(clone, 0, 2, flags, child_stack); + + if (rval == 0) + { + int exitCode = fn(arg); + rval = INTERNAL_SYSCALL(exit, 0, 1, exitCode); + } - if (fn && child_stack) - { - register unsigned long syscall __asm__ (SYSCALL_NUM); - register unsigned long arg0 __asm__ (SYSCALL_ARG0); - register unsigned long arg1 __asm__ (SYSCALL_ARG1); + return rval; +} - /* Clone this thread. */ - arg0 = flags; - arg1 = (unsigned long)child_stack; - syscall = __NR_clone; - __asm__ __volatile__ ("bralid r17, trap;nop;" - : "=r" (rval), "=r" (syscall) - : "1" (syscall), "r" (arg0), "r" (arg1) - : SYSCALL_CLOBBERS); +#ifdef __NR_clone2 +int +__clone2(int (*fn)(void *arg), void *child_stack, size_t stack_size, + int flags, void *arg, ...) +{ + int rval = -EINVAL; + if (fn && child_stack) + { + rval = INTERNAL_SYSCALL(clone2, 0, 3, flags, child_stack, stack_size); + } - if (rval == 0) - /* In child thread, call FN and exit. */ + if (rval == 0) { - arg0 = (*fn) (arg); - syscall = __NR_exit; - __asm__ __volatile__ ("bralid r17, trap;nop;" - : "=r" (rval), "=r" (syscall) - : "1" (syscall), "r" (arg0) - : SYSCALL_CLOBBERS); + int exitCode = fn(arg); + rval = INTERNAL_SYSCALL(exit, 0, 1, exitCode); } - } - __syscall_return (int, rval); + return rval; } +#endif diff --git a/libc/sysdeps/linux/microblaze/vfork.S b/libc/sysdeps/linux/microblaze/vfork.S index 42458308a..c4b4dbf2f 100644 --- a/libc/sysdeps/linux/microblaze/vfork.S +++ b/libc/sysdeps/linux/microblaze/vfork.S @@ -1,14 +1,14 @@ /* * libc/sysdeps/linux/microblaze/vfork.S -- `vfork' syscall for linux/microblaze * + * Copyright (C) 2003 John Williams * Copyright (C) 2001 NEC Corporation * Copyright (C) 2001 Miles Bader - * Copyright (C) 2003 John Williams - * Copyright (C) 2000-2006 Erik Andersen * - * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. - */ -/* + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License. See the file COPYING.LIB in the main + * directory of this archive for more details. + * * Written by Miles Bader * Microblaze port by John Williams */ @@ -18,7 +18,7 @@ #define _SYSCALL_H #include -#include +#include /* Clone the calling process, but without copying the whole address space. The calling process is suspended until the new process exits or is @@ -27,18 +27,20 @@ .global C_SYMBOL_NAME(errno) -C_ENTRY (__vfork): + .globl __vfork + .align 4 +__vfork: addi r12, r0, SYS_vfork - bralid r17, 0x08; - nop + brki r14, 0x08; addi r4, r3, 125 /* minimum err value */ blti r4, 1f /* is r3 < -125? */ - rtsd r15, 8 /* normal return */ - nop -1: sub r3, r3, r0 /* r3 = -r3 */ + bri 2f /* normal return */ +1: sub r3, r3, r0 /* r3 = -r3 */ swi r3, r0, C_SYMBOL_NAME(errno); - rtsd r15, 8 /* error return */ + /* state restore etc */ +2: rtsd r15, 8 /* error return */ nop -C_END(__vfork) + .size __vfork, .-__vfork + weak_alias(__vfork,vfork) libc_hidden_weak(vfork) -- cgit v1.2.3