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. The apparently
00135    preposterous do-while bracketing just helps silencing GCC's
00136    "warn_unused_result" attribute on the related kernel macros. */
00137 #define __xn_copy_from_user(task,dstP,srcP,n)  \
00138 do { \
00139     if (__copy_from_user_inatomic(dstP,srcP,n)) \
00140         ; \
00141 } while(0)
00142 #define __xn_copy_to_user(task,dstP,srcP,n)  \
00143 do { \
00144     if (__copy_to_user_inatomic(dstP,srcP,n)) \
00145         ; \
00146 } while(0)
00147 #define __xn_put_user(task,src,dstP)  __put_user(src,dstP)
00148 #define __xn_get_user(task,dst,srcP)  __get_user(dst,srcP)
00149 
00150 #define __xn_get_fs(task) (((task)->thread_info)->addr_limit)
00151 
00152 #define __xn_access_ok(task,type,addr,size) \
00153     __access_ok((addr),(size), __xn_get_fs(task))
00154 
00155 /* Purposedly used inlines and not macros for the following routines
00156    so that we don't risk spurious side-effects on the value arg. */
00157 
00158 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00159     __xn_reg_err(regs) = 0;
00160     __xn_reg_rval(regs) = v;
00161 }
00162 
00163 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00164     __xn_reg_err(regs) = -1;
00165     __xn_reg_rval(regs) = -v;
00166 }
00167 
00168 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00169     if(v < 0)
00170         __xn_error_return(regs, v);
00171     else
00172         __xn_success_return(regs, v);
00173 }
00174 
00175 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00176     return __xn_reg_err(regs) == -1 && __xn_reg_rval(regs) == -EINTR;
00177 }
00178 
00179 #define __xn_canonicalize_args(task,regs) do { } while(0)
00180 
00181 #else /* !__KERNEL__ */
00182 
00183 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00184 
00185 static inline unsigned long long __xn_rdtsc (void)
00186 
00187 {
00188     unsigned long long t;
00189     __asm__ __volatile__("mov %0=ar.itc;;" : "=r"(t) :: "memory");
00190     return t;
00191 }
00192 
00193 #endif /* __KERNEL__ */
00194 
00195 #endif /* !_RTAI_ASM_IA64_SYSCALL_H */

Generated on Wed Jun 22 22:54:02 2005 for RTAI Fusion API by  doxygen 1.4.1