Xenomai  3.1
syscall32.h
1 /*
2  * Copyright (C) 2014 Philippe Gerum <rpm@xenomai.org>.
3  *
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.
8  *
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.
13  *
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
17  * 02111-1307, USA.
18  */
19 #ifndef _COBALT_X86_ASM_SYSCALL32_H
20 #define _COBALT_X86_ASM_SYSCALL32_H
21 
22 #include <asm/unistd.h>
23 
24 #ifdef CONFIG_X86_X32
25 
26 #define __COBALT_X32_BASE 128
27 
28 #define __COBALT_SYSNR32x(__reg) \
29  ({ \
30  long __nr = __reg; \
31  if (__nr & __X32_SYSCALL_BIT) { \
32  __nr &= ~__X32_SYSCALL_BIT; \
33  __nr += __COBALT_X32_BASE; \
34  } \
35  __nr; \
36  })
37 
38 #define __COBALT_COMPAT32x(__reg) \
39  (((__reg) & __X32_SYSCALL_BIT) ? __COBALT_COMPATX_BIT : 0)
40 
41 #if __NR_COBALT_SYSCALLS > __COBALT_X32_BASE
42 #error "__NR_COBALT_SYSCALLS > __COBALT_X32_BASE"
43 #endif
44 
45 #define __syshand32x__(__name) ((cobalt_syshand)(CoBaLt32x_ ## __name))
46 
47 #define __COBALT_CALL32x_INITHAND(__handler) \
48  [__COBALT_X32_BASE ... __COBALT_X32_BASE + __NR_COBALT_SYSCALLS-1] = __handler,
49 
50 #define __COBALT_CALL32x_INITMODE(__mode) \
51  [__COBALT_X32_BASE ... __COBALT_X32_BASE + __NR_COBALT_SYSCALLS-1] = __mode,
52 
53 /* x32 default entry (no thunk) */
54 #define __COBALT_CALL32x_ENTRY(__name, __handler) \
55  [sc_cobalt_ ## __name + __COBALT_X32_BASE] = __handler,
56 
57 /* x32 thunk installation */
58 #define __COBALT_CALL32x_pure_THUNK(__name) \
59  __COBALT_CALL32x_ENTRY(__name, __syshand32x__(__name))
60 
61 #define __COBALT_CALL32x_THUNK(__name) \
62  __COBALT_CALL32x_ENTRY(__name, __syshand32emu__(__name))
63 
64 /* x32 thunk implementation. */
65 #define COBALT_SYSCALL32x(__name, __mode, __args) \
66  long CoBaLt32x_ ## __name __args
67 
68 /* x32 thunk declaration. */
69 #define COBALT_SYSCALL32x_DECL(__name, __args) \
70  long CoBaLt32x_ ## __name __args
71 
72 #else /* !CONFIG_X86_X32 */
73 
74 /* x32 support disabled. */
75 
76 #define __COBALT_SYSNR32x(__reg) (__reg)
77 
78 #define __COBALT_COMPAT32x(__reg) 0
79 
80 #define __COBALT_CALL32x_INITHAND(__handler)
81 
82 #define __COBALT_CALL32x_INITMODE(__mode)
83 
84 #define __COBALT_CALL32x_ENTRY(__name, __handler)
85 
86 #define __COBALT_CALL32x_pure_THUNK(__name)
87 
88 #define __COBALT_CALL32x_THUNK(__name)
89 
90 #define COBALT_SYSCALL32x_DECL(__name, __args)
91 
92 #endif /* !CONFIG_X86_X32 */
93 
94 #ifdef CONFIG_IA32_EMULATION
95 
96 #define __COBALT_IA32_BASE 256 /* Power of two. */
97 
98 #define __COBALT_SYSNR32emu(__reg) \
99  ({ \
100  long __nr = __reg; \
101  if (in_ia32_syscall()) \
102  __nr += __COBALT_IA32_BASE; \
103  __nr; \
104  })
105 
106 #define __COBALT_COMPAT32emu(__reg) \
107  (in_ia32_syscall() ? __COBALT_COMPAT_BIT : 0)
108 
109 #if __NR_COBALT_SYSCALLS > __COBALT_IA32_BASE
110 #error "__NR_COBALT_SYSCALLS > __COBALT_IA32_BASE"
111 #endif
112 
113 #define __syshand32emu__(__name) ((cobalt_syshand)(CoBaLt32emu_ ## __name))
114 
115 #define __COBALT_CALL32emu_INITHAND(__handler) \
116  [__COBALT_IA32_BASE ... __COBALT_IA32_BASE + __NR_COBALT_SYSCALLS-1] = __handler,
117 
118 #define __COBALT_CALL32emu_INITMODE(__mode) \
119  [__COBALT_IA32_BASE ... __COBALT_IA32_BASE + __NR_COBALT_SYSCALLS-1] = __mode,
120 
121 /* ia32 default entry (no thunk) */
122 #define __COBALT_CALL32emu_ENTRY(__name, __handler) \
123  [sc_cobalt_ ## __name + __COBALT_IA32_BASE] = __handler,
124 
125 /* ia32 thunk installation */
126 #define __COBALT_CALL32emu_THUNK(__name) \
127  __COBALT_CALL32emu_ENTRY(__name, __syshand32emu__(__name))
128 
129 /* ia32 thunk implementation. */
130 #define COBALT_SYSCALL32emu(__name, __mode, __args) \
131  long CoBaLt32emu_ ## __name __args
132 
133 /* ia32 thunk declaration. */
134 #define COBALT_SYSCALL32emu_DECL(__name, __args) \
135  long CoBaLt32emu_ ## __name __args
136 
137 #else /* !CONFIG_IA32_EMULATION */
138 
139 /* ia32 emulation support disabled. */
140 
141 #define __COBALT_SYSNR32emu(__reg) (__reg)
142 
143 #define __COBALT_COMPAT32emu(__reg) 0
144 
145 #define __COBALT_CALL32emu_INITHAND(__handler)
146 
147 #define __COBALT_CALL32emu_INITMODE(__mode)
148 
149 #define __COBALT_CALL32emu_ENTRY(__name, __handler)
150 
151 #define __COBALT_CALL32emu_THUNK(__name)
152 
153 #define COBALT_SYSCALL32emu_DECL(__name, __args)
154 
155 #endif /* !CONFIG_IA32_EMULATION */
156 
157 #define __COBALT_CALL32_ENTRY(__name, __handler) \
158  __COBALT_CALL32x_ENTRY(__name, __handler) \
159  __COBALT_CALL32emu_ENTRY(__name, __handler)
160 
161 #define __COBALT_CALL32_INITHAND(__handler) \
162  __COBALT_CALL32x_INITHAND(__handler) \
163  __COBALT_CALL32emu_INITHAND(__handler)
164 
165 #define __COBALT_CALL32_INITMODE(__mode) \
166  __COBALT_CALL32x_INITMODE(__mode) \
167  __COBALT_CALL32emu_INITMODE(__mode)
168 
169 /* Already checked for __COBALT_SYSCALL_BIT */
170 #define __COBALT_CALL32_SYSNR(__reg) \
171  ({ \
172  long __nr; \
173  __nr = __COBALT_SYSNR32x(__reg); \
174  if (__nr == (__reg)) \
175  __nr = __COBALT_SYSNR32emu(__reg); \
176  __nr; \
177  })
178 
179 #define __COBALT_CALL_COMPAT(__reg) \
180  ({ \
181  int __ret = __COBALT_COMPAT32x(__reg); \
182  if (__ret == 0) \
183  __ret = __COBALT_COMPAT32emu(__reg); \
184  __ret; \
185  })
186 
187 #endif /* !_COBALT_X86_ASM_SYSCALL32_H */