summaryrefslogtreecommitdiff
path: root/arch/sh/include/asm/syscall_64.h
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2008-12-10 19:46:18 +0900
committerPaul Mundt <lethal@linux-sh.org>2008-12-22 18:44:04 +0900
commit94e2fb3d3e1f4cb6bad2b13c572c4c99ad734a37 (patch)
tree7bfd32774ea72cbf0da11ed074dd449a31dbed0b /arch/sh/include/asm/syscall_64.h
parent6ac034375fe8b4341137657adf5e6ff0dcb5a99f (diff)
sh: Provide asm/syscall.h for SH-5.
This provides the asm/syscall.h implementation for sh64 parts. Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'arch/sh/include/asm/syscall_64.h')
-rw-r--r--arch/sh/include/asm/syscall_64.h76
1 files changed, 75 insertions, 1 deletions
diff --git a/arch/sh/include/asm/syscall_64.h b/arch/sh/include/asm/syscall_64.h
index bcaaa8ca4d70..e95f3ae30aff 100644
--- a/arch/sh/include/asm/syscall_64.h
+++ b/arch/sh/include/asm/syscall_64.h
@@ -1,6 +1,80 @@
#ifndef __ASM_SH_SYSCALL_64_H
#define __ASM_SH_SYSCALL_64_H
-#include <asm-generic/syscall.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/ptrace.h>
+
+/* The system call number is given by the user in R9 */
+static inline long syscall_get_nr(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return (regs->syscall_nr >= 0) ? regs->regs[9] : -1L;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ /*
+ * XXX: This needs some thought. On SH we don't
+ * save away the original R9 value anywhere.
+ */
+}
+
+static inline bool syscall_has_error(struct pt_regs *regs)
+{
+ return (regs->sr & 0x1) ? true : false;
+}
+static inline void syscall_set_error(struct pt_regs *regs)
+{
+ regs->sr |= 0x1;
+}
+static inline void syscall_clear_error(struct pt_regs *regs)
+{
+ regs->sr &= ~0x1;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return syscall_has_error(regs) ? regs->regs[9] : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->regs[9];
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ if (error) {
+ syscall_set_error(regs);
+ regs->regs[9] = -error;
+ } else {
+ syscall_clear_error(regs);
+ regs->regs[9] = val;
+ }
+}
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ BUG_ON(i + n > 6);
+ memcpy(args, &regs->reg[2 + i], n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ BUG_ON(i + n > 6);
+ memcpy(&regs->reg[2 + i], args, n * sizeof(args[0]));
+}
#endif /* __ASM_SH_SYSCALL_64_H */