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