/* syscall.c - System call interface for Pactor64 */ #include "syscall.h" /* Syscall dispatch table */ typedef uint64_t (*syscall_fn_t)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); static syscall_fn_t syscall_table[MAX_SYSCALL]; /* Current heap break for brk() */ static uint64_t current_brk = 0; /* === Individual syscall implementations === */ static uint64_t sys_read(uint64_t fd, uint64_t buf, uint64_t count, uint64_t a3, uint64_t a4) { (void)buf; (void)count; (void)a3; (void)a4; if (fd == 0) return 0; /* stdin: no input yet */ return (uint64_t)-1; } static uint64_t sys_write(uint64_t fd, uint64_t buf, uint64_t count, uint64_t a3, uint64_t a4) { (void)a3; (void)a4; if (fd == 1 || fd == 2) { const char *str = (const char *)(uintptr_t)buf; for (uint64_t i = 0; i < count; i++) serial_putc(str[i]); return count; } return (uint64_t)-1; } static uint64_t sys_open(uint64_t path, uint64_t flags, uint64_t mode, uint64_t a3, uint64_t a4) { (void)path; (void)flags; (void)mode; (void)a3; (void)a4; kprintf("[syscall] open: not yet implemented\n"); return (uint64_t)-1; } static uint64_t sys_close(uint64_t fd, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4) { (void)a1; (void)a2; (void)a3; (void)a4; if (fd <= 2) return 0; return (uint64_t)-1; } static uint64_t sys_exit(uint64_t status, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4) { (void)a1; (void)a2; (void)a3; (void)a4; kprintf("\n[syscall] Process exited with status %d\n", status); /* Return to kernel shell instead of hanging */ return (uint64_t)-999; return 0; /* unreachable */ } static uint64_t sys_brk(uint64_t addr, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4) { (void)a1; (void)a2; (void)a3; (void)a4; if (current_brk == 0) { current_brk = addr; return current_brk; } if (addr == 0) return current_brk; if (addr > current_brk) current_brk = addr; return current_brk; } /* Initialize the syscall interface */ void syscall_init(void) { for (int i = 0; i < MAX_SYSCALL; i++) syscall_table[i] = 0; syscall_table[SYS_READ] = sys_read; syscall_table[SYS_WRITE] = sys_write; syscall_table[SYS_OPEN] = sys_open; syscall_table[SYS_CLOSE] = sys_close; syscall_table[SYS_EXIT] = sys_exit; syscall_table[SYS_BRK] = sys_brk; /* STAR: kernel CS=0x08 (SS=0x10), user CS base=0x18 * SYSCALL: CS=STAR[63:48]=0x08, SS=STAR[63:48]+8=0x10 * SYSRET: CS=STAR[47:32]|3=0x1B, SS=(STAR[47:32]+8)|3=0x23 */ uint64_t star = ((uint64_t)0x0008 << 48) | ((uint64_t)0x0018 << 32); write_msr(MSR_STAR, star); write_msr(MSR_LSTAR, (uint64_t)(uintptr_t)syscall_entry); /* FMASK: clear IF and DF on SYSCALL entry */ write_msr(MSR_FMASK, (1 << 9) | (1 << 10)); kprintf("[syscall] Initialized SYSCALL interface\n"); kprintf("[syscall] STAR=0x%x LSTAR=0x%x\n", star, (uint64_t)(uintptr_t)syscall_entry); } /* Main syscall dispatcher - called from assembly */ uint64_t syscall_dispatch(uint64_t num, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t arg4, uint64_t arg5) { if (num >= MAX_SYSCALL || syscall_table[num] == 0) { kprintf("[syscall] Unimplemented syscall %d\n", num); return (uint64_t)-38; /* ENOSYS */ } return syscall_table[num](arg1, arg2, arg3, arg4, arg5); }