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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifdef CONFIG_RTAI_HW_X86_SEP
00041
00042
00043
00044
00045 #define DOSYSCALL "call *%%gs:0x10\n\t"
00046 #else
00047 #define DOSYSCALL "int $0x80\n\t"
00048 #endif
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
00139
00140
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
00175
00176
00177
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
00194
00195 #define __xn_access_ok(task,type,addr,size) (__xn_range_ok(task,addr,size))
00196
00197
00198
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
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
00231
00232 #endif
00233
00234 #endif