Browse Source

microblaze: vfork/clone interface

Fix the microblaze vfork() and clone() implementations.
Add support for clone2().

Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Steven J. Magnani 13 years ago
parent
commit
975ce63594
2 changed files with 49 additions and 52 deletions
  1. 33 38
      libc/sysdeps/linux/microblaze/clone.c
  2. 16 14
      libc/sysdeps/linux/microblaze/vfork.S

+ 33 - 38
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 <jwilliams@itee.uq.edu.au>
- *  Copyright (C) 2002,03  NEC Electronics Corporation
- *  Copyright (C) 2002,03  Miles Bader <miles@gnu.org>
- *
- * 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 <miles@gnu.org>
- * 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 <sched.h>
 #include <errno.h>
 #include <errno.h>
 #include <sys/syscall.h>
 #include <sys/syscall.h>
+#include <unistd.h>
 
 
-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

+ 16 - 14
libc/sysdeps/linux/microblaze/vfork.S

@@ -1,14 +1,14 @@
 /*
 /*
  * libc/sysdeps/linux/microblaze/vfork.S -- `vfork' syscall for linux/microblaze
  * libc/sysdeps/linux/microblaze/vfork.S -- `vfork' syscall for linux/microblaze
  *
  *
+ * Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
  * Copyright (C) 2001  NEC Corporation
  * Copyright (C) 2001  NEC Corporation
  * Copyright (C) 2001  Miles Bader <miles@gnu.org>
  * Copyright (C) 2001  Miles Bader <miles@gnu.org>
- * Copyright (C) 2003  John Williams <jwilliams@itee.uq.edu.au>
- * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
  *
  *
- * 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 <miles@gnu.org>
  * Written by Miles Bader <miles@gnu.org>
  * Microblaze port by John Williams
  * Microblaze port by John Williams
  */
  */
@@ -18,7 +18,7 @@
 #define _SYSCALL_H
 #define _SYSCALL_H
 #include <bits/sysnum.h>
 #include <bits/sysnum.h>
 
 
-#include <clinkage.h>
+#include <libc-symbols.h>
 
 
 /* Clone the calling process, but without copying the whole address space.
 /* Clone the calling process, but without copying the whole address space.
    The calling process is suspended until the new process exits or is
    The calling process is suspended until the new process exits or is
@@ -27,18 +27,20 @@
 
 
 .global C_SYMBOL_NAME(errno)
 .global C_SYMBOL_NAME(errno)
 
 
-C_ENTRY (__vfork):
+	.globl __vfork
+	.align 4
+__vfork:
 	addi	r12, r0, SYS_vfork
 	addi	r12, r0, SYS_vfork
-	bralid	r17, 0x08;
-	nop
+	brki	r14, 0x08;
 	addi	r4, r3, 125		/* minimum err value */
 	addi	r4, r3, 125		/* minimum err value */
 	blti	r4, 1f			/* is r3 < -125? */
 	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);
 	swi	r3, r0, C_SYMBOL_NAME(errno);
-	rtsd	r15, 8			/* error return */
+					/* state restore etc */
+2:	rtsd	r15, 8			/* error return */
 	nop
 	nop
-C_END(__vfork)
+       .size   __vfork, .-__vfork
+
 weak_alias(__vfork,vfork)
 weak_alias(__vfork,vfork)
 libc_hidden_weak(vfork)
 libc_hidden_weak(vfork)