167 lines
6.1 KiB
C
167 lines
6.1 KiB
C
#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 */
|
|
|
|
#ifndef __ASSEMBLER__
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
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;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* __ASSEMBLER__ */
|