diff options
author | Freya Murphy <freya@freyacat.org> | 2025-04-27 14:05:45 -0400 |
---|---|---|
committer | Freya Murphy <freya@freyacat.org> | 2025-04-27 14:05:45 -0400 |
commit | 53a3d70e238e423f8543164c0d4c5d2db2e1adbd (patch) | |
tree | 68ddde38efc0d759867ddba4999a2c260a08bc76 /kernel/syscall.c | |
parent | remove pit fixme (diff) | |
download | comus-53a3d70e238e423f8543164c0d4c5d2db2e1adbd.tar.gz comus-53a3d70e238e423f8543164c0d4c5d2db2e1adbd.tar.bz2 comus-53a3d70e238e423f8543164c0d4c5d2db2e1adbd.zip |
new syscalls
Diffstat (limited to 'kernel/syscall.c')
-rw-r--r-- | kernel/syscall.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/kernel/syscall.c b/kernel/syscall.c index 5e0abff..f5dc56e 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -1,9 +1,13 @@ #include <comus/cpu.h> #include <comus/syscalls.h> #include <comus/drivers/acpi.h> +#include <comus/drivers/gpu.h> +#include <comus/drivers/pit.h> #include <comus/memory.h> #include <comus/procs.h> +#include <stdint.h> +#define RET(type, name) type *name = (type *)(¤t_pcb->regs->rax) #define ARG1(type, name) type name = (type)(current_pcb->regs->rdi) #define ARG2(type, name) type name = (type)(current_pcb->regs->rsi) #define ARG3(type, name) type name = (type)(current_pcb->regs->rdx) @@ -61,6 +65,52 @@ static int sys_poweroff(void) return 1; } +static int sys_drm(void) +{ + ARG1(void **, res_fb); + ARG2(int *, res_width); + ARG3(int *, res_height); + ARG4(int *, res_bpp); + + void *pADDR, *vADDR; + int width, height, bpp; + size_t len; + + if (gpu_dev == NULL) + return 1; + + len = gpu_dev->width * gpu_dev->height * gpu_dev->bit_depth / 8; + pADDR = + mem_get_phys(kernel_mem_ctx, (void *)(uintptr_t)gpu_dev->framebuffer); + if (pADDR == NULL) + return 1; + + vADDR = mem_mapaddr(current_pcb->memctx, pADDR, (void *)0x1000000000, len, + F_PRESENT | F_WRITEABLE | F_UNPRIVILEGED); + if (vADDR == NULL) + return 1; + + width = gpu_dev->width; + height = gpu_dev->height; + bpp = gpu_dev->bit_depth; + + mem_ctx_switch(current_pcb->memctx); + *res_fb = vADDR; + *res_width = width; + *res_height = height; + *res_bpp = bpp; + mem_ctx_switch(kernel_mem_ctx); + + return 0; +} + +static int sys_ticks(void) +{ + RET(uint64_t, res_ticks); + *res_ticks = ticks; + return 0; +} + static int (*syscall_tbl[N_SYSCALLS])(void) = { [SYS_exit] = sys_exit, [SYS_waitpid] = NULL, [SYS_fork] = NULL, [SYS_exec] = NULL, @@ -71,6 +121,7 @@ static int (*syscall_tbl[N_SYSCALLS])(void) = { [SYS_setprio] = NULL, [SYS_kill] = NULL, [SYS_sleep] = NULL, [SYS_brk] = NULL, [SYS_sbrk] = NULL, [SYS_poweroff] = sys_poweroff, + [SYS_drm] = sys_drm, [SYS_ticks] = sys_ticks, }; void syscall_handler(struct cpu_regs *regs) @@ -85,6 +136,7 @@ void syscall_handler(struct cpu_regs *regs) // update data current_pcb->regs = regs; num = current_pcb->regs->rax; + current_pcb->regs->rax = 0; // syscall number @@ -96,11 +148,12 @@ void syscall_handler(struct cpu_regs *regs) ; } - // run syscall handler (if exists) + // run syscall handler handler = syscall_tbl[num]; if (handler != NULL) - handler(); + ret = handler(); - // save return value - current_pcb->regs->rax = ret; + // on failure, set rax + if (ret) + current_pcb->regs->rax = ret; } |