#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_MEM_SHARE 4 /* Map shared physical memory between processes */ #define SYS_MEM_ALLOC 5 /* Dynamically allocate virtual pages in process space */ #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 */ #define SYS_KEY_READ 10 /* Read character from keyboard / serial buffer */ #define SYS_SYSINFO 11 /* Query system/memory/thread information */ #define SYS_SHUTDOWN 12 /* Power off QEMU / system */ #define SYS_REBOOT 13 /* Reboot system */ #define SYS_RTC_GET 14 /* Get CMOS real-time clock */ #define SYS_FB_INFO 15 /* Query Limine Linear Framebuffer */ #define SYS_PROC_KILL 16 /* Terminate process/thread by PID */ #define SYS_DMESG 17 /* Retrieve kernel boot log */ #define SYS_PROC_LIST 18 /* Query active kernel thread list */ #define SYS_PROC_SPAWN 19 /* Dynamically load and run ELF process */ #define SYS_DMA_ALLOC 20 /* Allocate physical DMA buffer */ #define SYS_MOUSE_GET 21 /* Query PS/2 mouse coordinates and buttons */ #define SYS_GETRANDOM 22 /* Hardware RNG: fill buffer with random bytes */ #define SYS_ACPI_INFO 23 /* Query ACPI power and table statistics */ #define SYS_CPU_INFO 24 /* Query multi-core CPU core count and current core ID */ #define SYS_NOTIFY_SEND 25 /* Post desktop notification to GUI compositor */ #define SYS_NOTIFY_RECV 26 /* Poll pending desktop notifications non-blockingly */ #define SYS_MODULE_EXEC 27 /* Find and execute boot module by name (.opc or .elf) */ #define SYS_MODULE_LIST 28 /* List available boot modules in memory */ #define SYS_TASK_CREATE 29 /* Allocate new user PML4 & thread structure: (name, name_len) -> tid */ #define SYS_TASK_MAP_PAGE 30 /* Map page into target task: (target_tid, vaddr, src_buf, flags) -> status */ #define SYS_TASK_START 31 /* Activate thread: (target_tid, entry_rip, user_rsp) -> status */ #define SYS_CPU_SENSORS 32 /* Query CPU hardware sensors (DTS, MSR, frequency, power): (out_sensors) -> status */ /* Standard Ring 3 Service Endpoints */ #define UART_SERVICE_ENDPOINT 2 #define PROCMGR_ENDPOINT 4 #define VFS_ENDPOINT 5 #define NET_ENDPOINT 6 /* PROCMGR_ENDPOINT (4) IPC Opcodes */ #define PROC_OP_LIST 1 #define PROC_OP_KILL 2 #define PROC_OP_SPAWN 3 #define PROC_OP_STAT 4 /* POSIX Process Signals */ #define SIGHUP 1 #define SIGINT 2 #define SIGQUIT 3 #define SIGILL 4 #define SIGTRAP 5 #define SIGABRT 6 #define SIGBUS 7 #define SIGFPE 8 #define SIGKILL 9 #define SIGUSR1 10 #define SIGSEGV 11 #define SIGUSR2 12 #define SIGPIPE 13 #define SIGALRM 14 #define SIGTERM 15 #ifndef __ASSEMBLER__ #ifdef __cplusplus extern "C" { #endif typedef struct acpi_info_data { uint32_t found; uint32_t revision; uint32_t lapic_count; uint16_t pm1a_cnt; uint16_t pm1b_cnt; } acpi_info_data_t; typedef struct cpu_info_data { uint32_t cores_online; uint32_t current_cpu_id; uint64_t core_ticks[4]; } cpu_info_data_t; typedef struct mouse_data { int32_t x; int32_t y; uint32_t buttons; /* bit 0 = Left, bit 1 = Right, bit 2 = Middle */ } mouse_data_t; typedef struct thread_info { uint64_t tid; char name[32]; uint32_t state; // 0=Unused, 1=Ready, 2=Running, 3=Blocked, 4=Dead uint64_t cpu_ticks; uint64_t user_rip; uint64_t user_rsp; } thread_info_t; typedef struct dma_alloc_data { uint64_t virt_addr; uint64_t phys_addr; uint64_t size_bytes; } dma_alloc_data_t; typedef struct fb_info_data { uint64_t fb_addr; uint64_t width; uint64_t height; uint64_t pitch; uint32_t bpp; } fb_info_data_t; typedef fb_info_data_t fb_info_t; typedef struct sysinfo_data { uint64_t uptime_ticks; uint64_t total_memory_bytes; uint64_t free_memory_bytes; uint32_t active_threads; uint32_t cpu_cores; } sysinfo_data_t; typedef struct rtc_data { uint16_t year; uint8_t month; uint8_t day; uint8_t hour; uint8_t minute; uint8_t second; } rtc_data_t; typedef struct cpu_sensors_data { uint32_t core_temp_c[4]; /* Temperature per core in degrees Celsius */ uint32_t core_mhz[4]; /* Real-time frequency per core in MHz */ uint32_t pkg_watts_mw; /* Package power consumption in milliwatts */ uint32_t throttle_flags; /* Thermal throttle active flags */ uint32_t tj_max; /* Junction temperature max */ char vendor[16]; /* GenuineIntel / AuthenticAMD */ } cpu_sensors_data_t; static inline sysret_t sys_cpu_sensors(cpu_sensors_data_t *out_sensors) { register uint64_t rax __asm__("rax") = SYS_CPU_SENSORS; register uint64_t rdi __asm__("rdi") = (uint64_t)out_sensors; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); return (sysret_t)rax; } /* 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 void *sys_mem_alloc(size_t size_bytes) { register uint64_t rax __asm__("rax") = SYS_MEM_ALLOC; register uint64_t rdi __asm__("rdi") = (uint64_t)size_bytes; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); return (void *)rax; } static inline sysret_t sys_mem_share(uint64_t target_tid, uintptr_t src_vaddr, size_t size, uintptr_t target_vaddr) { register uint64_t rax __asm__("rax") = SYS_MEM_SHARE; register uint64_t rdi __asm__("rdi") = target_tid; register uint64_t rsi __asm__("rsi") = (uint64_t)src_vaddr; register uint64_t rdx __asm__("rdx") = (uint64_t)size; register uint64_t r8 __asm__("r8") = (uint64_t)target_vaddr; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi), "r"(rdx), "r"(r8) : "rcx", "r11", "memory"); return (sysret_t)rax; } static inline int sys_key_read(void) { register uint64_t rax __asm__("rax") = SYS_KEY_READ; __asm__ volatile("syscall" : "+r"(rax) : : "rcx", "r11", "memory"); return (int)rax; } static inline sysret_t sys_sysinfo(sysinfo_data_t *out_info) { register uint64_t rax __asm__("rax") = SYS_SYSINFO; register uint64_t rdi __asm__("rdi") = (uint64_t)out_info; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); return (sysret_t)rax; } static inline sysret_t sys_rtc_get(rtc_data_t *out_rtc) { register uint64_t rax __asm__("rax") = SYS_RTC_GET; register uint64_t rdi __asm__("rdi") = (uint64_t)out_rtc; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); return (sysret_t)rax; } static inline void sys_shutdown(void) { register uint64_t rax __asm__("rax") = SYS_SHUTDOWN; __asm__ volatile("syscall" : "+r"(rax) : : "rcx", "r11", "memory"); } static inline void sys_reboot(void) { register uint64_t rax __asm__("rax") = SYS_REBOOT; __asm__ volatile("syscall" : "+r"(rax) : : "rcx", "r11", "memory"); } 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; } static inline int64_t sys_module_exec(const char *name) { register uint64_t rax __asm__("rax") = SYS_MODULE_EXEC; register uint64_t rdi __asm__("rdi") = (uint64_t)name; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi) : "rcx", "r11", "memory"); return (int64_t)rax; } static inline int sys_module_list(char *out_buf, size_t max_len) { register uint64_t rax __asm__("rax") = SYS_MODULE_LIST; register uint64_t rdi __asm__("rdi") = (uint64_t)out_buf; register uint64_t rsi __asm__("rsi") = (uint64_t)max_len; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); return (int)rax; } static inline int64_t sys_task_create(const char *name, size_t name_len) { register uint64_t rax __asm__("rax") = SYS_TASK_CREATE; register uint64_t rdi __asm__("rdi") = (uint64_t)name; register uint64_t rsi __asm__("rsi") = (uint64_t)name_len; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi) : "rcx", "r11", "memory"); return (int64_t)rax; } static inline int64_t sys_task_map_page(uint64_t target_tid, uint64_t vaddr, const void *src_buf, uint64_t flags) { register uint64_t rax __asm__("rax") = SYS_TASK_MAP_PAGE; register uint64_t rdi __asm__("rdi") = target_tid; register uint64_t rsi __asm__("rsi") = vaddr; register uint64_t rdx __asm__("rdx") = (uint64_t)src_buf; register uint64_t r8 __asm__("r8") = flags; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi), "r"(rdx), "r"(r8) : "rcx", "r11", "memory"); return (int64_t)rax; } static inline int64_t sys_task_start(uint64_t target_tid, uint64_t entry_rip, uint64_t user_rsp) { register uint64_t rax __asm__("rax") = SYS_TASK_START; register uint64_t rdi __asm__("rdi") = target_tid; register uint64_t rsi __asm__("rsi") = entry_rip; register uint64_t rdx __asm__("rdx") = user_rsp; __asm__ volatile("syscall" : "+r"(rax) : "r"(rdi), "r"(rsi), "r"(rdx) : "rcx", "r11", "memory"); return (int64_t)rax; } #ifdef __cplusplus } #endif #endif /* __ASSEMBLER__ */