Xenomai  3.0-rc6
syscall.h
1 /*
2  * Copyright (C) 2011 Philippe Gerum <rpm@xenomai.org>.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18 #ifndef _LIB_COBALT_SH_SYSCALL_H
19 #define _LIB_COBALT_SH_SYSCALL_H
20 
21 #include <cobalt/uapi/syscall.h>
22 
23 /* Some code pulled from glibc's inline syscalls. */
24 
25 #define SYSCALL_INST_STR0 "trapa #0x10\n\t"
26 #define SYSCALL_INST_STR1 "trapa #0x11\n\t"
27 #define SYSCALL_INST_STR2 "trapa #0x12\n\t"
28 #define SYSCALL_INST_STR3 "trapa #0x13\n\t"
29 #define SYSCALL_INST_STR4 "trapa #0x14\n\t"
30 #define SYSCALL_INST_STR5 "trapa #0x15\n\t"
31 #define SYSCALL_INST_STR6 "trapa #0x16\n\t"
32 
33 /*
34  * Conservatively assume that a known SH-4 silicon bug bites us: 4
35  * instruction cycles not accessing cache and TLB are needed after
36  * trapa instruction.
37  */
38 #define SYSCALL_INST_PAD " \
39  or r0,r0; or r0,r0; or r0,r0; or r0,r0; or r0,r0"
40 
41 #define ASMFMT_0
42 #define ASMFMT_1 \
43  , "r" (r4)
44 #define ASMFMT_2 \
45  , "r" (r4), "r" (r5)
46 #define ASMFMT_3 \
47  , "r" (r4), "r" (r5), "r" (r6)
48 #define ASMFMT_4 \
49  , "r" (r4), "r" (r5), "r" (r6), "r" (r7)
50 #define ASMFMT_5 \
51  , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0)
52 #define ASMFMT_6 \
53  , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1)
54 #define ASMFMT_7 \
55  , "r" (r4), "r" (r5), "r" (r6), "r" (r7), "0" (r0), "r" (r1), "r" (r2)
56 
57 #define SUBSTITUTE_ARGS_0()
58 #define SUBSTITUTE_ARGS_1(arg1) \
59  long int _arg1 = (long int) (arg1); \
60  register long int r4 asm ("%r4") = (long int) (_arg1)
61 #define SUBSTITUTE_ARGS_2(arg1, arg2) \
62  long int _arg1 = (long int) (arg1); \
63  long int _arg2 = (long int) (arg2); \
64  register long int r4 asm ("%r4") = (long int) (_arg1); \
65  register long int r5 asm ("%r5") = (long int) (_arg2)
66 #define SUBSTITUTE_ARGS_3(arg1, arg2, arg3) \
67  long int _arg1 = (long int) (arg1); \
68  long int _arg2 = (long int) (arg2); \
69  long int _arg3 = (long int) (arg3); \
70  register long int r4 asm ("%r4") = (long int) (_arg1); \
71  register long int r5 asm ("%r5") = (long int) (_arg2); \
72  register long int r6 asm ("%r6") = (long int) (_arg3)
73 #define SUBSTITUTE_ARGS_4(arg1, arg2, arg3, arg4) \
74  long int _arg1 = (long int) (arg1); \
75  long int _arg2 = (long int) (arg2); \
76  long int _arg3 = (long int) (arg3); \
77  long int _arg4 = (long int) (arg4); \
78  register long int r4 asm ("%r4") = (long int) (_arg1); \
79  register long int r5 asm ("%r5") = (long int) (_arg2); \
80  register long int r6 asm ("%r6") = (long int) (_arg3); \
81  register long int r7 asm ("%r7") = (long int) (_arg4)
82 #define SUBSTITUTE_ARGS_5(arg1, arg2, arg3, arg4, arg5) \
83  long int _arg1 = (long int) (arg1); \
84  long int _arg2 = (long int) (arg2); \
85  long int _arg3 = (long int) (arg3); \
86  long int _arg4 = (long int) (arg4); \
87  long int _arg5 = (long int) (arg5); \
88  register long int r4 asm ("%r4") = (long int) (_arg1); \
89  register long int r5 asm ("%r5") = (long int) (_arg2); \
90  register long int r6 asm ("%r6") = (long int) (_arg3); \
91  register long int r7 asm ("%r7") = (long int) (_arg4); \
92  register long int r0 asm ("%r0") = (long int) (_arg5)
93 
94 #define XENOMAI_DO_SYSCALL(nr, op, args...) \
95  ({ \
96  unsigned long int __ret; \
97  register long int r3 asm ("%r3") = __xn_syscode(op); \
98  SUBSTITUTE_ARGS_##nr(args); \
99  \
100  asm volatile (SYSCALL_INST_STR##nr SYSCALL_INST_PAD \
101  : "=z" (__ret) \
102  : "r" (r3) ASMFMT_##nr \
103  : "memory", "t"); \
104  \
105  (int) __ret; \
106  })
107 
108 #define XENOMAI_SYSCALL0(op) XENOMAI_DO_SYSCALL(0,op)
109 #define XENOMAI_SYSCALL1(op,a1) XENOMAI_DO_SYSCALL(1,op,a1)
110 #define XENOMAI_SYSCALL2(op,a1,a2) XENOMAI_DO_SYSCALL(2,op,a1,a2)
111 #define XENOMAI_SYSCALL3(op,a1,a2,a3) XENOMAI_DO_SYSCALL(3,op,a1,a2,a3)
112 #define XENOMAI_SYSCALL4(op,a1,a2,a3,a4) XENOMAI_DO_SYSCALL(4,op,a1,a2,a3,a4)
113 #define XENOMAI_SYSCALL5(op,a1,a2,a3,a4,a5) XENOMAI_DO_SYSCALL(5,op,a1,a2,a3,a4,a5)
114 #define XENOMAI_SYSBIND(breq) XENOMAI_DO_SYSCALL(1,sc_cobalt_bind,breq)
115 
116 #endif /* !_LIB_COBALT_SH_SYSCALL_H */