/* Copyright (c) 2017 SiFive Inc. All rights reserved. This copyrighted material is made available to anyone wishing to use, modify, copy, or redistribute it subject to the terms and conditions of the FreeBSD License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY expressed or implied, including the implied warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. A copy of this license is available at http://www.opensource.org/licenses. */ #ifndef _INTERNAL_SYSCALL_H #define _INTERNAL_SYSCALL_H #include static inline long __syscall_error(long a0) { errno = -a0; return -1; } static inline long __internal_syscall(long n, long _a0, long _a1, long _a2, long _a3, long _a4, long _a5) { register long a0 asm("a0") = _a0; register long a1 asm("a1") = _a1; register long a2 asm("a2") = _a2; register long a3 asm("a3") = _a3; register long a4 asm("a4") = _a4; register long a5 asm("a5") = _a5; #ifdef __riscv_32e register long syscall_id asm("t0") = n; #else register long syscall_id asm("a7") = n; #endif asm volatile ("scall" : "+r"(a0) : "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5), "r"(syscall_id)); return a0; } static inline long syscall_errno(long n, long _a0, long _a1, long _a2, long _a3, long _a4, long _a5) { long a0 = __internal_syscall (n, _a0, _a1, _a2, _a3, _a4, _a5); if (a0 < 0) return __syscall_error (a0); else return a0; } #endif