Commit | Line | Data |
---|---|---|
badcbf0e DM |
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 | ||
e7b8e675 MF |
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 | */ | |
13 | extern const unsigned int sys_call_table[]; | |
14 | ||
badcbf0e DM |
15 | /* The system call number is given by the user in %g1 */ |
16 | static 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 | ||
24 | static inline void syscall_rollback(struct task_struct *task, | |
25 | struct pt_regs *regs) | |
26 | { | |
27 | /* XXX This needs some thought. On Sparc we don't | |
28 | * XXX save away the original %o0 value somewhere. | |
29 | * XXX Instead we hold it in register %l5 at the top | |
30 | * XXX level trap frame and pass this down to the signal | |
31 | * XXX dispatch code which is the only place that value | |
32 | * XXX ever was needed. | |
33 | */ | |
34 | } | |
35 | ||
36 | #ifdef CONFIG_SPARC32 | |
37 | static inline bool syscall_has_error(struct pt_regs *regs) | |
38 | { | |
39 | return (regs->psr & PSR_C) ? true : false; | |
40 | } | |
41 | static inline void syscall_set_error(struct pt_regs *regs) | |
42 | { | |
43 | regs->psr |= PSR_C; | |
44 | } | |
45 | static inline void syscall_clear_error(struct pt_regs *regs) | |
46 | { | |
47 | regs->psr &= ~PSR_C; | |
48 | } | |
49 | #else | |
50 | static inline bool syscall_has_error(struct pt_regs *regs) | |
51 | { | |
52 | return (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)) ? true : false; | |
53 | } | |
54 | static inline void syscall_set_error(struct pt_regs *regs) | |
55 | { | |
56 | regs->tstate |= (TSTATE_XCARRY | TSTATE_ICARRY); | |
57 | } | |
58 | static inline void syscall_clear_error(struct pt_regs *regs) | |
59 | { | |
60 | regs->tstate &= ~(TSTATE_XCARRY | TSTATE_ICARRY); | |
61 | } | |
62 | #endif | |
63 | ||
64 | static inline long syscall_get_error(struct task_struct *task, | |
65 | struct pt_regs *regs) | |
66 | { | |
67 | long val = regs->u_regs[UREG_I0]; | |
68 | ||
69 | return (syscall_has_error(regs) ? -val : 0); | |
70 | } | |
71 | ||
72 | static inline long syscall_get_return_value(struct task_struct *task, | |
73 | struct pt_regs *regs) | |
74 | { | |
75 | long val = regs->u_regs[UREG_I0]; | |
76 | ||
77 | return val; | |
78 | } | |
79 | ||
80 | static inline void syscall_set_return_value(struct task_struct *task, | |
81 | struct pt_regs *regs, | |
82 | int error, long val) | |
83 | { | |
84 | if (error) { | |
85 | syscall_set_error(regs); | |
86 | regs->u_regs[UREG_I0] = -error; | |
87 | } else { | |
88 | syscall_clear_error(regs); | |
89 | regs->u_regs[UREG_I0] = val; | |
90 | } | |
91 | } | |
92 | ||
93 | static inline void syscall_get_arguments(struct task_struct *task, | |
94 | struct pt_regs *regs, | |
95 | unsigned int i, unsigned int n, | |
96 | unsigned long *args) | |
97 | { | |
98 | int zero_extend = 0; | |
99 | unsigned int j; | |
100 | ||
101 | #ifdef CONFIG_SPARC64 | |
102 | if (test_tsk_thread_flag(task, TIF_32BIT)) | |
103 | zero_extend = 1; | |
104 | #endif | |
105 | ||
106 | for (j = 0; j < n; j++) { | |
107 | unsigned long val = regs->u_regs[UREG_I0 + i + j]; | |
108 | ||
109 | if (zero_extend) | |
110 | args[j] = (u32) val; | |
111 | else | |
112 | args[j] = val; | |
113 | } | |
114 | } | |
115 | ||
116 | static inline void syscall_set_arguments(struct task_struct *task, | |
117 | struct pt_regs *regs, | |
118 | unsigned int i, unsigned int n, | |
119 | const unsigned long *args) | |
120 | { | |
121 | unsigned int j; | |
122 | ||
123 | for (j = 0; j < n; j++) | |
124 | regs->u_regs[UREG_I0 + i + j] = args[j]; | |
125 | } | |
126 | ||
127 | #endif /* __ASM_SPARC_SYSCALL_H */ |