| 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, u64 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, u64 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, u64 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, u64 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, u64 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, u64 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, u64 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, u64 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, u64 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 | should_inline long syscall_vfs_rmdir(const char *path) |
| 385 | { |
| 386 | return (long) platform_syscall1(SYSCALL_vfs_rmdir, arg1: (reg_t) path); |
| 387 | } |
| 388 | |
| 389 | |