aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms/cell/spufs/syscalls.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2005-11-15 15:53:48 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-09 14:49:12 +1100
commit67207b9664a8d603138ef1556141e6d0a102bea7 (patch)
treee98886778be65aeb6625a5f516873bbc5beeb978 /arch/powerpc/platforms/cell/spufs/syscalls.c
parentd7a301033f1990188f65abf4fe8e5b90ef0e3888 (diff)
[PATCH] spufs: The SPU file system, base
This is the current version of the spu file system, used for driving SPEs on the Cell Broadband Engine. This release is almost identical to the version for the 2.6.14 kernel posted earlier, which is available as part of the Cell BE Linux distribution from http://www.bsc.es/projects/deepcomputing/linuxoncell/. The first patch provides all the interfaces for running spu application, but does not have any support for debugging SPU tasks or for scheduling. Both these functionalities are added in the subsequent patches. See Documentation/filesystems/spufs.txt on how to use spufs. Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/syscalls.c')
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c106
1 files changed, 106 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
new file mode 100644
index 00000000000..3f71bb5e9d8
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -0,0 +1,106 @@
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+
+#include <asm/uaccess.h>
+
+#include "spufs.h"
+
+/**
+ * sys_spu_run - run code loaded into an SPU
+ *
+ * @unpc: next program counter for the SPU
+ * @ustatus: status of the SPU
+ *
+ * This system call transfers the control of execution of a
+ * user space thread to an SPU. It will return when the
+ * SPU has finished executing or when it hits an error
+ * condition and it will be interrupted if a signal needs
+ * to be delivered to a handler in user space.
+ *
+ * The next program counter is set to the passed value
+ * before the SPU starts fetching code and the user space
+ * pointer gets updated with the new value when returning
+ * from kernel space.
+ *
+ * The status value returned from spu_run reflects the
+ * value of the spu_status register after the SPU has stopped.
+ *
+ */
+long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus)
+{
+ long ret;
+ struct spufs_inode_info *i;
+ u32 npc, status;
+
+ ret = -EFAULT;
+ if (get_user(npc, unpc))
+ goto out;
+
+ ret = -EINVAL;
+ if (filp->f_vfsmnt->mnt_sb->s_magic != SPUFS_MAGIC)
+ goto out;
+
+ i = SPUFS_I(filp->f_dentry->d_inode);
+ ret = spufs_run_spu(filp, i->i_ctx, &npc, &status);
+
+ if (ret ==-EAGAIN || ret == -EIO)
+ ret = status;
+
+ if (put_user(npc, unpc))
+ ret = -EFAULT;
+
+ if (ustatus && put_user(status, ustatus))
+ ret = -EFAULT;
+out:
+ return ret;
+}
+
+#ifndef MODULE
+asmlinkage long sys_spu_run(int fd, __u32 __user *unpc, __u32 __user *ustatus)
+{
+ int fput_needed;
+ struct file *filp;
+ long ret;
+
+ ret = -EBADF;
+ filp = fget_light(fd, &fput_needed);
+ if (filp) {
+ ret = do_spu_run(filp, unpc, ustatus);
+ fput_light(filp, fput_needed);
+ }
+
+ return ret;
+}
+#endif
+
+asmlinkage long sys_spu_create(const char __user *pathname,
+ unsigned int flags, mode_t mode)
+{
+ char *tmp;
+ int ret;
+
+ tmp = getname(pathname);
+ ret = PTR_ERR(tmp);
+ if (!IS_ERR(tmp)) {
+ struct nameidata nd;
+
+ ret = path_lookup(tmp, LOOKUP_PARENT|
+ LOOKUP_OPEN|LOOKUP_CREATE, &nd);
+ if (!ret) {
+ ret = spufs_create_thread(&nd, pathname, flags, mode);
+ path_release(&nd);
+ }
+ putname(tmp);
+ }
+
+ return ret;
+}
+
+struct spufs_calls spufs_calls = {
+ .create_thread = sys_spu_create,
+ .spu_run = do_spu_run,
+ .owner = THIS_MODULE,
+};