summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2026-10-09 10:24:41 -0400
committerJon Santmyer <jon@jonsantmyer.com>2026-10-09 10:24:41 -0400
commitcc23ea5a4b38807e79aceb23e6f43e965926618f (patch)
tree90142bb44186f4dad7bbd82d3d53655b835c822b /sys
parent434ddcd907832b1febc7d70e4faa52109c7eb3bd (diff)
downloadjove-kernel-cc23ea5a4b38807e79aceb23e6f43e965926618f.tar.gz
jove-kernel-cc23ea5a4b38807e79aceb23e6f43e965926618f.tar.bz2
jove-kernel-cc23ea5a4b38807e79aceb23e6f43e965926618f.zip
add basic scheduler logic. rename init rootdir indexes
Diffstat (limited to 'sys')
-rw-r--r--sys/link.c1
-rw-r--r--sys/objdir.c114
-rw-r--r--sys/objdir.h27
-rw-r--r--sys/syscall.c33
-rw-r--r--sys/syscall.h1
-rw-r--r--sys/syscall_pcb.c11
-rw-r--r--sys/syscall_untyped.c43
7 files changed, 214 insertions, 16 deletions
diff --git a/sys/link.c b/sys/link.c
index 45c118a..04a15cf 100644
--- a/sys/link.c
+++ b/sys/link.c
@@ -1,5 +1,6 @@
#include "link.h"
#include "arch/x86_64/hal/obj.h"
+#include "sys/objdir.h"
#include "hal/memory.h"
#include "lib/printf.h"
#include "jove.h"
diff --git a/sys/objdir.c b/sys/objdir.c
new file mode 100644
index 0000000..c448e85
--- /dev/null
+++ b/sys/objdir.c
@@ -0,0 +1,114 @@
+#include "api/error.h"
+#include "arch/x86_64/hal/obj.h"
+#include "hal/memory.h"
+#include "hal/obj.h"
+#include "lib/string.h"
+#include "jove.h"
+#include <errno.h>
+
+int
+objdir_new(jove_owned_obj_t *untyped_obj)
+{
+ jove_untyped_t *untyped = obj_deref(untyped_obj);
+ if((uintptr_t)untyped & (JOVE_OBJDIR_SIZE - 1)) return -EALIGN;
+ if(untyped->limit != JOVE_OBJDIR_SIZE) return -EBADSIZE;
+
+ memset(untyped, 0, JOVE_OBJDIR_SIZE);
+ obj_settype(untyped_obj, JOVE_OBJ_OBJDIR);
+ return 0;
+}
+
+jove_obj_t
+objdir_peeklocal(
+ jove_owned_obj_t *objdir_obj,
+ uint16_t entry)
+{
+ if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) {
+ errno = EBADOBJ;
+ return (jove_obj_t) { 0 };
+ }
+ if(entry >= JOVE_OBJDIR_ENTRIES) {
+ errno = EBADPATH;
+ return (jove_obj_t) { 0 };
+ }
+
+ jove_objdir_t *objtab = obj_deref(objdir_obj);
+ return objtab->entries[entry];
+}
+
+jove_owned_obj_t*
+objdir_getlocal(
+ jove_owned_obj_t *objdir_obj,
+ uint16_t entry)
+{
+ if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) {
+ reterr(EBADOBJ);
+ }
+ if(entry >= JOVE_OBJDIR_ENTRIES) {
+ reterr(EBADPATH);
+ }
+
+ jove_objdir_t *objtab = obj_deref(objdir_obj);
+ return obj_take(&objtab->entries[entry]);
+}
+
+jove_owned_obj_t*
+objdir_trygetlocal(
+ jove_owned_obj_t *objdir_obj,
+ uint16_t entry)
+{
+ if(obj_gettype(objdir_obj) != JOVE_OBJ_OBJDIR) {
+ reterr(EBADOBJ);
+ }
+ if(entry >= JOVE_OBJDIR_ENTRIES) {
+ reterr(EBADPATH);
+ }
+
+ jove_objdir_t *objtab = obj_deref(objdir_obj);
+ return obj_trytake(&objtab->entries[entry]);
+}
+
+jove_owned_obj_t*
+objdir_getobj(
+ jove_owned_obj_t *objdir_obj,
+ const uint16_t *path,
+ size_t path_len)
+{
+ errno = 0;
+ if(path_len == 0) {
+ return objdir_obj;
+ }
+ {
+ jove_owned_obj_t *child_objdir = objdir_getlocal(objdir_obj, path[0]);
+ if(child_objdir == 0) {
+ reterr(EBADPATH);
+ }
+
+ jove_owned_obj_t *target_obj = objdir_getobj(child_objdir, path + 1, path_len - 1);
+ obj_release(child_objdir);
+ return target_obj;
+ }
+}
+
+jove_owned_obj_t*
+objdir_trygetobj(
+ jove_owned_obj_t *objdir_obj,
+ const uint16_t *path,
+ size_t path_len)
+{
+ errno = 0;
+ if(path_len == 0) {
+ return objdir_obj;
+ }
+ {
+ jove_owned_obj_t *child_objdir = objdir_trygetlocal(objdir_obj, path[0]);
+ if(child_objdir == 0) {
+ return 0;
+ }
+
+ jove_owned_obj_t *target_obj = objdir_trygetobj(child_objdir, path + 1, path_len - 1);
+ obj_release(child_objdir);
+ return target_obj;
+ }
+}
+
diff --git a/sys/objdir.h b/sys/objdir.h
new file mode 100644
index 0000000..54e9618
--- /dev/null
+++ b/sys/objdir.h
@@ -0,0 +1,27 @@
+#ifndef _JOVE_SYS_OBJDIR_H
+#define _JOVE_SYS_OBJDIR_H 1
+
+#include "hal/obj.h"
+
+int objdir_new(jove_owned_obj_t *untyped_obj);
+/*Returns the n'th entry of the object directory passed.
+ * If the passed object is not an objdir, returns NULL and sets errno to EBADOBJ.
+ * If the passed entry index is out of bounds, returns NULL and sets errno to EOOB.*/
+jove_owned_obj_t *objdir_getlocal(jove_owned_obj_t *objdir_obj, uint16_t entry);
+/*Same as objdir_getlocal except does not block if entry obj is taken.*/
+jove_owned_obj_t *objdir_trygetlocal(jove_owned_obj_t *objdir_obj, uint16_t entry);
+jove_obj_t objdir_peeklocal(jove_owned_obj_t *objdir_obj, uint16_t entry);
+
+/*Recursively seeks through an object directory for an object following the passed
+ * path variable.
+ * If the path length is zero, returns the passed object.
+ * If the passed object is not an objdir, returns NULL and sets errno to EBADOBJ.
+ * If any object excluding the object at the end of the path is not an objdir,
+ * returns NULL and sets errno to EBADOBJ.
+ * If any entry in the path is out of bounds, returns NULL and sets errno to EBADOBJ.*/
+jove_owned_obj_t *objdir_getobj(jove_owned_obj_t *objdir_obj, const uint16_t *path, size_t path_len);
+/*Same as objdir_getobj but does not block if child objects are locked.*/
+jove_owned_obj_t *objdir_trygetobj(jove_owned_obj_t *objdir_obj, const uint16_t *path, size_t path_len);
+
+
+#endif
diff --git a/sys/syscall.c b/sys/syscall.c
index 05eeb58..0c40418 100644
--- a/sys/syscall.c
+++ b/sys/syscall.c
@@ -87,6 +87,7 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
ctx.pcb = process_current();
pcb_t *pcb = obj_deref(ctx.pcb);
+
ctx.objdir = lockstack_push(&ctx.lockstack, obj_take(pcb_getrootdir(pcb)));
ctx.message = link_try_traverse_objdir(
@@ -113,8 +114,8 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
goto release_return;
}
- uintptr_t message_vptr = message_unmap(ctx.message.obj,
- (jove_owned_obj_t*)pcb_getpagedir(pcb));
+ jove_owned_obj_t *pagedir = lockstack_push(&ctx.lockstack, pcb_getpagedir(ctx.objdir));
+ uintptr_t message_vptr = message_unmap(ctx.message.obj, pagedir);
size_t messagelen = 0x1000;
void *messagedata = (void*)message_getdata(ctx.message.obj);
@@ -135,27 +136,31 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen)
ctx.target = link_try_traverse_objdir(
ctx.objdir, &ctx.lockstack, ctx.header->pathlen, ctx.header->path);
- if(ctx.target.obj != 0) {
- sysret = _syscall_handle_switch(&ctx);
- }else{
- //Check if we're trying to reference the PCB. If we are, we should set it as the target
- //regardless of lock.
- if(ctx.header->pathlen == 1 &&
- objdir_peeklocal(ctx.objdir, ctx.header->path[0]).data == ctx.pcb->locked.data)
- {
- ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb };
- sysret = _syscall_handle_switch(&ctx);
-
+ if(ctx.target.obj == 0) {
+ //Check if we're trying to reference objects we've already locked in this function.
+ //If we are, we should set it as the target regardless of lock,
+ //since we're the ones with the lock already.
+ if(ctx.header->pathlen == 1) {
+ if(ctx.header->path[0] == PCB_ROOTDIR_SELF_I)
+ ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = ctx.pcb };
+ else if(ctx.header->path[0] == PCB_ROOTDIR_PAGEDIR_I)
+ ctx.target = (jove_perm_obj_t) { .permissions = 0xFF, .obj = pagedir };
+ else
+ goto fail_target_busy;
}else{
+fail_target_busy:
//Could not find payload target in pcb rootdir.
klogf("Process %i tried to call syscall with bad target path %P : %s\n",
pcb_getpid(pcb), header->path, header->pathlen, errstr(errno));
sysret = -errno;
+ goto remap_return;
}
}
+ sysret = _syscall_handle_switch(&ctx);
+
remap_return:
- message_remap(ctx.message.obj, (jove_owned_obj_t*)pcb_getpagedir(pcb), message_vptr);
+ message_remap(ctx.message.obj, pagedir, message_vptr);
release_return:
lockstack_popall(&ctx.lockstack);
diff --git a/sys/syscall.h b/sys/syscall.h
index 6387d79..946417c 100644
--- a/sys/syscall.h
+++ b/sys/syscall.h
@@ -4,6 +4,7 @@
#include "config.h"
#include "api/syscall.h"
#include "hal/obj.h"
+#include "sys/objdir.h"
#include "lockstack.h"
#include "link.h"
#include <stdint.h>
diff --git a/sys/syscall_pcb.c b/sys/syscall_pcb.c
index b77be95..a37e4bb 100644
--- a/sys/syscall_pcb.c
+++ b/sys/syscall_pcb.c
@@ -1,14 +1,21 @@
#include "api/error.h"
+#include "jove.h"
#include "lib/printf.h"
+#include "proc/process.h"
+#include "proc/scheduler.h"
#include "syscall.h"
+#include "errno.h"
int
s_syscall_pcb_yield(jove_owned_obj_t *pcb_obj,
size_t bytes_left,
void *payload_data)
{
- kprintf("%s: Stub!\n", __func__);
- return 0;
+ size_t bytes_needed = sizeof(pid_t);
+ CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload");
+
+ pid_t subject_pid = *((pid_t*)payload_data);
+ return scheduler_yield(subject_pid);
}
int
diff --git a/sys/syscall_untyped.c b/sys/syscall_untyped.c
index 8fe592d..1ec21c7 100644
--- a/sys/syscall_untyped.c
+++ b/sys/syscall_untyped.c
@@ -2,6 +2,7 @@
#include "hal/memory.h"
#include "jove.h"
#include "lib/printf.h"
+#include "proc/process.h"
#include "syscall.h"
static int
@@ -73,6 +74,27 @@ s_syscall_untyped_merge(
return sysret;
}
+int
+s_syscall_untyped_retype_pcb(jove_owned_obj_t *untyped_obj,
+ lockstack_t *lockstack,
+ jove_owned_obj_t *rootdir,
+ struct syscall_header *header)
+{
+ jove_untyped_t *untyped = obj_deref(untyped_obj);
+ CHECK_TOOSMALL(PCB_MINSIZE, untyped->limit, "Untyped object too small for PCB");
+
+ jove_perm_obj_t objdir_obj = link_try_traverse_objdir(
+ rootdir, lockstack, header->pathlen - 1, header->path);
+ if(errno) {
+ klogf("Unable to retrieve parent objdir at %P\n",
+ header->path, header->pathlen - 1);
+ return -errno;
+ }
+ CHECK_OBJPERM(objdir_obj, JOVE_PERM_ALL, "New PCB needs full access to it's root objdir!");
+
+ obj_settype(untyped_obj, JOVE_OBJ_PCB);
+ return pcb_new(untyped_obj, untyped->limit, objdir_obj.obj);
+}
int _syscall_handle_untyped(syscall_context_t *ctx)
{
@@ -99,6 +121,27 @@ int _syscall_handle_untyped(syscall_context_t *ctx)
&ctx->lockstack, ctx->objdir, ctx->target.obj, ctx->bytes_left, ctx->payload);
return -EPERM;
+ case SYSCALL_UNTYPED_RETYPE_OBJDIR:
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_RETYPE)
+ return objdir_new(ctx->target.obj);
+ return -EPERM;
+
+ case SYSCALL_UNTYPED_RETYPE_PAGEDIR:
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_RETYPE)
+ return pagedir_new(ctx->target.obj);
+ return -EPERM;
+
+ case SYSCALL_UNTYPED_RETYPE_SHMEMORY:
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_RETYPE)
+ return shmem_new(ctx->target.obj);
+ return -EPERM;
+
+ case SYSCALL_UNTYPED_RETYPE_PCB:
+ if(ctx->target.permissions & SYSCALL_PERM_UNTYPED_RETYPE)
+ return s_syscall_untyped_retype_pcb(
+ ctx->target.obj, &ctx->lockstack, ctx->objdir, ctx->header);
+ return -EPERM;
+
default:
return -EBADCALL;
}