summaryrefslogtreecommitdiff
path: root/kernel/syscall.c
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2025-04-27 14:05:45 -0400
committerFreya Murphy <freya@freyacat.org>2025-04-27 14:05:45 -0400
commit53a3d70e238e423f8543164c0d4c5d2db2e1adbd (patch)
tree68ddde38efc0d759867ddba4999a2c260a08bc76 /kernel/syscall.c
parentremove pit fixme (diff)
downloadcomus-53a3d70e238e423f8543164c0d4c5d2db2e1adbd.tar.gz
comus-53a3d70e238e423f8543164c0d4c5d2db2e1adbd.tar.bz2
comus-53a3d70e238e423f8543164c0d4c5d2db2e1adbd.zip
new syscalls
Diffstat (limited to 'kernel/syscall.c')
-rw-r--r--kernel/syscall.c61
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 *)(&current_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;
}