summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux/microblaze/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'libc/sysdeps/linux/microblaze/syscall.c')
-rw-r--r--libc/sysdeps/linux/microblaze/syscall.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/libc/sysdeps/linux/microblaze/syscall.c b/libc/sysdeps/linux/microblaze/syscall.c
new file mode 100644
index 000000000..be628a878
--- /dev/null
+++ b/libc/sysdeps/linux/microblaze/syscall.c
@@ -0,0 +1,51 @@
+/*
+ * libc/sysdeps/linux/microblaze/syscall.c -- generic syscall function for linux/microblaze
+ *
+ * Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
+ * Copyright (C) 2002 NEC Corporation
+ * Copyright (C) 2002 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>
+ */
+
+#include <errno.h>
+#include <sys/syscall.h>
+
+typedef unsigned long arg_t;
+
+/* Invoke `system call' NUM, passing it the remaining arguments.
+ This is completely system-dependent, and not often useful. */
+long
+syscall (long num, arg_t a1, arg_t a2, arg_t a3, arg_t a4, arg_t a5, arg_t a6)
+{
+ /* We don't know how many arguments are valid, so A5 and A6 are fetched
+ off the stack even for (the majority of) system calls with fewer
+ arguments; hopefully this won't cause any problems. A1-A4 are in
+ registers, so they're OK. */
+ register arg_t a asm (SYSCALL_ARG0) = a1;
+ register arg_t b asm (SYSCALL_ARG1) = a2;
+ register arg_t c asm (SYSCALL_ARG2) = a3;
+ register arg_t d asm (SYSCALL_ARG3) = a4;
+ register arg_t e asm (SYSCALL_ARG4) = a5;
+ register arg_t f asm (SYSCALL_ARG5) = a6;
+ register unsigned long syscall asm (SYSCALL_NUM) = num;
+ register unsigned long ret asm (SYSCALL_RET);
+ unsigned long ret_sav;
+
+ *((unsigned long *)0xFFFF4004) = (unsigned int)('+');
+ asm ("brlid r17, 08x; nop;"
+ : "=r" (ret)
+ : "r" (syscall), "r" (a), "r" (b), "r" (c), "r" (d), "r" (e), "r" (f)
+ : SYSCALL_CLOBBERS);
+
+ ret_sav=ret;
+ *((unsigned long *)0xFFFF4004) = (unsigned int)('-');
+
+
+
+ __syscall_return (long, ret);
+}