xref: /openbmc/linux/arch/ia64/include/asm/syscall.h (revision 9ac8d3fb)
1 /*
2  * Access to user system call parameters and results
3  *
4  * Copyright (C) 2008 Intel Corp.  Shaohua Li <shaohua.li@intel.com>
5  *
6  * This copyrighted material is made available to anyone wishing to use,
7  * modify, copy, or redistribute it subject to the terms and conditions
8  * of the GNU General Public License v.2.
9  *
10  * See asm-generic/syscall.h for descriptions of what we must do here.
11  */
12 
13 #ifndef _ASM_SYSCALL_H
14 #define _ASM_SYSCALL_H	1
15 
16 #include <linux/sched.h>
17 #include <linux/err.h>
18 
19 static inline long syscall_get_nr(struct task_struct *task,
20 				  struct pt_regs *regs)
21 {
22 	if ((long)regs->cr_ifs < 0) /* Not a syscall */
23 		return -1;
24 
25 #ifdef CONFIG_IA32_SUPPORT
26 	if (IS_IA32_PROCESS(regs))
27 		return regs->r1;
28 #endif
29 
30 	return regs->r15;
31 }
32 
33 static inline void syscall_rollback(struct task_struct *task,
34 				    struct pt_regs *regs)
35 {
36 #ifdef CONFIG_IA32_SUPPORT
37 	if (IS_IA32_PROCESS(regs))
38 		regs->r8 = regs->r1;
39 #endif
40 
41 	/* do nothing */
42 }
43 
44 static inline long syscall_get_error(struct task_struct *task,
45 				     struct pt_regs *regs)
46 {
47 #ifdef CONFIG_IA32_SUPPORT
48 	if (IS_IA32_PROCESS(regs))
49 		return regs->r8;
50 #endif
51 
52 	return regs->r10 == -1 ? regs->r8:0;
53 }
54 
55 static inline long syscall_get_return_value(struct task_struct *task,
56 					    struct pt_regs *regs)
57 {
58 	return regs->r8;
59 }
60 
61 static inline void syscall_set_return_value(struct task_struct *task,
62 					    struct pt_regs *regs,
63 					    int error, long val)
64 {
65 #ifdef CONFIG_IA32_SUPPORT
66 	if (IS_IA32_PROCESS(regs)) {
67 		regs->r8 = (long) error ? error : val;
68 		return;
69 	}
70 #endif
71 
72 	if (error) {
73 		/* error < 0, but ia64 uses > 0 return value */
74 		regs->r8 = -error;
75 		regs->r10 = -1;
76 	} else {
77 		regs->r8 = val;
78 		regs->r10 = 0;
79 	}
80 }
81 
82 extern void ia64_syscall_get_set_arguments(struct task_struct *task,
83 	struct pt_regs *regs, unsigned int i, unsigned int n,
84 	unsigned long *args, int rw);
85 static inline void syscall_get_arguments(struct task_struct *task,
86 					 struct pt_regs *regs,
87 					 unsigned int i, unsigned int n,
88 					 unsigned long *args)
89 {
90 	BUG_ON(i + n > 6);
91 
92 #ifdef CONFIG_IA32_SUPPORT
93 	if (IS_IA32_PROCESS(regs)) {
94 		switch (i + n) {
95 		case 6:
96 			if (!n--) break;
97 			*args++ = regs->r13;
98 		case 5:
99 			if (!n--) break;
100 			*args++ = regs->r15;
101 		case 4:
102 			if (!n--) break;
103 			*args++ = regs->r14;
104 		case 3:
105 			if (!n--) break;
106 			*args++ = regs->r10;
107 		case 2:
108 			if (!n--) break;
109 			*args++ = regs->r9;
110 		case 1:
111 			if (!n--) break;
112 			*args++ = regs->r11;
113 		case 0:
114 			if (!n--) break;
115 		default:
116 			BUG();
117 			break;
118 		}
119 
120 		return;
121 	}
122 #endif
123 	ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);
124 }
125 
126 static inline void syscall_set_arguments(struct task_struct *task,
127 					 struct pt_regs *regs,
128 					 unsigned int i, unsigned int n,
129 					 unsigned long *args)
130 {
131 	BUG_ON(i + n > 6);
132 
133 #ifdef CONFIG_IA32_SUPPORT
134 	if (IS_IA32_PROCESS(regs)) {
135 		switch (i + n) {
136 		case 6:
137 			if (!n--) break;
138 			regs->r13 = *args++;
139 		case 5:
140 			if (!n--) break;
141 			regs->r15 = *args++;
142 		case 4:
143 			if (!n--) break;
144 			regs->r14 = *args++;
145 		case 3:
146 			if (!n--) break;
147 			regs->r10 = *args++;
148 		case 2:
149 			if (!n--) break;
150 			regs->r9 = *args++;
151 		case 1:
152 			if (!n--) break;
153 			regs->r11 = *args++;
154 		case 0:
155 			if (!n--) break;
156 		}
157 
158 		return;
159 	}
160 #endif
161 	ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
162 }
163 #endif	/* _ASM_SYSCALL_H */
164