syscall.h

00001 /*
00002  * RTAI/fusion 64-bit PowerPC adoption
00003  * Copyright (C) 2005 Taneli Vähäkangas and Heikki Lindholm
00004  * based on previous work:
00005  *     
00006  * Copyright (C) 2001,2002,2003,2004 Philippe Gerum <rpm@xenomai.org>.
00007  *
00008  * RTAI/fusion is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012  *
00013  * RTAI/fusion is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with RTAI/fusion; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00021  * 02111-1307, USA.
00022  */
00023 
00024 #ifndef _RTAI_ASM_PPC64_SYSCALL_H
00025 #define _RTAI_ASM_PPC64_SYSCALL_H
00026 
00027 #include <rtai_config.h>
00028 #include <asm/ptrace.h>
00029 #include <nucleus/asm-generic/syscall.h>
00030 
00031 /*
00032  * Some of the following macros have been adapted from Linux's
00033  * implementation of the syscall mechanism in <asm-ppc64/unistd.h>:
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_DO_SYSCALL(nr, id, op, args...)                 \
00041   ({                                                            \
00042         register unsigned long __sc_0  __asm__ ("r0");          \
00043         register unsigned long __sc_3  __asm__ ("r3");          \
00044         register unsigned long __sc_4  __asm__ ("r4");          \
00045         register unsigned long __sc_5  __asm__ ("r5");          \
00046         register unsigned long __sc_6  __asm__ ("r6");          \
00047         register unsigned long __sc_7  __asm__ ("r7");          \
00048                                                                 \
00049         LOADARGS_##nr(__xn_mux_code(id,op), args);              \
00050         __asm__ __volatile__                                    \
00051                 ("sc           \n\t"                            \
00052                  "mfcr %0      "                                \
00053                 : "=&r" (__sc_0),                               \
00054                   "=&r" (__sc_3),  "=&r" (__sc_4),              \
00055                   "=&r" (__sc_5),  "=&r" (__sc_6),              \
00056                   "=&r" (__sc_7)                                \
00057                 : ASM_INPUT_##nr                                \
00058                 : "cr0", "ctr", "memory",                       \
00059                   "r8", "r9", "r10","r11", "r12");              \
00060         (int)((__sc_0 & (1 << 28)) ? -__sc_3 : __sc_3);         \
00061   })
00062 
00063 #define LOADARGS_0(muxcode, dummy...)                           \
00064         __sc_0 = muxcode
00065 #define LOADARGS_1(muxcode, arg1)                               \
00066         LOADARGS_0(muxcode);                                    \
00067         __sc_3 = (unsigned long) (arg1)
00068 #define LOADARGS_2(muxcode, arg1, arg2)                         \
00069         LOADARGS_1(muxcode, arg1);                              \
00070         __sc_4 = (unsigned long) (arg2)
00071 #define LOADARGS_3(muxcode, arg1, arg2, arg3)                   \
00072         LOADARGS_2(muxcode, arg1, arg2);                        \
00073         __sc_5 = (unsigned long) (arg3)
00074 #define LOADARGS_4(muxcode, arg1, arg2, arg3, arg4)             \
00075         LOADARGS_3(muxcode, arg1, arg2, arg3);                  \
00076         __sc_6 = (unsigned long) (arg4)
00077 #define LOADARGS_5(muxcode, arg1, arg2, arg3, arg4, arg5)       \
00078         LOADARGS_4(muxcode, arg1, arg2, arg3, arg4);            \
00079         __sc_7 = (unsigned long) (arg5)
00080 
00081 #define ASM_INPUT_0 "0" (__sc_0)
00082 #define ASM_INPUT_1 ASM_INPUT_0, "1" (__sc_3)
00083 #define ASM_INPUT_2 ASM_INPUT_1, "2" (__sc_4)
00084 #define ASM_INPUT_3 ASM_INPUT_2, "3" (__sc_5)
00085 #define ASM_INPUT_4 ASM_INPUT_3, "4" (__sc_6)
00086 #define ASM_INPUT_5 ASM_INPUT_4, "5" (__sc_7)
00087 
00088 /* Register mapping for accessing syscall args. */
00089 
00090 #define __xn_reg_mux(regs)    ((regs)->gpr[0])
00091 #define __xn_reg_rval(regs)   ((regs)->gpr[3])
00092 #define __xn_reg_arg1(regs)   ((regs)->gpr[3])
00093 #define __xn_reg_arg2(regs)   ((regs)->gpr[4])
00094 #define __xn_reg_arg3(regs)   ((regs)->gpr[5])
00095 #define __xn_reg_arg4(regs)   ((regs)->gpr[6])
00096 #define __xn_reg_arg5(regs)   ((regs)->gpr[7])
00097 
00098 #define __xn_reg_mux_p(regs)        ((__xn_reg_mux(regs) & 0xffff) == __xn_sys_mux)
00099 #define __xn_mux_id(regs)           ((__xn_reg_mux(regs) >> 16) & 0xff)
00100 #define __xn_mux_op(regs)           ((__xn_reg_mux(regs) >> 24) & 0xff)
00101 #define __xn_mux_code(id,op)        ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff))
00102 
00103 #define XENOMAI_SYSCALL0(op)                XENOMAI_DO_SYSCALL(0,0,op)
00104 #define XENOMAI_SYSCALL1(op,a1)             XENOMAI_DO_SYSCALL(1,0,op,a1)
00105 #define XENOMAI_SYSCALL2(op,a1,a2)          XENOMAI_DO_SYSCALL(2,0,op,a1,a2)
00106 #define XENOMAI_SYSCALL3(op,a1,a2,a3)       XENOMAI_DO_SYSCALL(3,0,op,a1,a2,a3)
00107 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4)
00108 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
00109 
00110 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_DO_SYSCALL(0,id,op)
00111 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_DO_SYSCALL(1,id,op,a1)
00112 #define XENOMAI_SKINCALL2(id,op,a1,a2)          XENOMAI_DO_SYSCALL(2,id,op,a1,a2)
00113 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3)       XENOMAI_DO_SYSCALL(3,id,op,a1,a2,a3)
00114 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4)    XENOMAI_DO_SYSCALL(4,id,op,a1,a2,a3,a4)
00115 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,id,op,a1,a2,a3,a4,a5)
00116 
00117 #ifdef __KERNEL__
00118 
00119 #include <linux/errno.h>
00120 #include <asm/uaccess.h>
00121 
00122 /* Our own set of copy-to/from-user macros which must bypass
00123    might_sleep() checks. The caller cannot fault and is expected to
00124    have checked for bad range before using the copy macros, so we
00125    should not have to care about the result. */
00126 #define __xn_copy_from_user(task,dstP,srcP,n)  \
00127     ({ int err = __copy_from_user_inatomic(dstP,srcP,n); err; })
00128 #define __xn_copy_to_user(task,dstP,srcP,n)  \
00129     ({ int err = __copy_to_user_inatomic(dstP,srcP,n); err; })
00130 #define __xn_put_user(task,src,dstP)           __put_user(src,dstP)
00131 #define __xn_get_user(task,dst,srcP)           __get_user(dst,srcP)
00132 #define __xn_strncpy_from_user(task,dstP,srcP,n)    __strncpy_from_user(dstP,srcP,n)
00133 
00134 #define __xn_range_ok(task,addr,size) \
00135         __access_ok(((__force unsigned long)(addr)),(size),(task->thread.fs))
00136 
00137 #define __xn_access_ok(task,type,addr,size)  __xn_range_ok(task,addr,size)
00138 
00139 /* Purposedly used inlines and not macros for the following routines
00140    so that we don't risk spurious side-effects on the value arg. */
00141 
00142 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00143     __xn_reg_rval(regs) = v;
00144 }
00145 
00146 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00147     /* We currently never set the SO bit for marking errors, even if
00148      * we always test it upon syscall return. */
00149     __xn_reg_rval(regs) = v;
00150 }
00151 
00152 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00153     __xn_reg_rval(regs) = v;
00154 }
00155 
00156 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00157     return __xn_reg_rval(regs) == -EINTR;
00158 }
00159 
00160 #else /* !__KERNEL__ */
00161 
00162 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00163 
00164 static inline unsigned long long __xn_rdtsc (void)
00165 
00166 {
00167     unsigned long long t;
00168 
00169     __asm__ __volatile__ ("mftb %0\n" : "=r" (t));
00170     return t;
00171 }
00172 
00173 #endif /* __KERNEL__ */
00174 
00175 #endif /* !_RTAI_ASM_PPC_SYSCALL_H */

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