00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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 #ifdef CONFIG_RTAI_HW_X86_VSYSCALL
00030
00031 #include <asm/unistd.h>
00032 #include <sys/prctl.h>
00033 #include <errno.h>
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 #define XENOMAI_SKIN_MUX(nr, id, op, args...) \
00063 ({ \
00064 int resultvar; \
00065 ARGDCL_##nr(args); \
00066 resultvar = prctl(__xn_mux_code(id,op) ARGFMT_##nr(args)); \
00067 resultvar == -1 ? -errno : resultvar; })
00068
00069 #define XENOMAI_SYS_MUX(nr, op, args...) XENOMAI_SKIN_MUX(nr, 0, op, args)
00070
00071 #define __ul(x) ((unsigned long)(x))
00072
00073 #define ARGDCL_0()
00074 #define ARGFMT_0() \
00075 , 0, 0, 0, 0
00076 #define ARGDCL_1(arg1)
00077 #define ARGFMT_1(arg1) \
00078 , 0, 0, 0, __ul(arg1)
00079 #define ARGDCL_2(arg1, arg2)
00080 #define ARGFMT_2(arg1, arg2) \
00081 , __ul(arg2), 0, 0, __ul(arg1)
00082 #define ARGDCL_3(arg1, arg2, arg3)
00083 #define ARGFMT_3(arg1, arg2, arg3) \
00084 , __ul(arg2), __ul(arg3), 0, __ul(arg1)
00085 #define ARGDCL_4(arg1, arg2, arg3, arg4)
00086 #define ARGFMT_4(arg1, arg2, arg3, arg4) \
00087 , __ul(arg2), __ul(arg3), __ul(arg4), __ul(arg1)
00088 #define ARGDCL_5(arg1, arg2, arg3, arg4, arg5) \
00089 unsigned long xargs[2] = { __ul(arg1), __ul(arg5) }
00090 #define ARGFMT_5(arg1, arg2, arg3, arg4, arg5) \
00091 | 0x8000, __ul(arg2), __ul(arg3), __ul(arg4), __ul(xargs)
00092
00093 #else
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 asm (".L__X'%ebx = 1\n\t"
00107 ".L__X'%ecx = 2\n\t"
00108 ".L__X'%edx = 2\n\t"
00109 ".L__X'%eax = 3\n\t"
00110 ".L__X'%esi = 3\n\t"
00111 ".L__X'%edi = 3\n\t"
00112 ".L__X'%ebp = 3\n\t"
00113 ".L__X'%esp = 3\n\t"
00114 ".macro bpushl name reg\n\t"
00115 ".if 1 - \\name\n\t"
00116 ".if 2 - \\name\n\t"
00117 "pushl %ebx\n\t"
00118 ".else\n\t"
00119 "xchgl \\reg, %ebx\n\t"
00120 ".endif\n\t"
00121 ".endif\n\t"
00122 ".endm\n\t"
00123 ".macro bpopl name reg\n\t"
00124 ".if 1 - \\name\n\t"
00125 ".if 2 - \\name\n\t"
00126 "popl %ebx\n\t"
00127 ".else\n\t"
00128 "xchgl \\reg, %ebx\n\t"
00129 ".endif\n\t"
00130 ".endif\n\t"
00131 ".endm\n\t"
00132 ".macro bmovl name reg\n\t"
00133 ".if 1 - \\name\n\t"
00134 ".if 2 - \\name\n\t"
00135 "movl \\reg, %ebx\n\t"
00136 ".endif\n\t"
00137 ".endif\n\t"
00138 ".endm\n\t");
00139
00140 #define XENOMAI_SYS_MUX(nr, op, args...) \
00141 ({ \
00142 unsigned resultvar; \
00143 asm volatile ( \
00144 LOADARGS_##nr \
00145 "movl %1, %%eax\n\t" \
00146 "int $0x80\n\t" \
00147 RESTOREARGS_##nr \
00148 : "=a" (resultvar) \
00149 : "i" (__xn_mux_code(0,op)) ASMFMT_##nr(args) : "memory", "cc"); \
00150 (int) resultvar; })
00151
00152 #define XENOMAI_SKIN_MUX(nr, id, op, args...) \
00153 ({ \
00154 int muxcode = __xn_mux_code(id,op); \
00155 unsigned resultvar; \
00156 asm volatile ( \
00157 LOADARGS_##nr \
00158 "movl %1, %%eax\n\t" \
00159 "int $0x80\n\t" \
00160 RESTOREARGS_##nr \
00161 : "=a" (resultvar) \
00162 : "m" (muxcode) ASMFMT_##nr(args) : "memory", "cc"); \
00163 (int) resultvar; })
00164
00165 #define LOADARGS_0
00166 #define LOADARGS_1 \
00167 "bpushl .L__X'%k2, %k2\n\t" \
00168 "bmovl .L__X'%k2, %k2\n\t"
00169 #define LOADARGS_2 LOADARGS_1
00170 #define LOADARGS_3 LOADARGS_1
00171 #define LOADARGS_4 LOADARGS_1
00172 #define LOADARGS_5 LOADARGS_1
00173
00174 #define RESTOREARGS_0
00175 #define RESTOREARGS_1 \
00176 "bpopl .L__X'%k2, %k2\n\t"
00177 #define RESTOREARGS_2 RESTOREARGS_1
00178 #define RESTOREARGS_3 RESTOREARGS_1
00179 #define RESTOREARGS_4 RESTOREARGS_1
00180 #define RESTOREARGS_5 RESTOREARGS_1
00181
00182 #define ASMFMT_0()
00183 #define ASMFMT_1(arg1) \
00184 , "acdSD" (arg1)
00185 #define ASMFMT_2(arg1, arg2) \
00186 , "adSD" (arg1), "c" (arg2)
00187 #define ASMFMT_3(arg1, arg2, arg3) \
00188 , "aSD" (arg1), "c" (arg2), "d" (arg3)
00189 #define ASMFMT_4(arg1, arg2, arg3, arg4) \
00190 , "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
00191 #define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
00192 , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
00193
00194 #endif
00195
00196 #endif
00197
00198
00199
00200 #define __xn_reg_mux(regs) ((regs)->orig_eax)
00201 #define __xn_reg_rval(regs) ((regs)->eax)
00202 #define __xn_reg_arg1(regs) ((regs)->ebx)
00203 #define __xn_reg_arg2(regs) ((regs)->ecx)
00204 #define __xn_reg_arg3(regs) ((regs)->edx)
00205 #define __xn_reg_arg4(regs) ((regs)->esi)
00206 #define __xn_reg_arg5(regs) ((regs)->edi)
00207
00208 #define __xn_reg_mux_p(regs) ((__xn_reg_mux(regs) & 0x7fff) == __xn_sys_mux)
00209 #define __xn_mux_id(regs) ((__xn_reg_mux(regs) >> 16) & 0xff)
00210 #define __xn_mux_op(regs) ((__xn_reg_mux(regs) >> 24) & 0xff)
00211 #define __xn_mux_code(id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0x7fff))
00212
00213 #define XENOMAI_SYSCALL0(op) XENOMAI_SYS_MUX(0,op)
00214 #define XENOMAI_SYSCALL1(op,a1) XENOMAI_SYS_MUX(1,op,a1)
00215 #define XENOMAI_SYSCALL2(op,a1,a2) XENOMAI_SYS_MUX(2,op,a1,a2)
00216 #define XENOMAI_SYSCALL3(op,a1,a2,a3) XENOMAI_SYS_MUX(3,op,a1,a2,a3)
00217 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4) XENOMAI_SYS_MUX(4,op,a1,a2,a3,a4)
00218 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_SYS_MUX(5,op,a1,a2,a3,a4,a5)
00219
00220 #define XENOMAI_SKINCALL0(id,op) XENOMAI_SKIN_MUX(0,id,op)
00221 #define XENOMAI_SKINCALL1(id,op,a1) XENOMAI_SKIN_MUX(1,id,op,a1)
00222 #define XENOMAI_SKINCALL2(id,op,a1,a2) XENOMAI_SKIN_MUX(2,id,op,a1,a2)
00223 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3) XENOMAI_SKIN_MUX(3,id,op,a1,a2,a3)
00224 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4) XENOMAI_SKIN_MUX(4,id,op,a1,a2,a3,a4)
00225 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_SKIN_MUX(5,id,op,a1,a2,a3,a4,a5)
00226
00227 #ifdef __KERNEL__
00228
00229 #include <linux/errno.h>
00230 #include <asm/uaccess.h>
00231
00232
00233
00234
00235
00236
00237
00238 #define __xn_copy_from_user(task,dstP,srcP,n) \
00239 do { \
00240 if (__copy_from_user_inatomic(dstP,srcP,n)) \
00241 ; \
00242 } while(0)
00243 #define __xn_copy_to_user(task,dstP,srcP,n) \
00244 do { \
00245 if (__copy_to_user_inatomic(dstP,srcP,n)) \
00246 ; \
00247 } while(0)
00248 #define __xn_put_user(task,src,dstP) __put_user(src,dstP)
00249 #define __xn_get_user(task,dst,srcP) __get_user(dst,srcP)
00250
00251 #define __xn_range_ok(task,addr,size) ({ \
00252 unsigned long flag,sum; \
00253 asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \
00254 :"=&r" (flag), "=r" (sum) \
00255 :"1" (addr),"g" ((int)(size)),"g" ((task)->thread_info->addr_limit.seg)); \
00256 flag; })
00257
00258
00259
00260 #define __xn_access_ok(task,type,addr,size) (__xn_range_ok(task,addr,size) == 0)
00261
00262
00263
00264
00265 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00266 __xn_reg_rval(regs) = v;
00267 }
00268
00269 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00270 __xn_reg_rval(regs) = v;
00271 }
00272
00273 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00274 __xn_reg_rval(regs) = v;
00275 }
00276
00277 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00278 return __xn_reg_rval(regs) == -EINTR;
00279 }
00280
00281 #ifdef CONFIG_RTAI_HW_X86_VSYSCALL
00282
00283 #define __xn_canonicalize_args(task,regs) \
00284 do { \
00285 if (__xn_reg_mux(regs) == __NR_prctl && \
00286 ((__xn_reg_arg1(regs) & 0x7fff) == __xn_sys_mux)) { \
00287 __xn_reg_mux(regs) = __xn_reg_arg1(regs); \
00288 if (__xn_reg_arg1(regs) & 0x8000) { \
00289 unsigned long xargs[2]; \
00290 __xn_copy_from_user(task,xargs,(void *)__xn_reg_arg5(regs),sizeof(xargs)); \
00291 __xn_reg_arg1(regs) = xargs[0]; \
00292 __xn_reg_arg5(regs) = xargs[1]; \
00293 } \
00294 else \
00295 __xn_reg_arg1(regs) = __xn_reg_arg5(regs); \
00296 } \
00297 } while(0)
00298
00299 #else
00300
00301 #define __xn_canonicalize_args(task,regs) do { } while(0)
00302
00303 #endif
00304
00305 #else
00306
00307 #ifdef CONFIG_X86_TSC
00308
00309 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00310
00311 static inline unsigned long long __xn_rdtsc (void)
00312
00313 {
00314 unsigned long long t;
00315 __asm__ __volatile__( "rdtsc" : "=A" (t));
00316 return t;
00317 }
00318
00319 #endif
00320
00321 #endif
00322
00323 #endif