License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[linux-2.6-block.git] / arch / sparc / include / asm / syscall.h
CommitLineData
b2441318 1/* SPDX-License-Identifier: GPL-2.0 */
badcbf0e
DM
2#ifndef __ASM_SPARC_SYSCALL_H
3#define __ASM_SPARC_SYSCALL_H
4
ce5d1128 5#include <uapi/linux/audit.h>
badcbf0e 6#include <linux/kernel.h>
203f7907 7#include <linux/compat.h>
badcbf0e
DM
8#include <linux/sched.h>
9#include <asm/ptrace.h>
ce5d1128 10#include <asm/thread_info.h>
badcbf0e 11
e7b8e675
MF
12/*
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.
16 */
17extern const unsigned int sys_call_table[];
18
badcbf0e
DM
19/* The system call number is given by the user in %g1 */
20static inline long syscall_get_nr(struct task_struct *task,
21 struct pt_regs *regs)
22{
23 int syscall_p = pt_regs_is_syscall(regs);
24
25 return (syscall_p ? regs->u_regs[UREG_G1] : -1L);
26}
27
28static inline void syscall_rollback(struct task_struct *task,
29 struct pt_regs *regs)
30{
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.
37 */
38}
39
40#ifdef CONFIG_SPARC32
41static inline bool syscall_has_error(struct pt_regs *regs)
42{
43 return (regs->psr & PSR_C) ? true : false;
44}
45static inline void syscall_set_error(struct pt_regs *regs)
46{
47 regs->psr |= PSR_C;
48}
49static inline void syscall_clear_error(struct pt_regs *regs)
50{
51 regs->psr &= ~PSR_C;
52}
53#else
54static inline bool syscall_has_error(struct pt_regs *regs)
55{
56 return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false;
57}
58static inline void syscall_set_error(struct pt_regs *regs)
59{
60 regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY);
61}
62static inline void syscall_clear_error(struct pt_regs *regs)
63{
64 regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY);
65}
66#endif
67
68static inline long syscall_get_error(struct task_struct *task,
69 struct pt_regs *regs)
70{
71 long val = regs->u_regs[UREG_I0];
72
73 return (syscall_has_error(regs) ? -val : 0);
74}
75
76static inline long syscall_get_return_value(struct task_struct *task,
77 struct pt_regs *regs)
78{
79 long val = regs->u_regs[UREG_I0];
80
81 return val;
82}
83
84static inline void syscall_set_return_value(struct task_struct *task,
85 struct pt_regs *regs,
86 int error, long val)
87{
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;
94 }
95}
96
97static inline void syscall_get_arguments(struct task_struct *task,
98 struct pt_regs *regs,
99 unsigned int i, unsigned int n,
100 unsigned long *args)
101{
102 int zero_extend = 0;
103 unsigned int j;
104
105#ifdef CONFIG_SPARC64
106 if (test_tsk_thread_flag(task, TIF_32BIT))
107 zero_extend = 1;
108#endif
109
110 for (j = 0; j < n; j++) {
111 unsigned long val = regs->u_regs[UREG_I0 + i + j];
112
113 if (zero_extend)
114 args[j] = (u32) val;
115 else
116 args[j] = val;
117 }
118}
119
120static inline void syscall_set_arguments(struct task_struct *task,
121 struct pt_regs *regs,
122 unsigned int i, unsigned int n,
123 const unsigned long *args)
124{
125 unsigned int j;
126
127 for (j = 0; j < n; j++)
128 regs->u_regs[UREG_I0 + i + j] = args[j];
129}
130
ce5d1128
EP
131static inline int syscall_get_arch(void)
132{
203f7907
AL
133#if defined(CONFIG_SPARC64) && defined(CONFIG_COMPAT)
134 return in_compat_syscall() ? 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
ce5d1128
EP
140}
141
badcbf0e 142#endif /* __ASM_SPARC_SYSCALL_H */