00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _RTAI_ASM_PPC_SYSCALL_H
00021 #define _RTAI_ASM_PPC_SYSCALL_H
00022
00023 #include <rtai_config.h>
00024 #include <asm/ptrace.h>
00025 #include <nucleus/asm-generic/syscall.h>
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #define XENOMAI_DO_SYSCALL(nr, id, op, args...) \
00037 ({ \
00038 register unsigned long __sc_0 __asm__ ("r0"); \
00039 register unsigned long __sc_3 __asm__ ("r3"); \
00040 register unsigned long __sc_4 __asm__ ("r4"); \
00041 register unsigned long __sc_5 __asm__ ("r5"); \
00042 register unsigned long __sc_6 __asm__ ("r6"); \
00043 register unsigned long __sc_7 __asm__ ("r7"); \
00044 \
00045 LOADARGS_##nr(__xn_mux_code(id,op), args); \
00046 __asm__ __volatile__ \
00047 ("sc \n\t" \
00048 "mfcr %0 " \
00049 : "=&r" (__sc_0), \
00050 "=&r" (__sc_3), "=&r" (__sc_4), \
00051 "=&r" (__sc_5), "=&r" (__sc_6), \
00052 "=&r" (__sc_7) \
00053 : ASM_INPUT_##nr \
00054 : "cr0", "ctr", "memory", \
00055 "r8", "r9", "r10","r11", "r12"); \
00056 (int)((__sc_0 & (1 << 28)) ? -__sc_3 : __sc_3); \
00057 })
00058
00059 #define LOADARGS_0(muxcode, dummy...) \
00060 __sc_0 = muxcode
00061 #define LOADARGS_1(muxcode, arg1) \
00062 LOADARGS_0(muxcode); \
00063 __sc_3 = (unsigned long) (arg1)
00064 #define LOADARGS_2(muxcode, arg1, arg2) \
00065 LOADARGS_1(muxcode, arg1); \
00066 __sc_4 = (unsigned long) (arg2)
00067 #define LOADARGS_3(muxcode, arg1, arg2, arg3) \
00068 LOADARGS_2(muxcode, arg1, arg2); \
00069 __sc_5 = (unsigned long) (arg3)
00070 #define LOADARGS_4(muxcode, arg1, arg2, arg3, arg4) \
00071 LOADARGS_3(muxcode, arg1, arg2, arg3); \
00072 __sc_6 = (unsigned long) (arg4)
00073 #define LOADARGS_5(muxcode, arg1, arg2, arg3, arg4, arg5) \
00074 LOADARGS_4(muxcode, arg1, arg2, arg3, arg4); \
00075 __sc_7 = (unsigned long) (arg5)
00076
00077 #define ASM_INPUT_0 "0" (__sc_0)
00078 #define ASM_INPUT_1 ASM_INPUT_0, "1" (__sc_3)
00079 #define ASM_INPUT_2 ASM_INPUT_1, "2" (__sc_4)
00080 #define ASM_INPUT_3 ASM_INPUT_2, "3" (__sc_5)
00081 #define ASM_INPUT_4 ASM_INPUT_3, "4" (__sc_6)
00082 #define ASM_INPUT_5 ASM_INPUT_4, "5" (__sc_7)
00083
00084
00085
00086 #define __xn_reg_mux(regs) ((regs)->gpr[0])
00087 #define __xn_reg_rval(regs) ((regs)->gpr[3])
00088 #define __xn_reg_arg1(regs) ((regs)->gpr[3])
00089 #define __xn_reg_arg2(regs) ((regs)->gpr[4])
00090 #define __xn_reg_arg3(regs) ((regs)->gpr[5])
00091 #define __xn_reg_arg4(regs) ((regs)->gpr[6])
00092 #define __xn_reg_arg5(regs) ((regs)->gpr[7])
00093
00094 #define __xn_reg_mux_p(regs) ((__xn_reg_mux(regs) & 0xffff) == __xn_sys_mux)
00095 #define __xn_mux_id(regs) ((__xn_reg_mux(regs) >> 16) & 0xff)
00096 #define __xn_mux_op(regs) ((__xn_reg_mux(regs) >> 24) & 0xff)
00097 #define __xn_mux_code(id,op) ((op << 24)|((id << 16) & 0xff0000)|(__xn_sys_mux & 0xffff))
00098
00099 #define XENOMAI_SYSCALL0(op) XENOMAI_DO_SYSCALL(0,0,op)
00100 #define XENOMAI_SYSCALL1(op,a1) XENOMAI_DO_SYSCALL(1,0,op,a1)
00101 #define XENOMAI_SYSCALL2(op,a1,a2) XENOMAI_DO_SYSCALL(2,0,op,a1,a2)
00102 #define XENOMAI_SYSCALL3(op,a1,a2,a3) XENOMAI_DO_SYSCALL(3,0,op,a1,a2,a3)
00103 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4) XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4)
00104 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
00105
00106 #define XENOMAI_SKINCALL0(id,op) XENOMAI_DO_SYSCALL(0,id,op)
00107 #define XENOMAI_SKINCALL1(id,op,a1) XENOMAI_DO_SYSCALL(1,id,op,a1)
00108 #define XENOMAI_SKINCALL2(id,op,a1,a2) XENOMAI_DO_SYSCALL(2,id,op,a1,a2)
00109 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3) XENOMAI_DO_SYSCALL(3,id,op,a1,a2,a3)
00110 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4) XENOMAI_DO_SYSCALL(4,id,op,a1,a2,a3,a4)
00111 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,id,op,a1,a2,a3,a4,a5)
00112
00113 #ifdef __KERNEL__
00114
00115 #include <linux/errno.h>
00116 #include <asm/uaccess.h>
00117
00118
00119
00120
00121
00122
00123
00124 #define __xn_copy_from_user(task,dstP,srcP,n) \
00125 do { \
00126 if (__copy_from_user_inatomic(dstP,srcP,n)) \
00127 ; \
00128 } while(0)
00129 #define __xn_copy_to_user(task,dstP,srcP,n) \
00130 do { \
00131 if (__copy_to_user_inatomic(dstP,srcP,n)) \
00132 ; \
00133 } while(0)
00134 #define __xn_put_user(task,src,dstP) __put_user(src,dstP)
00135 #define __xn_get_user(task,dst,srcP) __get_user(dst,srcP)
00136
00137 #define __xn_range_ok(task,addr,size) \
00138 ((addr) <= (task)->thread.fs.seg \
00139 && ((size) == 0 || (size) - 1 <= (task)->thread.fs.seg - (addr)))
00140
00141 #define __xn_access_ok(task,type,addr,size) __xn_range_ok(task,(unsigned long)addr,size)
00142
00143
00144
00145
00146 static inline void __xn_success_return(struct pt_regs *regs, int v) {
00147 __xn_reg_rval(regs) = v;
00148 }
00149
00150 static inline void __xn_error_return(struct pt_regs *regs, int v) {
00151
00152
00153 __xn_reg_rval(regs) = v;
00154 }
00155
00156 static inline void __xn_status_return(struct pt_regs *regs, int v) {
00157 __xn_reg_rval(regs) = v;
00158 }
00159
00160 static inline int __xn_interrupted_p(struct pt_regs *regs) {
00161 return __xn_reg_rval(regs) == -EINTR;
00162 }
00163
00164 #define __xn_canonicalize_args(task,regs) do { } while(0)
00165
00166 #else
00167
00168 #define CONFIG_RTAI_HW_DIRECT_TSC 1
00169
00170 static inline unsigned long long __xn_rdtsc (void)
00171
00172 {
00173 union {
00174 unsigned long long t;
00175 unsigned long v[2];
00176 } u;
00177 unsigned long __tbu;
00178
00179 __asm__ __volatile__ ("1: mftbu %0\n"
00180 "mftb %1\n"
00181 "mftbu %2\n"
00182 "cmpw %2,%0\n"
00183 "bne- 1b\n"
00184 :"=r" (u.v[0]),
00185 "=r" (u.v[1]),
00186 "=r" (__tbu));
00187 return u.t;
00188 }
00189
00190 #endif
00191
00192 #endif