2 * Copyright (C) 2011 Philippe Gerum <rpm@xenomai.org>.
4 * Xenomai is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * Xenomai is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Xenomai; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 #ifndef _XENO_ASM_SH_SYSCALL_H
21 #define _XENO_ASM_SH_SYSCALL_H
23 #include <asm-generic/xenomai/syscall.h>
24 #include <asm/xenomai/tsc.h>
26 #define __xn_mux_shifted_id(id) (id << 24)
27 #define __xn_mux_code(shifted_id,op) (shifted_id|((op << 16) & 0xff0000)|(__xn_sys_mux & 0xffff))
31 #include <linux/errno.h>
32 #include <asm/ptrace.h>
34 /* Register mapping for accessing syscall args. */
36 #define __xn_reg_mux(regs) ((regs)->regs[3])
37 #define __xn_reg_rval(regs) ((regs)->regs[0])
38 #define __xn_reg_arg1(regs) ((regs)->regs[4])
39 #define __xn_reg_arg2(regs) ((regs)->regs[5])
40 #define __xn_reg_arg3(regs) ((regs)->regs[6])
41 #define __xn_reg_arg4(regs) ((regs)->regs[7])
42 #define __xn_reg_arg5(regs) ((regs)->regs[0])
44 #define __xn_reg_mux_p(regs) ((__xn_reg_mux(regs) & 0xffff) == __xn_sys_mux)
45 #define __xn_mux_id(regs) ((__xn_reg_mux(regs) >> 24) & 0xff)
46 #define __xn_mux_op(regs) ((__xn_reg_mux(regs) >> 16) & 0xff)
48 #define __xn_linux_mux_p(regs, nr) (__xn_reg_mux(regs) == (nr))
51 * Purposedly used inlines and not macros for the following routines
52 * so that we don't risk spurious side-effects on the value arg.
54 static inline void __xn_success_return(struct pt_regs
*regs
, int v
)
56 __xn_reg_rval(regs
) = v
;
59 static inline void __xn_error_return(struct pt_regs
*regs
, int v
)
61 __xn_reg_rval(regs
) = v
;
64 static inline void __xn_status_return(struct pt_regs
*regs
, int v
)
66 __xn_reg_rval(regs
) = v
;
69 static inline int __xn_interrupted_p(struct pt_regs
*regs
)
71 return __xn_reg_rval(regs
) == -EINTR
;
74 #else /* !__KERNEL__ */
77 #include <asm/xenomai/atomic.h>
80 * The following code defines an inline syscall mechanism used by
81 * Xenomai's real-time interfaces to invoke the skin module
82 * services in kernel space.
85 #define SYSCALL_INST_STR0 "trapa #0x10\n\t"
86 #define SYSCALL_INST_STR1 "trapa #0x11\n\t"
87 #define SYSCALL_INST_STR2 "trapa #0x12\n\t"
88 #define SYSCALL_INST_STR3 "trapa #0x13\n\t"
89 #define SYSCALL_INST_STR4 "trapa #0x14\n\t"
90 #define SYSCALL_INST_STR5 "trapa #0x15\n\t"
91 #define SYSCALL_INST_STR6 "trapa #0x16\n\t"
94 * Conservatively assume that a known SH-4 silicon bug bites us: 4
95 * instruction cycles not accessing cache and TLB are needed after
98 #define SYSCALL_INST_PAD " \
99 or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0"
107 , "r" (r4), "r" (r5), "r" (r6)
109 , "r" (r4), "r" (r5), "r" (r6), "r" (r7)
111 , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0)
113 , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1)
115 , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1), "r" (r2)
117 #define SUBSTITUTE_ARGS_0()
118 #define SUBSTITUTE_ARGS_1(arg1) \
119 long int _arg1 = (long int) (arg1); \
120 register long int r4 asm ("%r4") = (long int) (_arg1)
121 #define SUBSTITUTE_ARGS_2(arg1, arg2) \
122 long int _arg1 = (long int) (arg1); \
123 long int _arg2 = (long int) (arg2); \
124 register long int r4 asm ("%r4") = (long int) (_arg1); \
125 register long int r5 asm ("%r5") = (long int) (_arg2)
126 #define SUBSTITUTE_ARGS_3(arg1, arg2, arg3) \
127 long int _arg1 = (long int) (arg1); \
128 long int _arg2 = (long int) (arg2); \
129 long int _arg3 = (long int) (arg3); \
130 register long int r4 asm ("%r4") = (long int) (_arg1); \
131 register long int r5 asm ("%r5") = (long int) (_arg2); \
132 register long int r6 asm ("%r6") = (long int) (_arg3)
133 #define SUBSTITUTE_ARGS_4(arg1, arg2, arg3, arg4) \
134 long int _arg1 = (long int) (arg1); \
135 long int _arg2 = (long int) (arg2); \
136 long int _arg3 = (long int) (arg3); \
137 long int _arg4 = (long int) (arg4); \
138 register long int r4 asm ("%r4") = (long int) (_arg1); \
139 register long int r5 asm ("%r5") = (long int) (_arg2); \
140 register long int r6 asm ("%r6") = (long int) (_arg3); \
141 register long int r7 asm ("%r7") = (long int) (_arg4)
142 #define SUBSTITUTE_ARGS_5(arg1, arg2, arg3, arg4, arg5) \
143 long int _arg1 = (long int) (arg1); \
144 long int _arg2 = (long int) (arg2); \
145 long int _arg3 = (long int) (arg3); \
146 long int _arg4 = (long int) (arg4); \
147 long int _arg5 = (long int) (arg5); \
148 register long int r4 asm ("%r4") = (long int) (_arg1); \
149 register long int r5 asm ("%r5") = (long int) (_arg2); \
150 register long int r6 asm ("%r6") = (long int) (_arg3); \
151 register long int r7 asm ("%r7") = (long int) (_arg4); \
152 register long int r0 asm ("%r0") = (long int) (_arg5)
154 #define XENOMAI_DO_SYSCALL(nr, shifted_id, op, args...) \
156 unsigned long int __ret; \
157 register long int r3 asm ("%r3") = __xn_mux_code(shifted_id, op); \
158 SUBSTITUTE_ARGS_##nr(args); \
160 asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \
162 : "r" (r3) ASMFMT_##nr \
168 #define XENOMAI_SYSCALL0(op) XENOMAI_DO_SYSCALL(0,0,op)
169 #define XENOMAI_SYSCALL1(op,a1) XENOMAI_DO_SYSCALL(1,0,op,a1)
170 #define XENOMAI_SYSCALL2(op,a1,a2) XENOMAI_DO_SYSCALL(2,0,op,a1,a2)
171 #define XENOMAI_SYSCALL3(op,a1,a2,a3) XENOMAI_DO_SYSCALL(3,0,op,a1,a2,a3)
172 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4) XENOMAI_DO_SYSCALL(4,0,op,a1,a2,a3,a4)
173 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,0,op,a1,a2,a3,a4,a5)
174 #define XENOMAI_SYSBIND(a1,a2,a3,a4) XENOMAI_DO_SYSCALL(4,0,__xn_sys_bind,a1,a2,a3,a4)
176 #define XENOMAI_SKINCALL0(id,op) XENOMAI_DO_SYSCALL(0,id,op)
177 #define XENOMAI_SKINCALL1(id,op,a1) XENOMAI_DO_SYSCALL(1,id,op,a1)
178 #define XENOMAI_SKINCALL2(id,op,a1,a2) XENOMAI_DO_SYSCALL(2,id,op,a1,a2)
179 #define XENOMAI_SKINCALL3(id,op,a1,a2,a3) XENOMAI_DO_SYSCALL(3,id,op,a1,a2,a3)
180 #define XENOMAI_SKINCALL4(id,op,a1,a2,a3,a4) XENOMAI_DO_SYSCALL(4,id,op,a1,a2,a3,a4)
181 #define XENOMAI_SKINCALL5(id,op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,id,op,a1,a2,a3,a4,a5)
183 #endif /* __KERNEL__ */
185 #endif /* !_XENO_ASM_SH_SYSCALL_H */