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