xref: /openbmc/linux/arch/nios2/include/asm/syscall.h (revision 1660aac45e5b49a5ace29fb5b73254617533fcbd)
11000197dSLey Foon Tan /*
21000197dSLey Foon Tan  * Copyright Altera Corporation (C) <2014>. All rights reserved
31000197dSLey Foon Tan  *
41000197dSLey Foon Tan  * This program is free software; you can redistribute it and/or modify it
51000197dSLey Foon Tan  * under the terms and conditions of the GNU General Public License,
61000197dSLey Foon Tan  * version 2, as published by the Free Software Foundation.
71000197dSLey Foon Tan  *
81000197dSLey Foon Tan  * This program is distributed in the hope it will be useful, but WITHOUT
91000197dSLey Foon Tan  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
101000197dSLey Foon Tan  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
111000197dSLey Foon Tan  * more details.
121000197dSLey Foon Tan  *
131000197dSLey Foon Tan  * You should have received a copy of the GNU General Public License along with
141000197dSLey Foon Tan  * this program.  If not, see <http://www.gnu.org/licenses/>.
151000197dSLey Foon Tan  */
161000197dSLey Foon Tan 
171000197dSLey Foon Tan #ifndef __ASM_NIOS2_SYSCALL_H__
181000197dSLey Foon Tan #define __ASM_NIOS2_SYSCALL_H__
191000197dSLey Foon Tan 
20*1660aac4SDmitry V. Levin #include <uapi/linux/audit.h>
211000197dSLey Foon Tan #include <linux/err.h>
221000197dSLey Foon Tan #include <linux/sched.h>
231000197dSLey Foon Tan 
241000197dSLey Foon Tan static inline int syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
251000197dSLey Foon Tan {
261000197dSLey Foon Tan 	return regs->r2;
271000197dSLey Foon Tan }
281000197dSLey Foon Tan 
291000197dSLey Foon Tan static inline void syscall_rollback(struct task_struct *task,
301000197dSLey Foon Tan 				struct pt_regs *regs)
311000197dSLey Foon Tan {
321000197dSLey Foon Tan 	regs->r2 = regs->orig_r2;
331000197dSLey Foon Tan 	regs->r7 = regs->orig_r7;
341000197dSLey Foon Tan }
351000197dSLey Foon Tan 
361000197dSLey Foon Tan static inline long syscall_get_error(struct task_struct *task,
371000197dSLey Foon Tan 				struct pt_regs *regs)
381000197dSLey Foon Tan {
391000197dSLey Foon Tan 	return regs->r7 ? regs->r2 : 0;
401000197dSLey Foon Tan }
411000197dSLey Foon Tan 
421000197dSLey Foon Tan static inline long syscall_get_return_value(struct task_struct *task,
431000197dSLey Foon Tan 	struct pt_regs *regs)
441000197dSLey Foon Tan {
451000197dSLey Foon Tan 	return regs->r2;
461000197dSLey Foon Tan }
471000197dSLey Foon Tan 
481000197dSLey Foon Tan static inline void syscall_set_return_value(struct task_struct *task,
491000197dSLey Foon Tan 	struct pt_regs *regs, int error, long val)
501000197dSLey Foon Tan {
511000197dSLey Foon Tan 	if (error) {
521000197dSLey Foon Tan 		/* error < 0, but nios2 uses > 0 return value */
531000197dSLey Foon Tan 		regs->r2 = -error;
541000197dSLey Foon Tan 		regs->r7 = 1;
551000197dSLey Foon Tan 	} else {
561000197dSLey Foon Tan 		regs->r2 = val;
571000197dSLey Foon Tan 		regs->r7 = 0;
581000197dSLey Foon Tan 	}
591000197dSLey Foon Tan }
601000197dSLey Foon Tan 
611000197dSLey Foon Tan static inline void syscall_get_arguments(struct task_struct *task,
621000197dSLey Foon Tan 	struct pt_regs *regs, unsigned int i, unsigned int n,
631000197dSLey Foon Tan 	unsigned long *args)
641000197dSLey Foon Tan {
651000197dSLey Foon Tan 	BUG_ON(i + n > 6);
661000197dSLey Foon Tan 
671000197dSLey Foon Tan 	switch (i) {
681000197dSLey Foon Tan 	case 0:
691000197dSLey Foon Tan 		if (!n--)
701000197dSLey Foon Tan 			break;
711000197dSLey Foon Tan 		*args++ = regs->r4;
721000197dSLey Foon Tan 	case 1:
731000197dSLey Foon Tan 		if (!n--)
741000197dSLey Foon Tan 			break;
751000197dSLey Foon Tan 		*args++ = regs->r5;
761000197dSLey Foon Tan 	case 2:
771000197dSLey Foon Tan 		if (!n--)
781000197dSLey Foon Tan 			break;
791000197dSLey Foon Tan 		*args++ = regs->r6;
801000197dSLey Foon Tan 	case 3:
811000197dSLey Foon Tan 		if (!n--)
821000197dSLey Foon Tan 			break;
831000197dSLey Foon Tan 		*args++ = regs->r7;
841000197dSLey Foon Tan 	case 4:
851000197dSLey Foon Tan 		if (!n--)
861000197dSLey Foon Tan 			break;
871000197dSLey Foon Tan 		*args++ = regs->r8;
881000197dSLey Foon Tan 	case 5:
891000197dSLey Foon Tan 		if (!n--)
901000197dSLey Foon Tan 			break;
911000197dSLey Foon Tan 		*args++ = regs->r9;
921000197dSLey Foon Tan 	case 6:
931000197dSLey Foon Tan 		if (!n--)
941000197dSLey Foon Tan 			break;
951000197dSLey Foon Tan 	default:
961000197dSLey Foon Tan 		BUG();
971000197dSLey Foon Tan 	}
981000197dSLey Foon Tan }
991000197dSLey Foon Tan 
1001000197dSLey Foon Tan static inline void syscall_set_arguments(struct task_struct *task,
1011000197dSLey Foon Tan 	struct pt_regs *regs, unsigned int i, unsigned int n,
1021000197dSLey Foon Tan 	const unsigned long *args)
1031000197dSLey Foon Tan {
1041000197dSLey Foon Tan 	BUG_ON(i + n > 6);
1051000197dSLey Foon Tan 
1061000197dSLey Foon Tan 	switch (i) {
1071000197dSLey Foon Tan 	case 0:
1081000197dSLey Foon Tan 		if (!n--)
1091000197dSLey Foon Tan 			break;
1101000197dSLey Foon Tan 		regs->r4 = *args++;
1111000197dSLey Foon Tan 	case 1:
1121000197dSLey Foon Tan 		if (!n--)
1131000197dSLey Foon Tan 			break;
1141000197dSLey Foon Tan 		regs->r5 = *args++;
1151000197dSLey Foon Tan 	case 2:
1161000197dSLey Foon Tan 		if (!n--)
1171000197dSLey Foon Tan 			break;
1181000197dSLey Foon Tan 		regs->r6 = *args++;
1191000197dSLey Foon Tan 	case 3:
1201000197dSLey Foon Tan 		if (!n--)
1211000197dSLey Foon Tan 			break;
1221000197dSLey Foon Tan 		regs->r7 = *args++;
1231000197dSLey Foon Tan 	case 4:
1241000197dSLey Foon Tan 		if (!n--)
1251000197dSLey Foon Tan 			break;
1261000197dSLey Foon Tan 		regs->r8 = *args++;
1271000197dSLey Foon Tan 	case 5:
1281000197dSLey Foon Tan 		if (!n--)
1291000197dSLey Foon Tan 			break;
1301000197dSLey Foon Tan 		regs->r9 = *args++;
1311000197dSLey Foon Tan 	case 6:
1321000197dSLey Foon Tan 		if (!n)
1331000197dSLey Foon Tan 			break;
1341000197dSLey Foon Tan 	default:
1351000197dSLey Foon Tan 		BUG();
1361000197dSLey Foon Tan 	}
1371000197dSLey Foon Tan }
1381000197dSLey Foon Tan 
139*1660aac4SDmitry V. Levin static inline int syscall_get_arch(void)
140*1660aac4SDmitry V. Levin {
141*1660aac4SDmitry V. Levin 	return AUDIT_ARCH_NIOS2;
142*1660aac4SDmitry V. Levin }
143*1660aac4SDmitry V. Levin 
1441000197dSLey Foon Tan #endif
145