Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sparc: Add asm/syscall.h

Based upon a patch by Roland McGrath.

Signed-off-by: David S. Miller <davem@davemloft.net>

+120
+120
arch/sparc/include/asm/syscall.h
··· 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 */