1 | // SPDX-License-Identifier: GPL-3.0-or-later |
2 | // Usermode syscall wrappers |
3 | // This file was generated by scripts/gen_syscall.py |
4 | |
5 | #pragma once |
6 | |
7 | #include <mos/filesystem/fs_types.h> |
8 | #include <mos/io/io_types.h> |
9 | #include <mos/mos_global.h> |
10 | #include <mos/tasks/signal_types.h> |
11 | #include <mos/types.h> |
12 | #include <sys/poll.h> |
13 | #include <sys/select.h> |
14 | #include <sys/uio.h> |
15 | |
16 | // platform syscall header |
17 | #include <mos/platform_syscall.h> |
18 | #include <mos/syscall/number.h> |
19 | |
20 | #ifdef __MOS_KERNEL__ |
21 | #error "This file should not be included in the kernel!" |
22 | #endif |
23 | |
24 | should_inline fd_t syscall_vfs_openat(fd_t dirfd, const char *file_path, open_flags flags) |
25 | { |
26 | return (fd_t) platform_syscall3(SYSCALL_vfs_openat, arg1: (reg_t) dirfd, arg2: (reg_t) file_path, arg3: (reg_t) flags); |
27 | } |
28 | |
29 | should_inline long syscall_vfs_fstatat(fd_t dirfd, const char *file_path, file_stat_t *stat_buf, fstatat_flags flags) |
30 | { |
31 | return (long) platform_syscall4(SYSCALL_vfs_fstatat, arg1: (reg_t) dirfd, arg2: (reg_t) file_path, arg3: (reg_t) stat_buf, arg4: (reg_t) flags); |
32 | } |
33 | |
34 | should_inline size_t syscall_io_read(fd_t fd, void *buffer, size_t size) |
35 | { |
36 | return (size_t) platform_syscall3(SYSCALL_io_read, arg1: (reg_t) fd, arg2: (reg_t) buffer, arg3: (reg_t) size); |
37 | } |
38 | |
39 | should_inline size_t syscall_io_write(fd_t fd, const void *buffer, size_t size) |
40 | { |
41 | return (size_t) platform_syscall3(SYSCALL_io_write, arg1: (reg_t) fd, arg2: (reg_t) buffer, arg3: (reg_t) size); |
42 | } |
43 | |
44 | should_inline bool syscall_io_close(fd_t fd) |
45 | { |
46 | return (bool) platform_syscall1(SYSCALL_io_close, arg1: (reg_t) fd); |
47 | } |
48 | |
49 | should_inline __attribute__((__noreturn__)) void syscall_exit(u32 exit_code) |
50 | { |
51 | platform_syscall1(SYSCALL_exit, arg1: (reg_t) exit_code); |
52 | __builtin_unreachable(); |
53 | } |
54 | |
55 | should_inline void syscall_yield_cpu(void) |
56 | { |
57 | platform_syscall0(SYSCALL_yield_cpu); |
58 | } |
59 | |
60 | should_inline pid_t syscall_fork(void) |
61 | { |
62 | return (pid_t) platform_syscall0(SYSCALL_fork); |
63 | } |
64 | |
65 | should_inline pid_t syscall_get_pid(void) |
66 | { |
67 | return (pid_t) platform_syscall0(SYSCALL_get_pid); |
68 | } |
69 | |
70 | should_inline pid_t syscall_get_parent_pid(void) |
71 | { |
72 | return (pid_t) platform_syscall0(SYSCALL_get_parent_pid); |
73 | } |
74 | |
75 | should_inline pid_t syscall_spawn(const char *file_path, const char *const *argv, const char *const *envp) |
76 | { |
77 | return (pid_t) platform_syscall3(SYSCALL_spawn, arg1: (reg_t) file_path, arg2: (reg_t) argv, arg3: (reg_t) envp); |
78 | } |
79 | |
80 | should_inline tid_t syscall_create_thread(const char *name, thread_entry_t entry, void *arg, size_t stack_size, void *stack) |
81 | { |
82 | return (tid_t) platform_syscall5(SYSCALL_create_thread, arg1: (reg_t) name, arg2: (reg_t) entry, arg3: (reg_t) arg, arg4: (reg_t) stack_size, arg5: (reg_t) stack); |
83 | } |
84 | |
85 | should_inline tid_t syscall_get_tid(void) |
86 | { |
87 | return (tid_t) platform_syscall0(SYSCALL_get_tid); |
88 | } |
89 | |
90 | should_inline __attribute__((__noreturn__)) void syscall_thread_exit(void) |
91 | { |
92 | platform_syscall0(SYSCALL_thread_exit); |
93 | __builtin_unreachable(); |
94 | } |
95 | |
96 | should_inline bool syscall_wait_for_thread(tid_t tid) |
97 | { |
98 | return (bool) platform_syscall1(SYSCALL_wait_for_thread, arg1: (reg_t) tid); |
99 | } |
100 | |
101 | should_inline bool syscall_futex_wait(futex_word_t *futex, u32 val) |
102 | { |
103 | return (bool) platform_syscall2(SYSCALL_futex_wait, arg1: (reg_t) futex, arg2: (reg_t) val); |
104 | } |
105 | |
106 | should_inline bool syscall_futex_wake(futex_word_t *futex, size_t count) |
107 | { |
108 | return (bool) platform_syscall2(SYSCALL_futex_wake, arg1: (reg_t) futex, arg2: (reg_t) count); |
109 | } |
110 | |
111 | should_inline fd_t syscall_ipc_create(const char *name, size_t max_pending_connections) |
112 | { |
113 | return (fd_t) platform_syscall2(SYSCALL_ipc_create, arg1: (reg_t) name, arg2: (reg_t) max_pending_connections); |
114 | } |
115 | |
116 | should_inline fd_t syscall_ipc_accept(fd_t fd) |
117 | { |
118 | return (fd_t) platform_syscall1(SYSCALL_ipc_accept, arg1: (reg_t) fd); |
119 | } |
120 | |
121 | should_inline fd_t syscall_ipc_connect(const char *name, size_t buffer_size) |
122 | { |
123 | return (fd_t) platform_syscall2(SYSCALL_ipc_connect, arg1: (reg_t) name, arg2: (reg_t) buffer_size); |
124 | } |
125 | |
126 | /** |
127 | * arch_syscall |
128 | * This syscall is used to implement architecture-specific syscalls. |
129 | * The first argument is the syscall number, and the remaining arguments |
130 | * are the arguments to the syscall. |
131 | */ |
132 | should_inline u64 syscall_arch_syscall(u64 nr, u64 arg1, u64 arg2, u64 arg3, u64 arg4) |
133 | { |
134 | return (u64) platform_syscall5(SYSCALL_arch_syscall, arg1: (reg_t) nr, arg2: (reg_t) arg1, arg3: (reg_t) arg2, arg4: (reg_t) arg3, arg5: (reg_t) arg4); |
135 | } |
136 | |
137 | should_inline long syscall_vfs_mount(const char *device, const char *mount_point, const char *fs_type, const char *options) |
138 | { |
139 | return (long) platform_syscall4(SYSCALL_vfs_mount, arg1: (reg_t) device, arg2: (reg_t) mount_point, arg3: (reg_t) fs_type, arg4: (reg_t) options); |
140 | } |
141 | |
142 | should_inline ssize_t syscall_vfs_readlinkat(fd_t dirfd, const char *path, char *buf, size_t buf_size) |
143 | { |
144 | return (ssize_t) platform_syscall4(SYSCALL_vfs_readlinkat, arg1: (reg_t) dirfd, arg2: (reg_t) path, arg3: (reg_t) buf, arg4: (reg_t) buf_size); |
145 | } |
146 | |
147 | should_inline long syscall_vfs_unlinkat(fd_t dirfd, const char *path) |
148 | { |
149 | return (long) platform_syscall2(SYSCALL_vfs_unlinkat, arg1: (reg_t) dirfd, arg2: (reg_t) path); |
150 | } |
151 | |
152 | should_inline long syscall_vfs_symlink(const char *link_path, const char *target) |
153 | { |
154 | return (long) platform_syscall2(SYSCALL_vfs_symlink, arg1: (reg_t) link_path, arg2: (reg_t) target); |
155 | } |
156 | |
157 | should_inline long syscall_vfs_mkdir(const char *path) |
158 | { |
159 | return (long) platform_syscall1(SYSCALL_vfs_mkdir, arg1: (reg_t) path); |
160 | } |
161 | |
162 | should_inline size_t syscall_vfs_list_dir(fd_t fd, char *buffer, size_t buffer_size) |
163 | { |
164 | return (size_t) platform_syscall3(SYSCALL_vfs_list_dir, arg1: (reg_t) fd, arg2: (reg_t) buffer, arg3: (reg_t) buffer_size); |
165 | } |
166 | |
167 | should_inline long syscall_fd_manipulate(fd_t fd, u64 cmd, void *arg) |
168 | { |
169 | return (long) platform_syscall3(SYSCALL_fd_manipulate, arg1: (reg_t) fd, arg2: (reg_t) cmd, arg3: (reg_t) arg); |
170 | } |
171 | |
172 | should_inline void *syscall_mmap_anonymous(ptr_t hint_addr, size_t size, mem_perm_t perm, mmap_flags_t flags) |
173 | { |
174 | return (void *) platform_syscall4(SYSCALL_mmap_anonymous, arg1: (reg_t) hint_addr, arg2: (reg_t) size, arg3: (reg_t) perm, arg4: (reg_t) flags); |
175 | } |
176 | |
177 | should_inline void *syscall_mmap_file(ptr_t hint_addr, size_t size, mem_perm_t perm, mmap_flags_t flags, fd_t fd, off_t offset) |
178 | { |
179 | return (void *) platform_syscall6(SYSCALL_mmap_file, arg1: (reg_t) hint_addr, arg2: (reg_t) size, arg3: (reg_t) perm, arg4: (reg_t) flags, arg5: (reg_t) fd, arg6: (reg_t) offset); |
180 | } |
181 | |
182 | should_inline pid_t syscall_wait_for_process(pid_t pid, u32 *exit_code, u32 flags) |
183 | { |
184 | return (pid_t) platform_syscall3(SYSCALL_wait_for_process, arg1: (reg_t) pid, arg2: (reg_t) exit_code, arg3: (reg_t) flags); |
185 | } |
186 | |
187 | should_inline bool syscall_munmap(void *addr, size_t size) |
188 | { |
189 | return (bool) platform_syscall2(SYSCALL_munmap, arg1: (reg_t) addr, arg2: (reg_t) size); |
190 | } |
191 | |
192 | should_inline long syscall_vfs_chdirat(fd_t dirfd, const char *path) |
193 | { |
194 | return (long) platform_syscall2(SYSCALL_vfs_chdirat, arg1: (reg_t) dirfd, arg2: (reg_t) path); |
195 | } |
196 | |
197 | should_inline ssize_t syscall_vfs_getcwd(char *buf, size_t buf_size) |
198 | { |
199 | return (ssize_t) platform_syscall2(SYSCALL_vfs_getcwd, arg1: (reg_t) buf, arg2: (reg_t) buf_size); |
200 | } |
201 | |
202 | should_inline off_t syscall_io_seek(fd_t fd, off_t offset, io_seek_whence_t whence) |
203 | { |
204 | return (off_t) platform_syscall3(SYSCALL_io_seek, arg1: (reg_t) fd, arg2: (reg_t) offset, arg3: (reg_t) whence); |
205 | } |
206 | |
207 | should_inline off_t syscall_io_tell(fd_t fd) |
208 | { |
209 | return (off_t) platform_syscall1(SYSCALL_io_tell, arg1: (reg_t) fd); |
210 | } |
211 | |
212 | should_inline bool syscall_signal_register(signal_t signum, const sigaction_t *action) |
213 | { |
214 | return (bool) platform_syscall2(SYSCALL_signal_register, arg1: (reg_t) signum, arg2: (reg_t) action); |
215 | } |
216 | |
217 | /** |
218 | * signal_process |
219 | * Send a signal to a process, an arbitrary thread in the target process |
220 | * will be selected to receive the signal. |
221 | */ |
222 | should_inline long syscall_signal_process(pid_t pid, signal_t signum) |
223 | { |
224 | return (long) platform_syscall2(SYSCALL_signal_process, arg1: (reg_t) pid, arg2: (reg_t) signum); |
225 | } |
226 | |
227 | /** |
228 | * signal_thread |
229 | * Send a signal to a specific thread in a process. |
230 | */ |
231 | should_inline long syscall_signal_thread(tid_t tid, signal_t signum) |
232 | { |
233 | return (long) platform_syscall2(SYSCALL_signal_thread, arg1: (reg_t) tid, arg2: (reg_t) signum); |
234 | } |
235 | |
236 | should_inline void syscall_poweroff(bool reboot, u32 magic) |
237 | { |
238 | platform_syscall2(SYSCALL_poweroff, arg1: (reg_t) reboot, arg2: (reg_t) magic); |
239 | } |
240 | |
241 | should_inline __attribute__((__noreturn__)) void syscall_signal_return(void *sp) |
242 | { |
243 | platform_syscall1(SYSCALL_signal_return, arg1: (reg_t) sp); |
244 | __builtin_unreachable(); |
245 | } |
246 | |
247 | should_inline bool syscall_vm_protect(void *addr, size_t size, mem_perm_t perm) |
248 | { |
249 | return (bool) platform_syscall3(SYSCALL_vm_protect, arg1: (reg_t) addr, arg2: (reg_t) size, arg3: (reg_t) perm); |
250 | } |
251 | |
252 | should_inline int syscall_io_poll(struct pollfd *fds, nfds_t nfds, int timeout) |
253 | { |
254 | return (int) platform_syscall3(SYSCALL_io_poll, arg1: (reg_t) fds, arg2: (reg_t) nfds, arg3: (reg_t) timeout); |
255 | } |
256 | |
257 | should_inline int syscall_io_pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask) |
258 | { |
259 | return (int) platform_syscall6(SYSCALL_io_pselect, arg1: (reg_t) nfds, arg2: (reg_t) readfds, arg3: (reg_t) writefds, arg4: (reg_t) exceptfds, arg5: (reg_t) timeout, arg6: (reg_t) sigmask); |
260 | } |
261 | |
262 | should_inline long syscall_execveat(fd_t dirfd, const char *file_path, const char *const *argv, const char *const *envp, u32 flags) |
263 | { |
264 | return (long) platform_syscall5(SYSCALL_execveat, arg1: (reg_t) dirfd, arg2: (reg_t) file_path, arg3: (reg_t) argv, arg4: (reg_t) envp, arg5: (reg_t) flags); |
265 | } |
266 | |
267 | should_inline long syscall_clock_msleep(u64 ms) |
268 | { |
269 | return (long) platform_syscall1(SYSCALL_clock_msleep, arg1: (reg_t) ms); |
270 | } |
271 | |
272 | should_inline fd_t syscall_io_dup(fd_t fd) |
273 | { |
274 | return (fd_t) platform_syscall1(SYSCALL_io_dup, arg1: (reg_t) fd); |
275 | } |
276 | |
277 | should_inline fd_t syscall_io_dup2(fd_t old_fd, fd_t new_fd) |
278 | { |
279 | return (fd_t) platform_syscall2(SYSCALL_io_dup2, arg1: (reg_t) old_fd, arg2: (reg_t) new_fd); |
280 | } |
281 | |
282 | /** |
283 | * dmabuf_alloc |
284 | * Allocate a DMA buffer, the buffer will be physically contiguous and its virtual address |
285 | * will be mapped into user's address space. |
286 | */ |
287 | should_inline bool syscall_dmabuf_alloc(size_t n_pages, ptr_t *out_paddr, ptr_t *out_vaddr) |
288 | { |
289 | return (bool) platform_syscall3(SYSCALL_dmabuf_alloc, arg1: (reg_t) n_pages, arg2: (reg_t) out_paddr, arg3: (reg_t) out_vaddr); |
290 | } |
291 | |
292 | /** |
293 | * dmabuf_free |
294 | * Free a DMA buffer that was previously allocated with dma_alloc(). |
295 | * The buffer will be unmapped from user's address space, and its physical pages |
296 | * will be reclaimed. |
297 | */ |
298 | should_inline bool syscall_dmabuf_free(ptr_t vaddr, ptr_t paddr) |
299 | { |
300 | return (bool) platform_syscall2(SYSCALL_dmabuf_free, arg1: (reg_t) vaddr, arg2: (reg_t) paddr); |
301 | } |
302 | |
303 | /** |
304 | * dmabuf_share |
305 | * Export (copy) a userspace buffer to a DMA buffer address that can be used by devices. |
306 | * The physical address of the buffer will be returned in out_paddr. |
307 | */ |
308 | should_inline bool syscall_dmabuf_share(void *buf, size_t bufsize, ptr_t *out_paddr) |
309 | { |
310 | return (bool) platform_syscall3(SYSCALL_dmabuf_share, arg1: (reg_t) buf, arg2: (reg_t) bufsize, arg3: (reg_t) out_paddr); |
311 | } |
312 | |
313 | /** |
314 | * dmabuf_unshare |
315 | * Unshare a DMA buffer that was previously shared with dmabuf_share(). |
316 | * The buffer will be freed after this call. |
317 | * The content of the buffer will be copied back to the userspace buffer, if vaddr is not NULL. |
318 | */ |
319 | should_inline bool syscall_dmabuf_unshare(ptr_t paddr, size_t size, void *vaddr) |
320 | { |
321 | return (bool) platform_syscall3(SYSCALL_dmabuf_unshare, arg1: (reg_t) paddr, arg2: (reg_t) size, arg3: (reg_t) vaddr); |
322 | } |
323 | |
324 | should_inline long syscall_pipe(fd_t *out_read_fd, fd_t *out_write_fd, fd_flags_t flags) |
325 | { |
326 | return (long) platform_syscall3(SYSCALL_pipe, arg1: (reg_t) out_read_fd, arg2: (reg_t) out_write_fd, arg3: (reg_t) flags); |
327 | } |
328 | |
329 | should_inline ssize_t syscall_io_readv(fd_t fd, const struct iovec *iov, int iov_count) |
330 | { |
331 | return (ssize_t) platform_syscall3(SYSCALL_io_readv, arg1: (reg_t) fd, arg2: (reg_t) iov, arg3: (reg_t) iov_count); |
332 | } |
333 | |
334 | should_inline long syscall_vfs_unmount(const char *mount_point) |
335 | { |
336 | return (long) platform_syscall1(SYSCALL_vfs_unmount, arg1: (reg_t) mount_point); |
337 | } |
338 | |
339 | should_inline long syscall_clock_gettimeofday(struct timespec *tv) |
340 | { |
341 | return (long) platform_syscall1(SYSCALL_clock_gettimeofday, arg1: (reg_t) tv); |
342 | } |
343 | |
344 | should_inline long syscall_thread_setname(tid_t tid, const char *name) |
345 | { |
346 | return (long) platform_syscall2(SYSCALL_thread_setname, arg1: (reg_t) tid, arg2: (reg_t) name); |
347 | } |
348 | |
349 | should_inline ssize_t syscall_thread_getname(tid_t tid, char *buf, size_t buf_size) |
350 | { |
351 | return (ssize_t) platform_syscall3(SYSCALL_thread_getname, arg1: (reg_t) tid, arg2: (reg_t) buf, arg3: (reg_t) buf_size); |
352 | } |
353 | |
354 | should_inline long syscall_vfs_fchmodat(fd_t dirfd, const char *path, int mode, int flags) |
355 | { |
356 | return (long) platform_syscall4(SYSCALL_vfs_fchmodat, arg1: (reg_t) dirfd, arg2: (reg_t) path, arg3: (reg_t) mode, arg4: (reg_t) flags); |
357 | } |
358 | |
359 | should_inline long syscall_io_pread(fd_t fd, void *buf, size_t count, off_t offset) |
360 | { |
361 | return (long) platform_syscall4(SYSCALL_io_pread, arg1: (reg_t) fd, arg2: (reg_t) buf, arg3: (reg_t) count, arg4: (reg_t) offset); |
362 | } |
363 | |
364 | should_inline fd_t syscall_memfd_create(const char *name, u32 flags) |
365 | { |
366 | return (fd_t) platform_syscall2(SYSCALL_memfd_create, arg1: (reg_t) name, arg2: (reg_t) flags); |
367 | } |
368 | |
369 | should_inline long syscall_signal_mask_op(int how, const sigset_t *set, sigset_t *oldset) |
370 | { |
371 | return (long) platform_syscall3(SYSCALL_signal_mask_op, arg1: (reg_t) how, arg2: (reg_t) set, arg3: (reg_t) oldset); |
372 | } |
373 | |
374 | /** |
375 | * vfs_fsync |
376 | * Synchronize the file to disk. |
377 | * If data_only is true, only the file data is synchronized, otherwise both data and metadata are synchronized. |
378 | */ |
379 | should_inline long syscall_vfs_fsync(fd_t fd, bool data_only) |
380 | { |
381 | return (long) platform_syscall2(SYSCALL_vfs_fsync, arg1: (reg_t) fd, arg2: (reg_t) data_only); |
382 | } |
383 | |
384 | |