Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /* Syscall definitions, Linux PowerPC generic version. |
---|---|
2 | Copyright (C) 2019-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ |
18 | |
19 | #ifndef _LINUX_POWERPC_SYSDEP_H |
20 | #define _LINUX_POWERPC_SYSDEP_H 1 |
21 | |
22 | #include <sysdeps/unix/sysv/linux/sysdep.h> |
23 | #include <sysdeps/unix/powerpc/sysdep.h> |
24 | #include <tls.h> |
25 | /* Define __set_errno() for INLINE_SYSCALL macro below. */ |
26 | #include <errno.h> |
27 | |
28 | /* For Linux we can use the system call table in the header file |
29 | /usr/include/asm/unistd.h |
30 | of the kernel. But these symbols do not follow the SYS_* syntax |
31 | so we have to redefine the `SYS_ify' macro here. */ |
32 | #undef SYS_ify |
33 | #define SYS_ify(syscall_name) __NR_##syscall_name |
34 | |
35 | /* Define a macro which expands inline into the wrapper code for a system |
36 | call. This use is for internal calls that do not need to handle errors |
37 | normally. It will never touch errno. This returns just what the kernel |
38 | gave back in the non-error (CR0.SO cleared) case, otherwise (CR0.SO set) |
39 | the negation of the return value in the kernel gets reverted. */ |
40 | |
41 | #define INTERNAL_VSYSCALL_CALL_TYPE(funcptr, type, nr, args...) \ |
42 | ({ \ |
43 | register void *r0 __asm__ ("r0"); \ |
44 | register long int r3 __asm__ ("r3"); \ |
45 | register long int r4 __asm__ ("r4"); \ |
46 | register long int r5 __asm__ ("r5"); \ |
47 | register long int r6 __asm__ ("r6"); \ |
48 | register long int r7 __asm__ ("r7"); \ |
49 | register long int r8 __asm__ ("r8"); \ |
50 | register type rval __asm__ ("r3"); \ |
51 | LOADARGS_##nr (funcptr, args); \ |
52 | __asm__ __volatile__ \ |
53 | ("mtctr %0\n\t" \ |
54 | "bctrl\n\t" \ |
55 | "mfcr %0\n\t" \ |
56 | "0:" \ |
57 | : "+r" (r0), "+r" (r3), "+r" (r4), "+r" (r5), "+r" (r6), \ |
58 | "+r" (r7), "+r" (r8) \ |
59 | : : "r9", "r10", "r11", "r12", \ |
60 | "cr0", "cr1", "cr5", "cr6", "cr7", \ |
61 | "xer", "lr", "ctr", "memory"); \ |
62 | __asm__ __volatile__ ("" : "=r" (rval) : "r" (r3)); \ |
63 | (long int) r0 & (1 << 28) ? -rval : rval; \ |
64 | }) |
65 | |
66 | #define INTERNAL_VSYSCALL_CALL(funcptr, nr, args...) \ |
67 | INTERNAL_VSYSCALL_CALL_TYPE(funcptr, long int, nr, args) |
68 | |
69 | #define DECLARE_REGS \ |
70 | register long int r0 __asm__ ("r0"); \ |
71 | register long int r3 __asm__ ("r3"); \ |
72 | register long int r4 __asm__ ("r4"); \ |
73 | register long int r5 __asm__ ("r5"); \ |
74 | register long int r6 __asm__ ("r6"); \ |
75 | register long int r7 __asm__ ("r7"); \ |
76 | register long int r8 __asm__ ("r8"); |
77 | |
78 | #define SYSCALL_SCV(nr) \ |
79 | ({ \ |
80 | __asm__ __volatile__ \ |
81 | (".machine \"push\"\n\t" \ |
82 | ".machine \"power9\"\n\t" \ |
83 | "scv 0\n\t" \ |
84 | ".machine \"pop\"\n\t" \ |
85 | "0:" \ |
86 | : "=&r" (r0), \ |
87 | "=&r" (r3), "=&r" (r4), "=&r" (r5), \ |
88 | "=&r" (r6), "=&r" (r7), "=&r" (r8) \ |
89 | : ASM_INPUT_##nr \ |
90 | : "r9", "r10", "r11", "r12", \ |
91 | "cr0", "cr1", "cr5", "cr6", "cr7", \ |
92 | "xer", "lr", "ctr", "memory"); \ |
93 | r3; \ |
94 | }) |
95 | |
96 | #define SYSCALL_SC(nr) \ |
97 | ({ \ |
98 | __asm__ __volatile__ \ |
99 | ("sc\n\t" \ |
100 | "mfcr %0\n\t" \ |
101 | "0:" \ |
102 | : "=&r" (r0), \ |
103 | "=&r" (r3), "=&r" (r4), "=&r" (r5), \ |
104 | "=&r" (r6), "=&r" (r7), "=&r" (r8) \ |
105 | : ASM_INPUT_##nr \ |
106 | : "r9", "r10", "r11", "r12", \ |
107 | "xer", "cr0", "ctr", "memory"); \ |
108 | r0 & (1 << 28) ? -r3 : r3; \ |
109 | }) |
110 | |
111 | /* This will only be non-empty for 64-bit systems, see below. */ |
112 | #define TRY_SYSCALL_SCV(nr) |
113 | |
114 | #if defined(__PPC64__) || defined(__powerpc64__) |
115 | # define SYSCALL_ARG_SIZE 8 |
116 | |
117 | /* For the static case, unlike the dynamic loader, there is no compile-time way |
118 | to check if we are inside startup code. So we need to check if the thread |
119 | pointer has already been setup before trying to access the TLS. */ |
120 | # ifndef SHARED |
121 | # define CHECK_THREAD_POINTER (__thread_register != 0) |
122 | # else |
123 | # define CHECK_THREAD_POINTER (1) |
124 | # endif |
125 | |
126 | /* When inside the dynamic loader, the thread pointer may not have been |
127 | initialized yet, so don't check for scv support in that case. */ |
128 | # if defined(USE_PPC_SCV) && !IS_IN(rtld) |
129 | # undef TRY_SYSCALL_SCV |
130 | # define TRY_SYSCALL_SCV(nr) \ |
131 | CHECK_THREAD_POINTER && THREAD_GET_HWCAP() & PPC_FEATURE2_SCV ? \ |
132 | SYSCALL_SCV(nr) : |
133 | # endif |
134 | |
135 | #else |
136 | # define SYSCALL_ARG_SIZE 4 |
137 | #endif |
138 | |
139 | # define INTERNAL_SYSCALL_NCS(name, nr, args...) \ |
140 | ({ \ |
141 | DECLARE_REGS; \ |
142 | LOADARGS_##nr (name, ##args); \ |
143 | TRY_SYSCALL_SCV(nr) \ |
144 | SYSCALL_SC(nr); \ |
145 | }) |
146 | |
147 | #undef INTERNAL_SYSCALL |
148 | #define INTERNAL_SYSCALL(name, nr, args...) \ |
149 | INTERNAL_SYSCALL_NCS (__NR_##name, nr, args) |
150 | |
151 | #define LOADARGS_0(name, dummy) \ |
152 | r0 = name |
153 | #define LOADARGS_1(name, __arg1) \ |
154 | long int _arg1 = (long int) (__arg1); \ |
155 | LOADARGS_0(name, 0); \ |
156 | extern void __illegally_sized_syscall_arg1 (void); \ |
157 | if (__builtin_classify_type (__arg1) != 5 \ |
158 | && sizeof (__arg1) > SYSCALL_ARG_SIZE) \ |
159 | __illegally_sized_syscall_arg1 (); \ |
160 | r3 = _arg1 |
161 | #define LOADARGS_2(name, __arg1, __arg2) \ |
162 | long int _arg2 = (long int) (__arg2); \ |
163 | LOADARGS_1(name, __arg1); \ |
164 | extern void __illegally_sized_syscall_arg2 (void); \ |
165 | if (__builtin_classify_type (__arg2) != 5 \ |
166 | && sizeof (__arg2) > SYSCALL_ARG_SIZE) \ |
167 | __illegally_sized_syscall_arg2 (); \ |
168 | r4 = _arg2 |
169 | #define LOADARGS_3(name, __arg1, __arg2, __arg3) \ |
170 | long int _arg3 = (long int) (__arg3); \ |
171 | LOADARGS_2(name, __arg1, __arg2); \ |
172 | extern void __illegally_sized_syscall_arg3 (void); \ |
173 | if (__builtin_classify_type (__arg3) != 5 \ |
174 | && sizeof (__arg3) > SYSCALL_ARG_SIZE) \ |
175 | __illegally_sized_syscall_arg3 (); \ |
176 | r5 = _arg3 |
177 | #define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \ |
178 | long int _arg4 = (long int) (__arg4); \ |
179 | LOADARGS_3(name, __arg1, __arg2, __arg3); \ |
180 | extern void __illegally_sized_syscall_arg4 (void); \ |
181 | if (__builtin_classify_type (__arg4) != 5 \ |
182 | && sizeof (__arg4) > SYSCALL_ARG_SIZE) \ |
183 | __illegally_sized_syscall_arg4 (); \ |
184 | r6 = _arg4 |
185 | #define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \ |
186 | long int _arg5 = (long int) (__arg5); \ |
187 | LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \ |
188 | extern void __illegally_sized_syscall_arg5 (void); \ |
189 | if (__builtin_classify_type (__arg5) != 5 \ |
190 | && sizeof (__arg5) > SYSCALL_ARG_SIZE) \ |
191 | __illegally_sized_syscall_arg5 (); \ |
192 | r7 = _arg5 |
193 | #define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \ |
194 | long int _arg6 = (long int) (__arg6); \ |
195 | LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \ |
196 | extern void __illegally_sized_syscall_arg6 (void); \ |
197 | if (__builtin_classify_type (__arg6) != 5 \ |
198 | && sizeof (__arg6) > SYSCALL_ARG_SIZE) \ |
199 | __illegally_sized_syscall_arg6 (); \ |
200 | r8 = _arg6 |
201 | |
202 | #define ASM_INPUT_0 "0" (r0) |
203 | #define ASM_INPUT_1 ASM_INPUT_0, "1" (r3) |
204 | #define ASM_INPUT_2 ASM_INPUT_1, "2" (r4) |
205 | #define ASM_INPUT_3 ASM_INPUT_2, "3" (r5) |
206 | #define ASM_INPUT_4 ASM_INPUT_3, "4" (r6) |
207 | #define ASM_INPUT_5 ASM_INPUT_4, "5" (r7) |
208 | #define ASM_INPUT_6 ASM_INPUT_5, "6" (r8) |
209 | |
210 | /* List of system calls which are supported as vsyscalls. */ |
211 | #define VDSO_NAME "LINUX_2.6.15" |
212 | #define VDSO_HASH 123718565 |
213 | |
214 | #if defined(__PPC64__) || defined(__powerpc64__) |
215 | #define HAVE_CLOCK_GETRES64_VSYSCALL "__kernel_clock_getres" |
216 | #define HAVE_CLOCK_GETTIME64_VSYSCALL "__kernel_clock_gettime" |
217 | #define HAVE_CLONE3_WRAPPER 1 |
218 | #else |
219 | #define HAVE_CLOCK_GETRES_VSYSCALL "__kernel_clock_getres" |
220 | #define HAVE_CLOCK_GETTIME_VSYSCALL "__kernel_clock_gettime" |
221 | #endif |
222 | #define HAVE_GETCPU_VSYSCALL "__kernel_getcpu" |
223 | #define HAVE_TIME_VSYSCALL "__kernel_time" |
224 | #define HAVE_GETTIMEOFDAY_VSYSCALL "__kernel_gettimeofday" |
225 | #define HAVE_GET_TBFREQ "__kernel_get_tbfreq" |
226 | |
227 | #endif /* _LINUX_POWERPC_SYSDEP_H */ |
228 |
Warning: That file was not part of the compilation database. It may have many parsing errors.