syscall.h

00001 /*
00002  * Copyright (C) 2001,2002,2003 Philippe Gerum <rpm@xenomai.org>.
00003  *
00004  * RTAI/fusion is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published
00006  * by the Free Software Foundation; either version 2 of the License,
00007  * or (at your option) any later version.
00008  *
00009  * RTAI/fusion is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with RTAI/fusion; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
00017  * 02111-1307, USA.
00018  */
00019 
00020 #ifndef _RTAI_ASM_I386_SYSCALL_H
00021 #define _RTAI_ASM_I386_SYSCALL_H
00022 
00023 #include <rtai_config.h>
00024 #include <asm/ptrace.h>
00025 #include <nucleus/asm-generic/syscall.h>
00026 
00027 #ifndef __KERNEL__
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 services
00037  * in kernel space.
00038  */
00039 
00040 #ifdef CONFIG_RTAI_HW_X86_SEP
00041 /* This form relies on the kernel's vsyscall support in order to use
00042    the SEP instructions which must be supported by the hardware. We
00043    also depend on the NPTL providing us a pointer to the vsyscall DSO
00044    entry point, to which we branch to instead of issuing a trap. */
00045 #define DOSYSCALL  "call *%%gs:0x10\n\t"
00046 #else /* CONFIG_RTAI_HW_X86_SEP */
00047 #define DOSYSCALL  "int $0x80\n\t"
00048 #endif /* CONFIG_RTAI_HW_X86_SEP */
00049 
00050 asm (".L__X'%ebx = 1\n\t"
00051      ".L__X'%ecx = 2\n\t"
00052      ".L__X'%edx = 2\n\t"
00053      ".L__X'%eax = 3\n\t"
00054      ".L__X'%esi = 3\n\t"
00055      ".L__X'%edi = 3\n\t"
00056      ".L__X'%ebp = 3\n\t"
00057      ".L__X'%esp = 3\n\t"
00058      ".macro bpushl name reg\n\t"
00059      ".if 1 - \\name\n\t"
00060      ".if 2 - \\name\n\t"
00061      "pushl %ebx\n\t"
00062      ".else\n\t"
00063      "xchgl \\reg, %ebx\n\t"
00064      ".endif\n\t"
00065      ".endif\n\t"
00066      ".endm\n\t"
00067      ".macro bpopl name reg\n\t"
00068      ".if 1 - \\name\n\t"
00069      ".if 2 - \\name\n\t"
00070      "popl %ebx\n\t"
00071      ".else\n\t"
00072      "xchgl \\reg, %ebx\n\t"
00073      ".endif\n\t"
00074      ".endif\n\t"
00075      ".endm\n\t"
00076      ".macro bmovl name reg\n\t"
00077      ".if 1 - \\name\n\t"
00078      ".if 2 - \\name\n\t"
00079      "movl \\reg, %ebx\n\t"
00080      ".endif\n\t"
00081      ".endif\n\t"
00082      ".endm\n\t");
00083 
00084 #define XENOMAI_SYS_MUX(nr, op, args...) \
00085   ({                                                                  \
00086     unsigned resultvar;                                               \
00087     asm volatile (                                                    \
00088     LOADARGS_##nr                                                     \
00089     "movl %1, %%eax\n\t"                                              \
00090     DOSYSCALL                                                         \
00091     RESTOREARGS_##nr                                                  \
00092     : "=a" (resultvar)                                                \
00093     : "i" (__xn_mux_code(0,op)) ASMFMT_##nr(args) : "memory", "cc");  \
00094     (int) resultvar; })
00095 
00096 #define XENOMAI_SKIN_MUX(nr, id, op, args...) \
00097   ({                                                                  \
00098     int muxcode = __xn_mux_code(id,op);                               \
00099     unsigned resultvar;                                               \
00100     asm volatile (                                                    \
00101     LOADARGS_##nr                                                     \
00102     "movl %1, %%eax\n\t"                                              \
00103     DOSYSCALL                                                         \
00104     RESTOREARGS_##nr                                                  \
00105     : "=a" (resultvar)                                                \
00106     : "m" (muxcode) ASMFMT_##nr(args) : "memory", "cc");              \
00107     (int) resultvar; })
00108 
00109 #define LOADARGS_0
00110 #define LOADARGS_1 \
00111     "bpushl .L__X'%k2, %k2\n\t" \
00112     "bmovl .L__X'%k2, %k2\n\t"
00113 #define LOADARGS_2      LOADARGS_1
00114 #define LOADARGS_3      LOADARGS_1
00115 #define LOADARGS_4      LOADARGS_1
00116 #define LOADARGS_5      LOADARGS_1
00117 
00118 #define RESTOREARGS_0
00119 #define RESTOREARGS_1 \
00120     "bpopl .L__X'%k2, %k2\n\t"
00121 #define RESTOREARGS_2   RESTOREARGS_1
00122 #define RESTOREARGS_3   RESTOREARGS_1
00123 #define RESTOREARGS_4   RESTOREARGS_1
00124 #define RESTOREARGS_5   RESTOREARGS_1
00125 
00126 #define ASMFMT_0()
00127 #define ASMFMT_1(arg1) \
00128         , "acdSD" (arg1)
00129 #define ASMFMT_2(arg1, arg2) \
00130         , "adSD" (arg1), "c" (arg2)
00131 #define ASMFMT_3(arg1, arg2, arg3) \
00132         , "aSD" (arg1), "c" (arg2), "d" (arg3)
00133 #define ASMFMT_4(arg1, arg2, arg3, arg4) \
00134         , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
00135 #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
00136         , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
00137 
00138 #endif /* !__KERNEL__ */
00139 
00140 /* Register mapping for accessing syscall args. */
00141 
00142 #define __xn_reg_mux(regs)    ((regs)->orig_eax)
00143 #define __xn_reg_rval(regs)   ((regs)->eax)
00144 #define __xn_reg_arg1(regs)   ((regs)->ebx)
00145 #define __xn_reg_arg2(regs)   ((regs)->ecx)
00146 #define __xn_reg_arg3(regs)   ((regs)->edx)
00147 #define __xn_reg_arg4(regs)   ((regs)->esi)
00148 #define __xn_reg_arg5(regs)   ((regs)->edi)
00149 
00150 #define __xn_reg_mux_p(regs)  ((__xn_reg_mux(regs) & 0x7fff) == __xn_sys_mux)
00151 #define __xn_mux_id(regs)     ((__xn_reg_mux(regs) >> 16) & 0xff)
00152 #define __xn_mux_op(regs)     ((__xn_reg_mux(regs) >> 24) & 0xff)
00153 #define __xn_mux_code(id,op)  ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0x7fff))
00154 
00155 #define XENOMAI_SYSCALL0(op)                XENOMAI_SYS_MUX(0,op)
00156 #define XENOMAI_SYSCALL1(op,a1)             XENOMAI_SYS_MUX(1,op,a1)
00157 #define XENOMAI_SYSCALL2(op,a1,a2)          XENOMAI_SYS_MUX(2,op,a1,a2)
00158 #define XENOMAI_SYSCALL3(op,a1,a2,a3)       XENOMAI_SYS_MUX(3,op,a1,a2,a3)
00159 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    XENOMAI_SYS_MUX(4,op,a1,a2,a3,a4)
00160 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_SYS_MUX(5,op,a1,a2,a3,a4,a5)
00161 
00162 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_SKIN_MUX(0,id,op)
00163 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_SKIN_MUX(1,id,op,a1)
00164 #define XENOMAI_SKINCALL2(id,op,a1,a2)          XENOMAI_SKIN_MUX(2,id,op,a1,a2)
00165 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3)       XENOMAI_SKIN_MUX(3,id,op,a1,a2,a3)
00166 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4)    XENOMAI_SKIN_MUX(4,id,op,a1,a2,a3,a4)
00167 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_SKIN_MUX(5,id,op,a1,a2,a3,a4,a5)
00168 
00169 #ifdef __KERNEL__
00170 
00171 #include <linux/errno.h>
00172 #include <asm/uaccess.h>
00173 
00174 /* Our own set of copy-to/from-user macros which must bypass
00175    might_sleep() checks. The caller cannot fault and is expected to
00176    have checked for bad range before using the copy macros, so we
00177    should not have to care about the result. */
00178 #define __xn_copy_from_user(task,dstP,srcP,n)  \
00179     ({ int err = __copy_from_user_inatomic(dstP,srcP,n); err; })
00180 #define __xn_copy_to_user(task,dstP,srcP,n)  \
00181     ({ int err = __copy_to_user_inatomic(dstP,srcP,n); err; })
00182 #define __xn_put_user(task,src,dstP)           __put_user(src,dstP)
00183 #define __xn_get_user(task,dst,srcP)           __get_user(dst,srcP)
00184 #define __xn_strncpy_from_user(task,dstP,srcP,n)    rthal_strncpy_from_user(dstP,srcP,n)
00185 
00186 #define __xn_range_ok(task,addr,size) ({ \
00187         unsigned long flag,sum; \
00188         asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \
00189                 :"=&r" (flag), "=r" (sum) \
00190                 :"1" (addr),"g" ((int)(size)),"g" ((task)->thread_info->addr_limit.seg)); \
00191         flag == 0; })
00192 
00193 /* WP bit must work for using the shadow support, so we only need
00194    trivial range checking here. */
00195 #define __xn_access_ok(task,type,addr,size)    (__xn_range_ok(task,addr,size))
00196 
00197 /* Purposedly used inlines and not macros for the following routines
00198    so that we don't risk spurious side-effects on the value arg. */
00199 
00200 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00201     __xn_reg_rval(regs) = v;
00202 }
00203 
00204 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00205     __xn_reg_rval(regs) = v;
00206 }
00207 
00208 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00209     __xn_reg_rval(regs) = v;
00210 }
00211 
00212 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00213     return __xn_reg_rval(regs) == -EINTR;
00214 }
00215 
00216 #else /* !__KERNEL__ */
00217 
00218 #ifdef CONFIG_X86_TSC
00219 
00220 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00221 
00222 static inline unsigned long long __xn_rdtsc (void)
00223 
00224 {
00225     unsigned long long t;
00226     __asm__ __volatile__( "rdtsc" : "=A" (t));
00227     return t;
00228 }
00229 
00230 #endif  /* CONFIG_X86_TSC */
00231 
00232 #endif /* __KERNEL__ */
00233 
00234 #endif /* !_RTAI_ASM_I386_SYSCALL_H */

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