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/* 9 * The syscall table always contains 32 bit pointers since we know that the 10 * address of the function to be called is (way) below 4GB. So the "int" 11 * type here is what we want [need] for both 32 bit and 64 bit systems. 12 */ 13extern const unsigned int sys_call_table[]; 14 15/* The system call number is given by the user in %g1 */ 16static inline long syscall_get_nr(struct task_struct *task, 17 struct pt_regs *regs) 18{ 19 int syscall_p = pt_regs_is_syscall(regs); 20 21 return (syscall_p ? regs->u_regs[UREG_G1] : -1L); 22} 23 24static inline void syscall_rollback(struct task_struct *task, 25 struct pt_regs *regs) 26{ 27} 28 29#ifdef CONFIG_SPARC32 30static inline bool syscall_has_error(struct pt_regs *regs) 31{ 32 return (regs->psr & PSR_C) ? true : false; 33} 34static inline void syscall_set_error(struct pt_regs *regs) 35{ 36 regs->psr |= PSR_C; 37} 38static inline void syscall_clear_error(struct pt_regs *regs) 39{ 40 regs->psr &= ~PSR_C; 41} 42#else 43static inline bool syscall_has_error(struct pt_regs *regs) 44{ 45 return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false; 46} 47static inline void syscall_set_error(struct pt_regs *regs) 48{ 49 regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY); 50} 51static inline void syscall_clear_error(struct pt_regs *regs) 52{ 53 regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY); 54} 55#endif 56 57static 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 65static 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 73static 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 86static 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 109static 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