syscall.h

00001 /*
00002  * Copyright (C) 2001,2002,2003,2004 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_PPC_SYSCALL_H
00047 #define _RTAI_ASM_PPC_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 Linux's
00054  * implementation of the syscall mechanism in <asm-ppc/unistd.h>:
00055  *
00056  * The following code defines an inline syscall mechanism used by
00057  * Xenomai's real-time interfaces to invoke the skin module services
00058  * in kernel space.
00059  */
00060 
00061 /* Xenomai multiplexer syscall. */
00062 #define __xn_sys_mux    555
00063 /* Xenomai nucleus syscalls. */
00064 #define __xn_sys_attach     0   /* muxid = xnshadow_attach_skin(magic,infp) */
00065 #define __xn_sys_detach     1   /* xnshadow_detach_skin(muxid) */
00066 #define __xn_sys_sync       2   /* xnshadow_sync(&syncflag) */
00067 #define __xn_sys_migrate    3   /* switched = xnshadow_relax/harden() */
00068 #define __xn_sys_barrier    4   /* started = xnshadow_wait_barrier(&entry,&cookie) */
00069 #ifdef CONFIG_RTAI_OPT_TIMESTAMPS
00070 #define __xn_sys_timestamps 5   /* xnpod_get_timestamps(&timestamps) */
00071 #endif /* CONFIG_RTAI_OPT_TIMESTAMPS */
00072 
00073 #define XENOMAI_DO_SYSCALL(nr, id, op, args...)                 \
00074   ({                                                            \
00075         register unsigned long __sc_0  __asm__ ("r0");          \
00076         register unsigned long __sc_3  __asm__ ("r3");          \
00077         register unsigned long __sc_4  __asm__ ("r4");          \
00078         register unsigned long __sc_5  __asm__ ("r5");          \
00079         register unsigned long __sc_6  __asm__ ("r6");          \
00080         register unsigned long __sc_7  __asm__ ("r7");          \
00081                                                                 \
00082         LOADARGS_##nr(__xn_mux_code(id,op), args);              \
00083         __asm__ __volatile__                                    \
00084                 ("sc           \n\t"                            \
00085                  "mfcr %0      "                                \
00086                 : "=&r" (__sc_0),                               \
00087                   "=&r" (__sc_3),  "=&r" (__sc_4),              \
00088                   "=&r" (__sc_5),  "=&r" (__sc_6),              \
00089                   "=&r" (__sc_7)                                \
00090                 : ASM_INPUT_##nr                                \
00091                 : "cr0", "ctr", "memory",                       \
00092                   "r8", "r9", "r10","r11", "r12");              \
00093         (int)((__sc_0 & (1 << 28)) ? -__sc_3 : __sc_3);         \
00094   })
00095 
00096 #define LOADARGS_0(muxcode, dummy...)                           \
00097         __sc_0 = muxcode
00098 #define LOADARGS_1(muxcode, arg1)                               \
00099         LOADARGS_0(muxcode);                                    \
00100         __sc_3 = (unsigned long) (arg1)
00101 #define LOADARGS_2(muxcode, arg1, arg2)                         \
00102         LOADARGS_1(muxcode, arg1);                              \
00103         __sc_4 = (unsigned long) (arg2)
00104 #define LOADARGS_3(muxcode, arg1, arg2, arg3)                   \
00105         LOADARGS_2(muxcode, arg1, arg2);                        \
00106         __sc_5 = (unsigned long) (arg3)
00107 #define LOADARGS_4(muxcode, arg1, arg2, arg3, arg4)             \
00108         LOADARGS_3(muxcode, arg1, arg2, arg3);                  \
00109         __sc_6 = (unsigned long) (arg4)
00110 #define LOADARGS_5(muxcode, arg1, arg2, arg3, arg4, arg5)       \
00111         LOADARGS_4(muxcode, arg1, arg2, arg3, arg4);            \
00112         __sc_7 = (unsigned long) (arg5)
00113 
00114 #define ASM_INPUT_0 "0" (__sc_0)
00115 #define ASM_INPUT_1 ASM_INPUT_0, "1" (__sc_3)
00116 #define ASM_INPUT_2 ASM_INPUT_1, "2" (__sc_4)
00117 #define ASM_INPUT_3 ASM_INPUT_2, "3" (__sc_5)
00118 #define ASM_INPUT_4 ASM_INPUT_3, "4" (__sc_6)
00119 #define ASM_INPUT_5 ASM_INPUT_4, "5" (__sc_7)
00120 
00121 /* Register mapping for accessing syscall args. */
00122 
00123 #define __xn_reg_mux(regs)    ((regs)->gpr[0])
00124 #define __xn_reg_rval(regs)   ((regs)->gpr[3])
00125 #define __xn_reg_arg1(regs)   ((regs)->gpr[3])
00126 #define __xn_reg_arg2(regs)   ((regs)->gpr[4])
00127 #define __xn_reg_arg3(regs)   ((regs)->gpr[5])
00128 #define __xn_reg_arg4(regs)   ((regs)->gpr[6])
00129 #define __xn_reg_arg5(regs)   ((regs)->gpr[7])
00130 
00131 #define __xn_reg_mux_p(regs)        ((__xn_reg_mux(regs) & 0xffff) == __xn_sys_mux)
00132 #define __xn_mux_id(regs)           ((__xn_reg_mux(regs) >> 16) & 0xff)
00133 #define __xn_mux_op(regs)           ((__xn_reg_mux(regs) >> 24) & 0xff)
00134 #define __xn_mux_code(id,op)        ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff))
00135 
00136 #define XENOMAI_SYSCALL0(op)                XENOMAI_DO_SYSCALL(0,0,op)
00137 #define XENOMAI_SYSCALL1(op,a1)             XENOMAI_DO_SYSCALL(1,0,op,a1)
00138 #define XENOMAI_SYSCALL2(op,a1,a2)          XENOMAI_DO_SYSCALL(2,0,op,a1,a2)
00139 #define XENOMAI_SYSCALL3(op,a1,a2,a3)       XENOMAI_DO_SYSCALL(3,0,op,a1,a2,a3)
00140 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4)    XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4)
00141 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
00142 
00143 #define XENOMAI_SKINCALL0(id,op)                XENOMAI_DO_SYSCALL(0,id,op)
00144 #define XENOMAI_SKINCALL1(id,op,a1)             XENOMAI_DO_SYSCALL(1,id,op,a1)
00145 #define XENOMAI_SKINCALL2(id,op,a1,a2)          XENOMAI_DO_SYSCALL(2,id,op,a1,a2)
00146 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3)       XENOMAI_DO_SYSCALL(3,id,op,a1,a2,a3)
00147 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4)    XENOMAI_DO_SYSCALL(4,id,op,a1,a2,a3,a4)
00148 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,id,op,a1,a2,a3,a4,a5)
00149 
00150 typedef struct xnsysinfo {
00151 
00152     unsigned long long cpufreq; /* CPU frequency */
00153     unsigned long tickval;      /* Tick duration (ns) */
00154 
00155 } xnsysinfo_t;
00156 
00157 typedef struct xninquiry {
00158 
00159     char name[32];
00160     int prio;
00161     unsigned long status;
00162     void *khandle;
00163     void *uhandle;
00164 
00165 } xninquiry_t;
00166 
00167 struct task_struct;
00168 
00169 #ifdef __KERNEL__
00170 
00171 #include <linux/errno.h>
00172 #include <asm/uaccess.h>
00173 
00174 #define __xn_copy_from_user(task,dstP,srcP,n)  __copy_from_user(dstP,srcP,n)
00175 #define __xn_copy_to_user(task,dstP,srcP,n)    __copy_to_user(dstP,srcP,n)
00176 #define __xn_put_user(task,src,dstP)           __put_user(src,dstP)
00177 #define __xn_get_user(task,dst,srcP)           __get_user(dst,srcP)
00178 
00179 #define __xn_range_ok(task,addr,size) \
00180         ((addr) <= (task)->thread.fs.seg \
00181          && ((size) == 0 || (size) - 1 <= (task)->thread.fs.seg - (addr)))
00182 
00183 #define __xn_access_ok(task,type,addr,size)  __xn_range_ok(task,(unsigned long)addr,size)
00184 
00185 #define XNARCH_MAX_SYSENT 255
00186 
00187 typedef struct _xnsysent {
00188 
00189     int (*svc)(struct task_struct *task,
00190                struct pt_regs *regs);
00191 
00192 /* Syscall must run into the Linux domain. */
00193 #define __xn_flag_lostage    0x1
00194 /* Syscall must run into the RTAI domain. */
00195 #define __xn_flag_histage    0x2
00196 /* Shadow syscall; caller must be mapped. */
00197 #define __xn_flag_shadow     0x4
00198 /* Context-agnostic syscall. */
00199 #define __xn_flag_anycall    0x0
00200 /* Short-hand for shadow initializing syscall. */
00201 #define __xn_flag_init       __xn_flag_lostage
00202 /* Short-hand for pure shadow syscall in RTAI space. */
00203 #define __xn_flag_regular   (__xn_flag_shadow|__xn_flag_histage)
00204 
00205     u_long flags;
00206 
00207 } xnsysent_t;
00208 
00209 extern int nkgkptd;
00210 
00211 #define xnshadow_ptd(t)    ((t)->ptd[nkgkptd])
00212 #define xnshadow_thread(t) ((xnthread_t *)xnshadow_ptd(t))
00213 
00214 /* Purposedly used inlines and not macros for the following routines
00215    so that we don't risk spurious side-effects on the value arg. */
00216 
00217 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00218     __xn_reg_rval(regs) = v;
00219 }
00220 
00221 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00222     __xn_reg_rval(regs) = v;
00223 }
00224 
00225 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00226     __xn_reg_rval(regs) = v;
00227 }
00228 
00229 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00230     return __xn_reg_rval(regs) == -EINTR;
00231 }
00232 
00233 #else /* !__KERNEL__ */
00234 
00235 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00236 
00237 static inline unsigned long long __xn_rdtsc (void)
00238 
00239 {
00240     unsigned long long t;
00241     unsigned long __tbu;
00242 
00243     __asm__ __volatile__ ("1: mftbu %0\n"
00244                           "mftb %1\n"
00245                           "mftbu %2\n"
00246                           "cmpw %2,%0\n"
00247                           "bne- 1b\n"
00248                           :"=r" (((unsigned long *)&t)[0]),
00249                           "=r" (((unsigned long *)&t)[1]),
00250                           "=r" (__tbu));
00251     return t;
00252 }
00253 
00254 #endif /* __KERNEL__ */
00255 
00256 #endif /* !_RTAI_ASM_PPC_SYSCALL_H */

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