diff options
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/sparc/include/asm/syscall.h | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/arch/sparc/include/asm/syscall.h b/arch/sparc/include/asm/syscall.h new file mode 100644 index 000000000000..7486c605e23c --- /dev/null +++ b/arch/sparc/include/asm/syscall.h | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | #ifndef __ASM_SPARC_SYSCALL_H | ||
| 2 | #define __ASM_SPARC_SYSCALL_H | ||
| 3 | |||
| 4 | #include <linux/kernel.h> | ||
| 5 | #include <linux/sched.h> | ||
| 6 | #include <asm/ptrace.h> | ||
| 7 | |||
| 8 | /* The system call number is given by the user in %g1 */ | ||
| 9 | static inline long syscall_get_nr(struct task_struct *task, | ||
| 10 | struct pt_regs *regs) | ||
| 11 | { | ||
| 12 | int syscall_p = pt_regs_is_syscall(regs); | ||
| 13 | |||
| 14 | return (syscall_p ? regs->u_regs[UREG_G1] : -1L); | ||
| 15 | } | ||
| 16 | |||
| 17 | static inline void syscall_rollback(struct task_struct *task, | ||
| 18 | struct pt_regs *regs) | ||
| 19 | { | ||
| 20 | /* XXX This needs some thought. On Sparc we don't | ||
| 21 | * XXX save away the original %o0 value somewhere. | ||
| 22 | * XXX Instead we hold it in register %l5 at the top | ||
| 23 | * XXX level trap frame and pass this down to the signal | ||
| 24 | * XXX dispatch code which is the only place that value | ||
| 25 | * XXX ever was needed. | ||
| 26 | */ | ||
| 27 | } | ||
| 28 | |||
| 29 | #ifdef CONFIG_SPARC32 | ||
| 30 | static inline bool syscall_has_error(struct pt_regs *regs) | ||
| 31 | { | ||
| 32 | return (regs->psr & PSR_C) ? true : false; | ||
| 33 | } | ||
| 34 | static inline void syscall_set_error(struct pt_regs *regs) | ||
| 35 | { | ||
| 36 | regs->psr |= PSR_C; | ||
| 37 | } | ||
| 38 | static inline void syscall_clear_error(struct pt_regs *regs) | ||
| 39 | { | ||
| 40 | regs->psr &= ~PSR_C; | ||
| 41 | } | ||
| 42 | #else | ||
| 43 | static inline bool syscall_has_error(struct pt_regs *regs) | ||
| 44 | { | ||
| 45 | return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false; | ||
| 46 | } | ||
| 47 | static inline void syscall_set_error(struct pt_regs *regs) | ||
| 48 | { | ||
| 49 | regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY); | ||
| 50 | } | ||
| 51 | static inline void syscall_clear_error(struct pt_regs *regs) | ||
| 52 | { | ||
| 53 | regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY); | ||
| 54 | } | ||
| 55 | #endif | ||
| 56 | |||
| 57 | static inline long syscall_get_error(struct task_struct *task, | ||
| 58 | struct pt_regs *regs) | ||
| 59 | { | ||
| 60 | long val = regs->u_regs[UREG_I0]; | ||
| 61 | |||
| 62 | return (syscall_has_error(regs) ? -val : 0); | ||
| 63 | } | ||
| 64 | |||
| 65 | static inline long syscall_get_return_value(struct task_struct *task, | ||
| 66 | struct pt_regs *regs) | ||
| 67 | { | ||
| 68 | long val = regs->u_regs[UREG_I0]; | ||
| 69 | |||
| 70 | return val; | ||
| 71 | } | ||
| 72 | |||
| 73 | static inline void syscall_set_return_value(struct task_struct *task, | ||
| 74 | struct pt_regs *regs, | ||
| 75 | int error, long val) | ||
| 76 | { | ||
| 77 | if (error) { | ||
| 78 | syscall_set_error(regs); | ||
| 79 | regs->u_regs[UREG_I0] = -error; | ||
| 80 | } else { | ||
| 81 | syscall_clear_error(regs); | ||
| 82 | regs->u_regs[UREG_I0] = val; | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline void syscall_get_arguments(struct task_struct *task, | ||
| 87 | struct pt_regs *regs, | ||
| 88 | unsigned int i, unsigned int n, | ||
| 89 | unsigned long *args) | ||
| 90 | { | ||
| 91 | int zero_extend = 0; | ||
| 92 | unsigned int j; | ||
| 93 | |||
| 94 | #ifdef CONFIG_SPARC64 | ||
| 95 | if (test_tsk_thread_flag(task, TIF_32BIT)) | ||
| 96 | zero_extend = 1; | ||
| 97 | #endif | ||
| 98 | |||
| 99 | for (j = 0; j < n; j++) { | ||
| 100 | unsigned long val = regs->u_regs[UREG_I0 + i + j]; | ||
| 101 | |||
| 102 | if (zero_extend) | ||
| 103 | args[j] = (u32) val; | ||
| 104 | else | ||
| 105 | args[j] = val; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | static inline void syscall_set_arguments(struct task_struct *task, | ||
| 110 | struct pt_regs *regs, | ||
| 111 | unsigned int i, unsigned int n, | ||
| 112 | const unsigned long *args) | ||
| 113 | { | ||
| 114 | unsigned int j; | ||
| 115 | |||
| 116 | for (j = 0; j < n; j++) | ||
| 117 | regs->u_regs[UREG_I0 + i + j] = args[j]; | ||
| 118 | } | ||
| 119 | |||
| 120 | #endif /* __ASM_SPARC_SYSCALL_H */ | ||
