syscall.h

00001 /*
00002  * Copyright &copy; 2001,2002,2003,2004 Philippe Gerum <rpm@xenomai.org>.
00003  * Copyright &copy; 2004 The HYADES project <http://www.hyades-itea.org>
00004  *
00005  * RTAI/fusion is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License as published
00007  * by the Free Software Foundation; either version 2 of the License,
00008  * or (at your option) any later version.
00009  *
00010  * RTAI/fusion is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with RTAI/fusion; if not, write to the Free Software
00017  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00018  * 02111-1307, USA.
00019  */
00020 
00021 #ifndef _RTAI_ASM_IA64_SYSCALL_H
00022 #define _RTAI_ASM_IA64_SYSCALL_H
00023 
00024 #include <rtai_config.h>
00025 #include <asm/ptrace.h>
00026 #include <asm/unistd.h>
00027 #include <nucleus/asm-generic/syscall.h>
00028 
00029 /*
00030  * Some of the following macros have been adapted from glibc's syscall
00031  * mechanism implementation:
00032  * Copyright (C) 1992,1993,1995-2000,2002,2003 Free Software Foundation, Inc.
00033  * Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
00034  *
00035  * The following code defines an inline syscall mechanism used by
00036  * RTAI/fusion's real-time interfaces to invoke the skin module
00037  * services in kernel space.
00038  */
00039 
00040 #define XENOMAI_SKIN_MUX(nr, id, op, args...)                   \
00041   ({                                                            \
00042     register long _r15 asm ("r15") = (__xn_mux_code(id,op));    \
00043     register long _retval asm ("r8");                           \
00044     register long err asm ("r10");                              \
00045     LOAD_ARGS_##nr (args);                                      \
00046     __asm __volatile ("break %3;;\n\t"                          \
00047                       : "=r" (_retval), "=r" (_r15), "=r" (err) \
00048                       : "i" (__BREAK_SYSCALL), "1" (_r15)       \
00049                         ASM_ARGS_##nr                           \
00050                       : "memory" ASM_CLOBBERS_##nr);            \
00051     err < 0 ? -_retval : _retval; })
00052 
00053 #define XENOMAI_SYS_MUX(nr, op, args...) XENOMAI_SKIN_MUX(nr, 0, op , ##args)
00054 
00055 #define LOAD_ARGS_0()   do { } while (0)
00056 #define LOAD_ARGS_1(out0)                               \
00057   register long _out0 asm ("out0") = (long) (out0);     \
00058   LOAD_ARGS_0 ()
00059 #define LOAD_ARGS_2(out0, out1)                         \
00060   register long _out1 asm ("out1") = (long) (out1);     \
00061     LOAD_ARGS_1 (out0)                                  
00062 #define LOAD_ARGS_3(out0, out1, out2)                   \
00063   register long _out2 asm ("out2") = (long) (out2);     \
00064   LOAD_ARGS_2 (out0, out1)
00065 #define LOAD_ARGS_4(out0, out1, out2, out3)             \
00066   register long _out3 asm ("out3") = (long) (out3);     \
00067   LOAD_ARGS_3 (out0, out1, out2)
00068 #define LOAD_ARGS_5(out0, out1, out2, out3, out4)       \
00069   register long _out4 asm ("out4") = (long) (out4);     \
00070   LOAD_ARGS_4 (out0, out1, out2, out3)
00071 
00072 #define ASM_ARGS_0
00073 #define ASM_ARGS_1      ASM_ARGS_0, "r" (_out0)
00074 #define ASM_ARGS_2      ASM_ARGS_1, "r" (_out1)
00075 #define ASM_ARGS_3      ASM_ARGS_2, "r" (_out2)
00076 #define ASM_ARGS_4      ASM_ARGS_3, "r" (_out3)
00077 #define ASM_ARGS_5      ASM_ARGS_4, "r" (_out4)
00078 
00079 #define ASM_CLOBBERS_0  ASM_CLOBBERS_1, "out0"
00080 #define ASM_CLOBBERS_1  ASM_CLOBBERS_2, "out1"
00081 #define ASM_CLOBBERS_2  ASM_CLOBBERS_3, "out2"
00082 #define ASM_CLOBBERS_3  ASM_CLOBBERS_4, "out3"
00083 #define ASM_CLOBBERS_4  ASM_CLOBBERS_5, "out4"
00084 #define ASM_CLOBBERS_5  , "out5", "out6", "out7",                       \
00085   /* Non-stacked integer registers, minus r8, r10, r15.  */             \
00086   "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17",           \
00087   "r18", "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \
00088   "r28", "r29", "r30", "r31",                                           \
00089   /* Predicate registers.  */                                           \
00090   "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15",     \
00091   /* Non-rotating fp registers.  */                                     \
00092   "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",     \
00093   /* Branch registers.  */                                              \
00094   "b6", "b7"
00095 
00096 /* Register mapping for accessing syscall args. */
00097 
00098 #define __xn_reg_mux(regs)    (regs->r15)
00099 #define __xn_reg_rval(regs)   (regs->r8)
00100 #define __xn_reg_err(regs)    (regs->r10)
00101 #define __xn_reg_arg1(regs)   (regs->r16)
00102 #define __xn_reg_arg2(regs)   (regs->r17)
00103 #define __xn_reg_arg3(regs)   (regs->r18)
00104 #define __xn_reg_arg4(regs)   (regs->r19)
00105 #define __xn_reg_arg5(regs)   (regs->r20)
00106 
00107 #define __xn_reg_mux_p(regs)        ((__xn_reg_mux(regs) & 0xffff) == __xn_sys_mux)
00108 #define __xn_mux_id(regs)           ((__xn_reg_mux(regs) >> 16) & 0xff)
00109 #define __xn_mux_op(regs)           ((__xn_reg_mux(regs) >> 24) & 0xff)
00110 #define __xn_mux_code(id,op)        ((op << 24)|(((id << 16) & 0xff0000UL)|(__xn_sys_mux & 0xffffUL)))
00111 
00112 #define XENOMAI_SYSCALL0(op)                XENOMAI_SYS_MUX(0,op)
00113 #define XENOMAI_SYSCALL1(op,a1)             XENOMAI_SYS_MUX(1,op,a1)
00114 #define XENOMAI_SYSCALL2(op,a1,a2)          XENOMAI_SYS_MUX(2,op,a1,a2)
00115 #define XENOMAI_SYSCALL3(op,a1,a2,a3)       XENOMAI_SYS_MUX(3,op,a1,a2,a3)
00116 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    XENOMAI_SYS_MUX(4,op,a1,a2,a3,a4)
00117 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_SYS_MUX(5,op,a1,a2,a3,a4,a5)
00118 
00119 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_SKIN_MUX(0,id,op)
00120 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_SKIN_MUX(1,id,op,a1)
00121 #define XENOMAI_SKINCALL2(id,op,a1,a2)          XENOMAI_SKIN_MUX(2,id,op,a1,a2)
00122 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3)       XENOMAI_SKIN_MUX(3,id,op,a1,a2,a3)
00123 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4)    XENOMAI_SKIN_MUX(4,id,op,a1,a2,a3,a4)
00124 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_SKIN_MUX(5,id,op,a1,a2,a3,a4,a5)
00125 
00126 #ifdef __KERNEL__
00127 
00128 #include <linux/errno.h>
00129 #include <asm/uaccess.h>
00130 
00131 /* Our own set of copy-to/from-user macros which must bypass
00132    might_sleep() checks. The caller cannot fault and is expected to
00133    have checked for bad range before using the copy macros, so we
00134    should not have to care about the result. */
00135 #define __xn_copy_from_user(task,dstP,srcP,n)  \
00136     ({ int err = __copy_from_user_inatomic(dstP,srcP,n); err; })
00137 #define __xn_copy_to_user(task,dstP,srcP,n)  \
00138     ({ int err = __copy_to_user_inatomic(dstP,srcP,n); err; })
00139 #define __xn_put_user(task,src,dstP)          __put_user(src,dstP)
00140 #define __xn_get_user(task,dst,srcP)          __get_user(dst,srcP)
00141 #define __xn_strncpy_from_user(task,dstP,srcP,n)   __strncpy_from_user(dstP,srcP,n)
00142 
00143 #define __xn_get_fs(task) (((task)->thread_info)->addr_limit)
00144 
00145 #define __xn_access_ok(task,type,addr,size) \
00146     __access_ok((addr),(size), __xn_get_fs(task))
00147 
00148 /* Purposedly used inlines and not macros for the following routines
00149    so that we don't risk spurious side-effects on the value arg. */
00150 
00151 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00152     __xn_reg_err(regs) = 0;
00153     __xn_reg_rval(regs) = v;
00154 }
00155 
00156 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00157     __xn_reg_err(regs) = -1;
00158     __xn_reg_rval(regs) = -v;
00159 }
00160 
00161 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00162     if(v < 0)
00163         __xn_error_return(regs, v);
00164     else
00165         __xn_success_return(regs, v);
00166 }
00167 
00168 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00169     return __xn_reg_err(regs) == -1 && __xn_reg_rval(regs) == -EINTR;
00170 }
00171 
00172 #else /* !__KERNEL__ */
00173 
00174 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00175 
00176 static inline unsigned long long __xn_rdtsc (void)
00177 
00178 {
00179     unsigned long long t;
00180     __asm__ __volatile__("mov %0=ar.itc;;" : "=r"(t) :: "memory");
00181     return t;
00182 }
00183 
00184 #endif /* __KERNEL__ */
00185 
00186 #endif /* !_RTAI_ASM_IA64_SYSCALL_H */

Generated on Sat Sep 3 12:32:46 2005 for RTAI Fusion API by  doxygen 1.4.2