Linux 5.7.6
[linux/fpc-iii.git] / arch / sparc / include / asm / syscall.h
blob62a5a78804c46d76f5155d337117f8c7fee0baf1
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __ASM_SPARC_SYSCALL_H
3 #define __ASM_SPARC_SYSCALL_H
5 #include <uapi/linux/audit.h>
6 #include <linux/kernel.h>
7 #include <linux/compat.h>
8 #include <linux/sched.h>
9 #include <asm/ptrace.h>
10 #include <asm/thread_info.h>
13 * The syscall table always contains 32 bit pointers since we know that the
14 * address of the function to be called is (way) below 4GB. So the "int"
15 * type here is what we want [need] for both 32 bit and 64 bit systems.
17 extern const unsigned int sys_call_table[];
19 /* The system call number is given by the user in %g1 */
20 static inline long syscall_get_nr(struct task_struct *task,
21 struct pt_regs *regs)
23 int syscall_p = pt_regs_is_syscall(regs);
25 return (syscall_p ? regs->u_regs[UREG_G1] : -1L);
28 static inline void syscall_rollback(struct task_struct *task,
29 struct pt_regs *regs)
31 /* XXX This needs some thought. On Sparc we don't
32 * XXX save away the original %o0 value somewhere.
33 * XXX Instead we hold it in register %l5 at the top
34 * XXX level trap frame and pass this down to the signal
35 * XXX dispatch code which is the only place that value
36 * XXX ever was needed.
40 #ifdef CONFIG_SPARC32
41 static inline bool syscall_has_error(struct pt_regs *regs)
43 return (regs->psr & PSR_C) ? true : false;
45 static inline void syscall_set_error(struct pt_regs *regs)
47 regs->psr |= PSR_C;
49 static inline void syscall_clear_error(struct pt_regs *regs)
51 regs->psr &= ~PSR_C;
53 #else
54 static inline bool syscall_has_error(struct pt_regs *regs)
56 return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false;
58 static inline void syscall_set_error(struct pt_regs *regs)
60 regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY);
62 static inline void syscall_clear_error(struct pt_regs *regs)
64 regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY);
66 #endif
68 static inline long syscall_get_error(struct task_struct *task,
69 struct pt_regs *regs)
71 long val = regs->u_regs[UREG_I0];
73 return (syscall_has_error(regs) ? -val : 0);
76 static inline long syscall_get_return_value(struct task_struct *task,
77 struct pt_regs *regs)
79 long val = regs->u_regs[UREG_I0];
81 return val;
84 static inline void syscall_set_return_value(struct task_struct *task,
85 struct pt_regs *regs,
86 int error, long val)
88 if (error) {
89 syscall_set_error(regs);
90 regs->u_regs[UREG_I0] = -error;
91 } else {
92 syscall_clear_error(regs);
93 regs->u_regs[UREG_I0] = val;
97 static inline void syscall_get_arguments(struct task_struct *task,
98 struct pt_regs *regs,
99 unsigned long *args)
101 int zero_extend = 0;
102 unsigned int j;
103 unsigned int n = 6;
105 #ifdef CONFIG_SPARC64
106 if (test_tsk_thread_flag(task, TIF_32BIT))
107 zero_extend = 1;
108 #endif
110 for (j = 0; j < n; j++) {
111 unsigned long val = regs->u_regs[UREG_I0 + j];
113 if (zero_extend)
114 args[j] = (u32) val;
115 else
116 args[j] = val;
120 static inline void syscall_set_arguments(struct task_struct *task,
121 struct pt_regs *regs,
122 const unsigned long *args)
124 unsigned int i;
126 for (i = 0; i < 6; i++)
127 regs->u_regs[UREG_I0 + i] = args[i];
130 static inline int syscall_get_arch(struct task_struct *task)
132 #if defined(CONFIG_SPARC64) && defined(CONFIG_COMPAT)
133 return test_tsk_thread_flag(task, TIF_32BIT)
134 ? AUDIT_ARCH_SPARC : AUDIT_ARCH_SPARC64;
135 #elif defined(CONFIG_SPARC64)
136 return AUDIT_ARCH_SPARC64;
137 #else
138 return AUDIT_ARCH_SPARC;
139 #endif
142 #endif /* __ASM_SPARC_SYSCALL_H */