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