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 */ 121