syscall.h

00001 /*
00002  * Copyright (C) 2001,2002,2003 Philippe Gerum <rpm@xenomai.org>.
00003  *
00004  * Xenomai is free software; you can redistribute it and/or modify it
00005  * under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * Xenomai 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 Xenomai; if not, write to the Free Software Foundation,
00016  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  *
00018  * As a special exception, the RTAI project gives permission
00019  * for additional uses of the text contained in its release of
00020  * Xenomai.
00021  *
00022  * The exception is that, if you link the Xenomai libraries with other
00023  * files to produce an executable, this does not by itself cause the
00024  * resulting executable to be covered by the GNU General Public License.
00025  * Your use of that executable is in no way restricted on account of
00026  * linking the Xenomai libraries code into it.
00027  *
00028  * This exception does not however invalidate any other reasons why
00029  * the executable file might be covered by the GNU General Public
00030  * License.
00031  *
00032  * This exception applies only to the code released by the
00033  * RTAI project under the name Xenomai.  If you copy code from other
00034  * RTAI project releases into a copy of Xenomai, as the General Public
00035  * License permits, the exception does not apply to the code that you
00036  * add in this way.  To avoid misleading anyone as to the status of
00037  * such modified files, you must delete this exception notice from
00038  * them.
00039  *
00040  * If you write modifications of your own for Xenomai, it is your
00041  * choice whether to permit this exception to apply to your
00042  * modifications. If you do not wish that, delete this exception
00043  * notice.
00044  */
00045 
00046 #ifndef _RTAI_ASM_I386_SYSCALL_H
00047 #define _RTAI_ASM_I386_SYSCALL_H
00048 
00049 #include <rtai_config.h>
00050 #include <asm/ptrace.h>
00051 
00052 /*
00053  * Some of the following macros have been adapted from glibc's syscall
00054  * mechanism implementation:
00055  * Copyright (C) 1992,1993,1995-2000,2002,2003 Free Software Foundation, Inc.
00056  * Contributed by Ulrich Drepper, <drepper@gnu.org>, August 1995.
00057  *
00058  * The following code defines an inline syscall mechanism used by
00059  * Xenomai's real-time interfaces to invoke the skin module services
00060  * in kernel space.
00061  */
00062 
00063 /* Xenomai multiplexer syscall. */
00064 #define __xn_sys_mux    555
00065 /* Xenomai nucleus syscalls. */
00066 #define __xn_sys_attach     0   /* muxid = xnshadow_attach_skin(magic,infp) */
00067 #define __xn_sys_detach     1   /* xnshadow_detach_skin(muxid) */
00068 #define __xn_sys_sync       2   /* xnshadow_sync(&syncflag) */
00069 #define __xn_sys_migrate    3   /* switched = xnshadow_relax/harden() */
00070 #define __xn_sys_barrier    4   /* started = xnshadow_wait_barrier(&entry,&cookie) */
00071 #ifdef CONFIG_RTAI_OPT_TIMESTAMPS
00072 #define __xn_sys_timestamps 5   /* xnpod_get_timestamps(&timestamps) */
00073 #endif /* CONFIG_RTAI_OPT_TIMESTAMPS */
00074 
00075 asm (".L__X'%ebx = 1\n\t"
00076      ".L__X'%ecx = 2\n\t"
00077      ".L__X'%edx = 2\n\t"
00078      ".L__X'%eax = 3\n\t"
00079      ".L__X'%esi = 3\n\t"
00080      ".L__X'%edi = 3\n\t"
00081      ".L__X'%ebp = 3\n\t"
00082      ".L__X'%esp = 3\n\t"
00083      ".macro bpushl name reg\n\t"
00084      ".if 1 - \\name\n\t"
00085      ".if 2 - \\name\n\t"
00086      "pushl %ebx\n\t"
00087      ".else\n\t"
00088      "xchgl \\reg, %ebx\n\t"
00089      ".endif\n\t"
00090      ".endif\n\t"
00091      ".endm\n\t"
00092      ".macro bpopl name reg\n\t"
00093      ".if 1 - \\name\n\t"
00094      ".if 2 - \\name\n\t"
00095      "popl %ebx\n\t"
00096      ".else\n\t"
00097      "xchgl \\reg, %ebx\n\t"
00098      ".endif\n\t"
00099      ".endif\n\t"
00100      ".endm\n\t"
00101      ".macro bmovl name reg\n\t"
00102      ".if 1 - \\name\n\t"
00103      ".if 2 - \\name\n\t"
00104      "movl \\reg, %ebx\n\t"
00105      ".endif\n\t"
00106      ".endif\n\t"
00107      ".endm\n\t");
00108 
00109 #define XENOMAI_SYS_MUX(nr, op, args...) \
00110   ({                                                                  \
00111     unsigned resultvar;                                               \
00112     asm volatile (                                                    \
00113     LOADARGS_##nr                                                     \
00114     "movl %1, %%eax\n\t"                                              \
00115     "int $0x80\n\t"                                                   \
00116     RESTOREARGS_##nr                                                  \
00117     : "=a" (resultvar)                                                \
00118     : "i" (__xn_mux_code(0,op)) ASMFMT_##nr(args) : "memory", "cc");  \
00119     (int) resultvar; })
00120 
00121 #define XENOMAI_SKIN_MUX(nr, id, op, args...) \
00122   ({                                                                  \
00123     int muxcode = __xn_mux_code(id,op);                               \
00124     unsigned resultvar;                                               \
00125     asm volatile (                                                    \
00126     LOADARGS_##nr                                                     \
00127     "movl %1, %%eax\n\t"                                              \
00128     "int $0x80\n\t"                                                   \
00129     RESTOREARGS_##nr                                                  \
00130     : "=a" (resultvar)                                                \
00131     : "m" (muxcode) ASMFMT_##nr(args) : "memory", "cc");              \
00132     (int) resultvar; })
00133 
00134 #define LOADARGS_0
00135 #define LOADARGS_1 \
00136     "bpushl .L__X'%k2, %k2\n\t" \
00137     "bmovl .L__X'%k2, %k2\n\t"
00138 #define LOADARGS_2      LOADARGS_1
00139 #define LOADARGS_3      LOADARGS_1
00140 #define LOADARGS_4      LOADARGS_1
00141 #define LOADARGS_5      LOADARGS_1
00142 
00143 #define RESTOREARGS_0
00144 #define RESTOREARGS_1 \
00145     "bpopl .L__X'%k2, %k2\n\t"
00146 #define RESTOREARGS_2   RESTOREARGS_1
00147 #define RESTOREARGS_3   RESTOREARGS_1
00148 #define RESTOREARGS_4   RESTOREARGS_1
00149 #define RESTOREARGS_5   RESTOREARGS_1
00150 
00151 #define ASMFMT_0()
00152 #define ASMFMT_1(arg1) \
00153         , "acdSD" (arg1)
00154 #define ASMFMT_2(arg1, arg2) \
00155         , "adSD" (arg1), "c" (arg2)
00156 #define ASMFMT_3(arg1, arg2, arg3) \
00157         , "aSD" (arg1), "c" (arg2), "d" (arg3)
00158 #define ASMFMT_4(arg1, arg2, arg3, arg4) \
00159         , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
00160 #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
00161         , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
00162 
00163 /* Register mapping for accessing syscall args. */
00164 
00165 #define __xn_reg_mux(regs)    ((regs)->orig_eax)
00166 #define __xn_reg_rval(regs)   ((regs)->eax)
00167 #define __xn_reg_arg1(regs)   ((regs)->ebx)
00168 #define __xn_reg_arg2(regs)   ((regs)->ecx)
00169 #define __xn_reg_arg3(regs)   ((regs)->edx)
00170 #define __xn_reg_arg4(regs)   ((regs)->esi)
00171 #define __xn_reg_arg5(regs)   ((regs)->edi)
00172 
00173 #define __xn_reg_mux_p(regs)        ((__xn_reg_mux(regs) & 0xffff) == __xn_sys_mux)
00174 #define __xn_mux_id(regs)           ((__xn_reg_mux(regs) >> 16) & 0xff)
00175 #define __xn_mux_op(regs)           ((__xn_reg_mux(regs) >> 24) & 0xff)
00176 #define __xn_mux_code(id,op)        ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff))
00177 
00178 #define XENOMAI_SYSCALL0(op)                XENOMAI_SYS_MUX(0,op)
00179 #define XENOMAI_SYSCALL1(op,a1)             XENOMAI_SYS_MUX(1,op,a1)
00180 #define XENOMAI_SYSCALL2(op,a1,a2)          XENOMAI_SYS_MUX(2,op,a1,a2)
00181 #define XENOMAI_SYSCALL3(op,a1,a2,a3)       XENOMAI_SYS_MUX(3,op,a1,a2,a3)
00182 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    XENOMAI_SYS_MUX(4,op,a1,a2,a3,a4)
00183 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_SYS_MUX(5,op,a1,a2,a3,a4,a5)
00184 
00185 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_SKIN_MUX(0,id,op)
00186 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_SKIN_MUX(1,id,op,a1)
00187 #define XENOMAI_SKINCALL2(id,op,a1,a2)          XENOMAI_SKIN_MUX(2,id,op,a1,a2)
00188 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3)       XENOMAI_SKIN_MUX(3,id,op,a1,a2,a3)
00189 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4)    XENOMAI_SKIN_MUX(4,id,op,a1,a2,a3,a4)
00190 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_SKIN_MUX(5,id,op,a1,a2,a3,a4,a5)
00191 
00192 typedef struct xnsysinfo {
00193 
00194     unsigned long long cpufreq; /* CPU frequency */
00195     unsigned long tickval;      /* Tick duration (ns) */
00196 
00197 } xnsysinfo_t;
00198 
00199 typedef struct xninquiry {
00200 
00201     char name[32];
00202     int prio;
00203     unsigned long status;
00204     void *khandle;
00205     void *uhandle;
00206 
00207 } xninquiry_t;
00208 
00209 struct task_struct;
00210 
00211 #ifdef __KERNEL__
00212 
00213 #include <linux/errno.h>
00214 #include <asm/uaccess.h>
00215 
00216 #define __xn_copy_from_user(task,dstP,srcP,n)  __copy_from_user(dstP,srcP,n)
00217 #define __xn_copy_to_user(task,dstP,srcP,n)    __copy_to_user(dstP,srcP,n)
00218 #define __xn_put_user(task,src,dstP)           __put_user(src,dstP)
00219 #define __xn_get_user(task,dst,srcP)           __get_user(dst,srcP)
00220 
00221 #define __xn_range_ok(task,addr,size) ({ \
00222         unsigned long flag,sum; \
00223         asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \
00224                 :"=&r" (flag), "=r" (sum) \
00225                 :"1" (addr),"g" ((int)(size)),"g" ((task)->thread_info->addr_limit.seg)); \
00226         flag; })
00227 
00228 /* WP bit must work for using the shadow support, so we only need
00229    trivial range checking here. */
00230 #define __xn_access_ok(task,type,addr,size)    (__xn_range_ok(task,addr,size) == 0)
00231 
00232 #define XNARCH_MAX_SYSENT 255
00233 
00234 typedef struct _xnsysent {
00235 
00236     int (*svc)(struct task_struct *task,
00237                struct pt_regs *regs);
00238 
00239 /* Syscall must run into the Linux domain. */
00240 #define __xn_flag_lostage    0x1
00241 /* Syscall must run into the RTAI domain. */
00242 #define __xn_flag_histage    0x2
00243 /* Shadow syscall; caller must be mapped. */
00244 #define __xn_flag_shadow     0x4
00245 /* Context-agnostic syscall. */
00246 #define __xn_flag_anycall    0x0
00247 /* Short-hand for shadow initializing syscall. */
00248 #define __xn_flag_init       __xn_flag_lostage
00249 /* Short-hand for pure shadow syscall in RTAI space. */
00250 #define __xn_flag_regular   (__xn_flag_shadow|__xn_flag_histage)
00251 
00252     u_long flags;
00253 
00254 } xnsysent_t;
00255 
00256 extern int nkgkptd;
00257 
00258 #define xnshadow_ptd(t)    ((t)->ptd[nkgkptd])
00259 #define xnshadow_thread(t) ((xnthread_t *)xnshadow_ptd(t))
00260 
00261 /* Purposedly used inlines and not macros for the following routines
00262    so that we don't risk spurious side-effects on the value arg. */
00263 
00264 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00265     __xn_reg_rval(regs) = v;
00266 }
00267 
00268 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00269     __xn_reg_rval(regs) = v;
00270 }
00271 
00272 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00273     __xn_reg_rval(regs) = v;
00274 }
00275 
00276 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00277     return __xn_reg_rval(regs) == -EINTR;
00278 }
00279 
00280 #else /* !__KERNEL__ */
00281 
00282 #ifdef CONFIG_X86_TSC
00283 
00284 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00285 
00286 static inline unsigned long long __xn_rdtsc (void)
00287 
00288 {
00289     unsigned long long t;
00290     __asm__ __volatile__( "rdtsc" : "=A" (t));
00291     return t;
00292 }
00293 
00294 #endif  /* CONFIG_X86_TSC */
00295 
00296 #endif /* __KERNEL__ */
00297 
00298 #endif /* !_RTAI_ASM_I386_SYSCALL_H */

Generated on Mon Dec 13 09:49:49 2004 for RTAI API by  doxygen 1.3.9.1