Files
osc2025/kernel/lib/syscall.c
2025-05-04 20:38:25 +08:00

118 lines
3.1 KiB
C

#include <syscall.h>
#include <logger.h>
#include <uart.h>
#include <thread.h>
#include <process.h>
#include <mbox.h>
#include <exec.h>
void syscall_handler(trapframe_t *regs)
{
thread_t *th = get_current();
th->process->regs = regs;
switch (regs->x8) {
case 0: // int32_t getpid(void)
regs->x0 = sys_getpid();
break;
case 1: // size_t uart_read(char buf[], size_t size)
regs->x0 = sys_uart_read((char *)regs->x0, (size_t)regs->x1);
break;
case 2: // size_t uart_write(const char buf[], size_t size)
regs->x0 = sys_uart_write((const char *)regs->x0, (size_t)regs->x1);
break;
case 3: // int32_t exec(const char *name, char *const argv[])
regs->x0 = sys_exec((const char *)regs->x0, (char *const *)regs->x1);
break;
case 4: // int32_t fork(void)
regs->x0 = sys_fork();
break;
case 5: // void exit(int32_t status)
sys_exit((int32_t)regs->x0);
break;
case 6: // int32_t mbox_call(uint8_t ch, uint32_t *mbox)
regs->x0 = sys_mbox_call((uint8_t)regs->x0, (uint32_t *)regs->x1);
break;
case 7: // void kill_by_id(int32_t pid)
sys_kill_by_id((int32_t)regs->x0);
break;
case 8: // void signal(int32_t SIGNAL, signal_handler_t handler)
sys_signal((int32_t)regs->x0, (signal_handler_t)regs->x1);
break;
case 9: // void kill(int32_t pid, int32_t SIGNAL)
sys_kill((int32_t)regs->x0, (int32_t)regs->x1);
break;
case 10: // void sigreturn(void)
sys_sigreturn();
break;
default:
LOG("unsupported syscall"); ERROR(regs->x8);
}
}
int32_t sys_getpid(void)
{
thread_t *th = get_current();
if (th->process == 0x0)
return -1;
return th->process->pid;
}
size_t sys_uart_read(char buf[], size_t size)
{ return uart_getb((uint8_t *)buf, size); }
size_t sys_uart_write(const char buf[], size_t size)
{ return uart_putb((const uint8_t *)buf, size); }
int32_t sys_exec(const char *name, char *const argv[])
{ return run_process_by_name((uint64_t)name); /* ignore argv for now */ }
int32_t sys_fork(void)
{
thread_t *cur = get_current();
process_t *newproc = fork_process(cur->process);
run_thread(run_process, (uint64_t)newproc);
return newproc->pid;
}
void sys_exit(int32_t status)
{
thread_t *th = get_current();
th->status = THREAD_STATUS_ZOMBIE;
}
int32_t sys_mbox_call(uint8_t ch, uint32_t *mbox)
{ return mbox_call(ch, mbox); }
void sys_kill_by_id(int32_t pid)
{
if (!global_processes || global_processes->size <= (size_t)pid) {
LOG("Process not exist"); INFOR(pid);
return;
}
process_t *process = VEC_AT(process_t, global_processes, pid);
process->th->status = THREAD_STATUS_ZOMBIE;
LOG("Process killed"); INFOR(pid);
}
void sys_signal(int32_t SIGNAL, signal_handler_t handler)
{
thread_t *th = get_current();
th->process->sighandlers[SIGNAL] = handler;
LOG(handler); LOG(SIGNAL); DEBUG_SIGNAL("registered");
}
void sys_kill(int32_t pid, int32_t SIGNAL)
{
process_t *process = VEC_AT(process_t, global_processes, pid);
process->sigstate[SIGNAL] = true;
}
void sys_sigreturn(void)
{
DEBUG_SIGNAL("sigreturn");
thread_t *th = get_current();
user_exec(th->process->regs);
}