xref: /openbmc/linux/arch/nios2/include/asm/syscall.h (revision 1000197d801329804d30094aef5dba0265204d17)
1*1000197dSLey Foon Tan /*
2*1000197dSLey Foon Tan  * Copyright Altera Corporation (C) <2014>. All rights reserved
3*1000197dSLey Foon Tan  *
4*1000197dSLey Foon Tan  * This program is free software; you can redistribute it and/or modify it
5*1000197dSLey Foon Tan  * under the terms and conditions of the GNU General Public License,
6*1000197dSLey Foon Tan  * version 2, as published by the Free Software Foundation.
7*1000197dSLey Foon Tan  *
8*1000197dSLey Foon Tan  * This program is distributed in the hope it will be useful, but WITHOUT
9*1000197dSLey Foon Tan  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10*1000197dSLey Foon Tan  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11*1000197dSLey Foon Tan  * more details.
12*1000197dSLey Foon Tan  *
13*1000197dSLey Foon Tan  * You should have received a copy of the GNU General Public License along with
14*1000197dSLey Foon Tan  * this program.  If not, see <http://www.gnu.org/licenses/>.
15*1000197dSLey Foon Tan  */
16*1000197dSLey Foon Tan 
17*1000197dSLey Foon Tan #ifndef __ASM_NIOS2_SYSCALL_H__
18*1000197dSLey Foon Tan #define __ASM_NIOS2_SYSCALL_H__
19*1000197dSLey Foon Tan 
20*1000197dSLey Foon Tan #include <linux/err.h>
21*1000197dSLey Foon Tan #include <linux/sched.h>
22*1000197dSLey Foon Tan 
23*1000197dSLey Foon Tan static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
24*1000197dSLey Foon Tan {
25*1000197dSLey Foon Tan 	return regs->r2;
26*1000197dSLey Foon Tan }
27*1000197dSLey Foon Tan 
28*1000197dSLey Foon Tan static inline void syscall_rollback(struct task_struct *task,
29*1000197dSLey Foon Tan 				struct pt_regs *regs)
30*1000197dSLey Foon Tan {
31*1000197dSLey Foon Tan 	regs->r2 = regs->orig_r2;
32*1000197dSLey Foon Tan 	regs->r7 = regs->orig_r7;
33*1000197dSLey Foon Tan }
34*1000197dSLey Foon Tan 
35*1000197dSLey Foon Tan static inline long syscall_get_error(struct task_struct *task,
36*1000197dSLey Foon Tan 				struct pt_regs *regs)
37*1000197dSLey Foon Tan {
38*1000197dSLey Foon Tan 	return regs->r7 ? regs->r2 : 0;
39*1000197dSLey Foon Tan }
40*1000197dSLey Foon Tan 
41*1000197dSLey Foon Tan static inline long syscall_get_return_value(struct task_struct *task,
42*1000197dSLey Foon Tan 	struct pt_regs *regs)
43*1000197dSLey Foon Tan {
44*1000197dSLey Foon Tan 	return regs->r2;
45*1000197dSLey Foon Tan }
46*1000197dSLey Foon Tan 
47*1000197dSLey Foon Tan static inline void syscall_set_return_value(struct task_struct *task,
48*1000197dSLey Foon Tan 	struct pt_regs *regs, int error, long val)
49*1000197dSLey Foon Tan {
50*1000197dSLey Foon Tan 	if (error) {
51*1000197dSLey Foon Tan 		/* error < 0, but nios2 uses > 0 return value */
52*1000197dSLey Foon Tan 		regs->r2 = -error;
53*1000197dSLey Foon Tan 		regs->r7 = 1;
54*1000197dSLey Foon Tan 	} else {
55*1000197dSLey Foon Tan 		regs->r2 = val;
56*1000197dSLey Foon Tan 		regs->r7 = 0;
57*1000197dSLey Foon Tan 	}
58*1000197dSLey Foon Tan }
59*1000197dSLey Foon Tan 
60*1000197dSLey Foon Tan static inline void syscall_get_arguments(struct task_struct *task,
61*1000197dSLey Foon Tan 	struct pt_regs *regs, unsigned int i, unsigned int n,
62*1000197dSLey Foon Tan 	unsigned long *args)
63*1000197dSLey Foon Tan {
64*1000197dSLey Foon Tan 	BUG_ON(i + n > 6);
65*1000197dSLey Foon Tan 
66*1000197dSLey Foon Tan 	switch (i) {
67*1000197dSLey Foon Tan 	case 0:
68*1000197dSLey Foon Tan 		if (!n--)
69*1000197dSLey Foon Tan 			break;
70*1000197dSLey Foon Tan 		*args++ = regs->r4;
71*1000197dSLey Foon Tan 	case 1:
72*1000197dSLey Foon Tan 		if (!n--)
73*1000197dSLey Foon Tan 			break;
74*1000197dSLey Foon Tan 		*args++ = regs->r5;
75*1000197dSLey Foon Tan 	case 2:
76*1000197dSLey Foon Tan 		if (!n--)
77*1000197dSLey Foon Tan 			break;
78*1000197dSLey Foon Tan 		*args++ = regs->r6;
79*1000197dSLey Foon Tan 	case 3:
80*1000197dSLey Foon Tan 		if (!n--)
81*1000197dSLey Foon Tan 			break;
82*1000197dSLey Foon Tan 		*args++ = regs->r7;
83*1000197dSLey Foon Tan 	case 4:
84*1000197dSLey Foon Tan 		if (!n--)
85*1000197dSLey Foon Tan 			break;
86*1000197dSLey Foon Tan 		*args++ = regs->r8;
87*1000197dSLey Foon Tan 	case 5:
88*1000197dSLey Foon Tan 		if (!n--)
89*1000197dSLey Foon Tan 			break;
90*1000197dSLey Foon Tan 		*args++ = regs->r9;
91*1000197dSLey Foon Tan 	case 6:
92*1000197dSLey Foon Tan 		if (!n--)
93*1000197dSLey Foon Tan 			break;
94*1000197dSLey Foon Tan 	default:
95*1000197dSLey Foon Tan 		BUG();
96*1000197dSLey Foon Tan 	}
97*1000197dSLey Foon Tan }
98*1000197dSLey Foon Tan 
99*1000197dSLey Foon Tan static inline void syscall_set_arguments(struct task_struct *task,
100*1000197dSLey Foon Tan 	struct pt_regs *regs, unsigned int i, unsigned int n,
101*1000197dSLey Foon Tan 	const unsigned long *args)
102*1000197dSLey Foon Tan {
103*1000197dSLey Foon Tan 	BUG_ON(i + n > 6);
104*1000197dSLey Foon Tan 
105*1000197dSLey Foon Tan 	switch (i) {
106*1000197dSLey Foon Tan 	case 0:
107*1000197dSLey Foon Tan 		if (!n--)
108*1000197dSLey Foon Tan 			break;
109*1000197dSLey Foon Tan 		regs->r4 = *args++;
110*1000197dSLey Foon Tan 	case 1:
111*1000197dSLey Foon Tan 		if (!n--)
112*1000197dSLey Foon Tan 			break;
113*1000197dSLey Foon Tan 		regs->r5 = *args++;
114*1000197dSLey Foon Tan 	case 2:
115*1000197dSLey Foon Tan 		if (!n--)
116*1000197dSLey Foon Tan 			break;
117*1000197dSLey Foon Tan 		regs->r6 = *args++;
118*1000197dSLey Foon Tan 	case 3:
119*1000197dSLey Foon Tan 		if (!n--)
120*1000197dSLey Foon Tan 			break;
121*1000197dSLey Foon Tan 		regs->r7 = *args++;
122*1000197dSLey Foon Tan 	case 4:
123*1000197dSLey Foon Tan 		if (!n--)
124*1000197dSLey Foon Tan 			break;
125*1000197dSLey Foon Tan 		regs->r8 = *args++;
126*1000197dSLey Foon Tan 	case 5:
127*1000197dSLey Foon Tan 		if (!n--)
128*1000197dSLey Foon Tan 			break;
129*1000197dSLey Foon Tan 		regs->r9 = *args++;
130*1000197dSLey Foon Tan 	case 6:
131*1000197dSLey Foon Tan 		if (!n)
132*1000197dSLey Foon Tan 			break;
133*1000197dSLey Foon Tan 	default:
134*1000197dSLey Foon Tan 		BUG();
135*1000197dSLey Foon Tan 	}
136*1000197dSLey Foon Tan }
137*1000197dSLey Foon Tan 
138*1000197dSLey Foon Tan #endif
139