diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/include/comus/syscalls.h | 4 | ||||
-rw-r--r-- | kernel/syscall.c | 61 |
2 files changed, 60 insertions, 5 deletions
diff --git a/kernel/include/comus/syscalls.h b/kernel/include/comus/syscalls.h index 0105104..f714184 100644 --- a/kernel/include/comus/syscalls.h +++ b/kernel/include/comus/syscalls.h @@ -28,9 +28,11 @@ #define SYS_brk 15 #define SYS_sbrk 16 #define SYS_poweroff 17 +#define SYS_drm 18 +#define SYS_ticks 19 // UPDATE THIS DEFINITION IF MORE SYSCALLS ARE ADDED! -#define N_SYSCALLS 18 +#define N_SYSCALLS 20 // interrupt vector entry for system calls #define VEC_SYSCALL 0x80 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; } |