#pragma once #include "types.h" /* Syscall Numbers (passed in RAX) */ #define SYS_IPC_CALL 1 /* Synchronous call: send message & wait for reply */ #define SYS_IPC_REPLY_RECV 2 /* Server fast-path: reply to current and wait next */ #define SYS_IPC_SEND 3 /* Asynchronous/non-blocking send */ #define SYS_IPC_RECV 4 /* Block waiting for incoming message */ #define SYS_MEM_MAP 5 /* Map memory / shared memory region */ #define SYS_CAP_GRANT 6 /* Delegate capability to CNode */ #define SYS_THREAD_YIELD 7 /* Yield CPU slice */ #define SYS_THREAD_EXIT 8 /* Terminate current thread */ #define SYS_LOG_DEBUG 9 /* Direct Ring 0 debug print */ #ifndef __ASSEMBLER__ #ifdef __cplusplus extern "C" { #endif /* Low-level inline syscall invocations adhering to System V AMD64 ABI + Fast-Path */ static inline sysret_t sys_ipc_call_raw(cap_t dest_cap, uint64_t msg_code, uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t *out0, uint64_t *out1) { register uint64_t rax __asm__("rax") = SYS_IPC_CALL; register uint64_t rdi __asm__("rdi") = dest_cap; register uint64_t rsi __asm__("rsi") = msg_code; register uint64_t rdx __asm__("rdx") = arg0; register uint64_t r8 __asm__("r8") = arg1; register uint64_t r9 __asm__("r9") = arg2; register uint64_t r10 __asm__("r10") = arg3; __asm__ volatile( "syscall" : "+r"(rax), "+r"(rdx), "+r"(r8) : "r"(rdi), "r"(rsi), "r"(r9), "r"(r10) : "rcx", "r11", "memory" ); if (out0) *out0 = rdx; if (out1) *out1 = r8; return (sysret_t)rax; } static inline sysret_t sys_ipc_reply_recv_raw(cap_t listen_ep, uint64_t reply_to_tid, uint64_t reply_val0, uint64_t reply_val1, uint64_t *sender_tid, uint64_t *opcode, uint64_t *arg0, uint64_t *arg1) { register uint64_t rax __asm__("rax") = SYS_IPC_REPLY_RECV; register uint64_t rdi __asm__("rdi") = listen_ep; register uint64_t rsi __asm__("rsi") = reply_to_tid; register uint64_t rdx __asm__("rdx") = reply_val0; register uint64_t r8 __asm__("r8") = reply_val1; __asm__ volatile( "syscall" : "+r"(rax), "+r"(rdi), "+r"(rsi), "+r"(rdx), "+r"(r8) : : "rcx", "r11", "memory" ); if (sender_tid) *sender_tid = rdi; if (opcode) *opcode = rsi; if (arg0) *arg0 = rdx; if (arg1) *arg1 = r8; return (sysret_t)rax; } static inline sysret_t sys_yield(void) { register uint64_t rax __asm__("rax") = SYS_THREAD_YIELD; __asm__ volatile("syscall" : "+r"(rax) : : "rcx", "r11", "memory"); return (sysret_t)rax; } static inline void sys_exit(int code) { register uint64_t rax __asm__("rax") = SYS_THREAD_EXIT; register uint64_t rdi __asm__("rdi") = (uint64_t)code; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); __builtin_unreachable(); } static inline sysret_t sys_log_debug(const char *msg, size_t len) { register uint64_t rax __asm__("rax") = SYS_LOG_DEBUG; register uint64_t rdi __asm__("rdi") = (uint64_t)msg; register uint64_t rsi __asm__("rsi") = (uint64_t)len; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); return (sysret_t)rax; } #ifdef __cplusplus } #endif #endif /* __ASSEMBLER__ */