summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/error.h1
-rw-r--r--api/init.h31
-rw-r--r--api/process.h18
-rw-r--r--api/syscall.h20
-rw-r--r--arch/x86_64/hal/obj.c99
-rw-r--r--arch/x86_64/hal/paging.c14
-rw-r--r--arch/x86_64/hal/serial_com.c5
-rw-r--r--arch/x86_64/hal/smp.c18
-rw-r--r--arch/x86_64/lib/printf.c5
-rw-r--r--arch/x86_64/main.c2
-rw-r--r--arch/x86_64/proc/init.c13
-rw-r--r--arch/x86_64/proc/process.c52
-rw-r--r--arch/x86_64/proc/process.h7
-rw-r--r--arch/x86_64/proc/scheduler.c20
-rw-r--r--arch/x86_64/proc/switch.s9
-rw-r--r--arch/x86_64/sys/syscall.c2
-rw-r--r--boot/initrd.c3
-rw-r--r--boot/limine/framebuffer.c3
-rw-r--r--boot/limine/memorymap.c2
-rw-r--r--config.h2
-rw-r--r--hal/memory.h4
-rw-r--r--hal/obj.h20
-rw-r--r--hal/shmem.c20
-rw-r--r--hal/smp.h5
-rw-r--r--lib/rbtree.c33
-rw-r--r--lib/rbtree.h4
-rw-r--r--lib/virtterm.c9
-rw-r--r--proc/init.c3
-rw-r--r--proc/process.c64
-rw-r--r--proc/process.h34
-rw-r--r--proc/scheduler.c52
-rw-r--r--proc/scheduler.h8
-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
39 files changed, 564 insertions, 248 deletions
diff --git a/api/error.h b/api/error.h
index af85bd9..d938100 100644
--- a/api/error.h
+++ b/api/error.h
@@ -21,5 +21,6 @@
#define EBADPROC 18
#define ENOMAIL 19
#define ETIMEOUT 20
+#define ENOTFOUND 21
#endif
diff --git a/api/init.h b/api/init.h
index 3458ca1..436cfa8 100644
--- a/api/init.h
+++ b/api/init.h
@@ -4,26 +4,25 @@
#include <stdint.h>
enum {
- ROOTDIR_NULL_I = 0,
- ROOTDIR_DIR_I,
- ROOTDIR_PROCESSORS_I,
- ROOTDIR_PAGEDIR_I,
- ROOTDIR_FREEMEMORY_I,
- ROOTDIR_HWMEMORY_I,
- ROOTDIR_PCB_I,
- ROOTDIR_INTERRUPTS_I,
- ROOTDIR_INITRD_I,
- ROOTDIR_MESSAGE_I,
- ROOTDIR_FRAMEBUFFER_I,
- ROOTDIR_VIRTTERM_I,
- _ROOTDIR_LAST_I
+ INIT_ROOTDIR_DIR_I = 0,
+ INIT_ROOTDIR_PCB_I,
+ INIT_ROOTDIR_PAGEDIR_I,
+ INIT_ROOTDIR_PROCESSORS_I,
+ INIT_ROOTDIR_FREEMEMORY_I,
+ INIT_ROOTDIR_HWMEMORY_I,
+ INIT_ROOTDIR_INTERRUPTS_I,
+ INIT_ROOTDIR_INITRD_I,
+ INIT_ROOTDIR_MESSAGE_I,
+ INIT_ROOTDIR_FRAMEBUFFER_I,
+ INIT_ROOTDIR_VIRTTERM_I,
+ _INIT_ROOTDIR_LAST_I
};
#ifdef __x86_64__
enum {
- ROOTDIR_IOPB_I = _ROOTDIR_LAST_I,
- ROOTDIR_SERIAL_COM_I,
- _ROOTDIR_LAST_ARCH_I
+ INIT_ROOTDIR_IOPB_I = _INIT_ROOTDIR_LAST_I,
+ INIT_ROOTDIR_SERIAL_COM_I,
+ _INIT_ROOTDIR_LAST_ARCH_I
};
#endif
diff --git a/api/process.h b/api/process.h
index 080e001..5ccf69d 100644
--- a/api/process.h
+++ b/api/process.h
@@ -5,4 +5,22 @@
typedef intmax_t pid_t;
+enum pcb_state
+{
+ _PCB_STATE_INVALID = 0,
+ PCB_STATE_DEAD,
+ PCB_STATE_EMBRYO,
+ PCB_STATE_READY,
+ PCB_STATE_RUNNING,
+ PCB_STATE_WAITING,
+ PCB_STATE_BLOCKED_MAIL
+};
+
+enum pcb_rootdir_entries
+{
+ _PCB_ROOTDIR_NULL = 0,
+ PCB_ROOTDIR_SELF_I,
+ PCB_ROOTDIR_PAGEDIR_I,
+};
+
#endif
diff --git a/api/syscall.h b/api/syscall.h
index 3f9d115..88aad81 100644
--- a/api/syscall.h
+++ b/api/syscall.h
@@ -46,13 +46,19 @@ enum
SYSCALL_UNTYPED_SIZE,
SYSCALL_UNTYPED_SPLIT,
SYSCALL_UNTYPED_MERGE,
- SYSCALL_UNTYPED_RETYPE,
+ SYSCALL_UNTYPED_RETYPE_OBJDIR,
+ SYSCALL_UNTYPED_RETYPE_PAGEDIR,
+ SYSCALL_UNTYPED_RETYPE_SHMEMORY,
+ SYSCALL_UNTYPED_RETYPE_PCB,
+ SYSCALL_UNTYPED_RETYPE_MESSAGE,
+ _SYSCALL_UNTYPED_ARCH_BEGIN
};
#define SYSCALL_PERM_UNTYPED_ADDRESS JOVE_PERM_READ
#define SYSCALL_PERM_UNTYPED_SIZE JOVE_PERM_READ
#define SYSCALL_PERM_UNTYPED_SPLIT (JOVE_PERM_WRITE | JOVE_PERM_MUTATE)
#define SYSCALL_PERM_UNTYPED_MERGE (JOVE_PERM_WRITE | JOVE_PERM_MUTATE)
+#define SYSCALL_PERM_UNTYPED_RETYPE (JOVE_PERM_WRITE | JOVE_PERM_MUTATE)
struct syscall_untyped_split
{
@@ -175,12 +181,18 @@ enum
_SYSCALL_PCB_NONE = 0,
SYSCALL_PCB_YIELD,
SYSCALL_PCB_SEND,
- SYSCALL_PCB_RECV
+ SYSCALL_PCB_RECV,
+ SYSCALL_PCB_SET_RDIR,
+ SYSCALL_PCB_SET_PDIR,
+ SYSCALL_PCB_SET_READY,
};
#define SYSCALL_PERM_PCB_YIELD (JOVE_PERM_WRITE)
-#define SYSCALL_PERM_PCB_SEND (JOVE_PERM_MUTATE)
-#define SYSCALL_PERM_PCB_RECV (JOVE_PERM_MUTATE)
+#define SYSCALL_PERM_PCB_SEND (JOVE_PERM_WRITE)
+#define SYSCALL_PERM_PCB_RECV (JOVE_PERM_WRITE)
+#define SYSCALL_PERM_PCB_SET_RDIR (JOVE_PERM_WRITE | JOVE_PERM_MUTATE)
+#define SYSCALL_PERM_PCB_SET_PDIR (JOVE_PERM_WRITE | JOVE_PERM_MUTATE)
+#define SYSCALL_PERM_PCB_SET_READY (JOVE_PERM_WRITE | JOVE_PERM_MUTATE)
#define SYSCALL_PERM_PCB_SEND_TGT (JOVE_PERM_MUTATE)
#define SYSCALL_PERM_PCB_RECV_DST (JOVE_PERM_MUTATE)
diff --git a/arch/x86_64/hal/obj.c b/arch/x86_64/hal/obj.c
index 110351c..b3658b2 100644
--- a/arch/x86_64/hal/obj.c
+++ b/arch/x86_64/hal/obj.c
@@ -28,6 +28,11 @@ obj_trytake(jove_obj_t *obj)
return (jove_owned_obj_t*)obj;
}
+jove_obj_t *obj_asunowned(jove_owned_obj_t *obj)
+{
+ return (jove_obj_t*)obj;
+}
+
jove_obj_t*
obj_release(jove_owned_obj_t *obj)
{
@@ -74,97 +79,3 @@ obj_setvalue(jove_owned_obj_t *obj, uintmax_t value)
obj->locked.value = value & 0x00007FFFFFFFFFFFULL;
}
-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/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c
index 1587c62..535d5b2 100644
--- a/arch/x86_64/hal/paging.c
+++ b/arch/x86_64/hal/paging.c
@@ -114,6 +114,18 @@ s_pagedir_get_pml1(page_t *pml4, uintptr_t vptr)
return PML_TBL(pml2, pml2i);
}
+int
+pagedir_new(jove_owned_obj_t *untyped_obj)
+{
+ jove_untyped_t *untyped = obj_deref(untyped_obj);
+ if((uintptr_t)untyped & 0xFFF) return -EALIGN;
+ if(untyped->limit != 0x1000) return -EBADSIZE;
+
+ obj_settype(untyped_obj, JOVE_OBJ_PAGEDIR);
+ memcpy(untyped, _kernel_pml4, 0x1000);
+ return 0;
+}
+
uintptr_t *pagedir_get_mapping(jove_owned_obj_t *pagedir, uintptr_t vptr)
{
page_t *pml4 = obj_deref(pagedir);
@@ -440,7 +452,7 @@ paging_pml4_init(void)
paging_pml4_switch(kernel_pml4_pptr);
{
- jove_owned_obj_t *pgdir_o = objdir_getlocal(_rootdir_obj, ROOTDIR_PAGEDIR_I);
+ jove_owned_obj_t *pgdir_o = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_PAGEDIR_I);
obj_settype(pgdir_o, JOVE_OBJ_PAGEDIR);
obj_setvalue(pgdir_o, kernel_pml4_pptr);
obj_release(pgdir_o);
diff --git a/arch/x86_64/hal/serial_com.c b/arch/x86_64/hal/serial_com.c
index 343d2ae..372a433 100644
--- a/arch/x86_64/hal/serial_com.c
+++ b/arch/x86_64/hal/serial_com.c
@@ -4,6 +4,7 @@
#include "hal/obj.h"
#include "proc/init.h"
#include "lib/printf.h"
+#include "sys/objdir.h"
static int
serial_com_recv(uint16_t port)
@@ -68,13 +69,13 @@ serial_com_init(void)
}
{
- jove_owned_obj_t *com_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_SERIAL_COM_I);
+ jove_owned_obj_t *com_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_SERIAL_COM_I);
obj_settype(com_obj, JOVE_OBJ_SERIAL_COM);
obj_setvalue(com_obj, SERIAL_COM1);
obj_release(com_obj);
}
- kprintf("Initialized COM1 on port %X for obj %X\n", SERIAL_COM1, ROOTDIR_SERIAL_COM_I);
+ kprintf("Initialized COM1 on port %X for obj %X\n", SERIAL_COM1, INIT_ROOTDIR_SERIAL_COM_I);
}
int
diff --git a/arch/x86_64/hal/smp.c b/arch/x86_64/hal/smp.c
index b894eb9..392e68f 100644
--- a/arch/x86_64/hal/smp.c
+++ b/arch/x86_64/hal/smp.c
@@ -8,6 +8,7 @@
#include "proc/process.h"
#include "lib/printf.h"
#include "lib/string.h"
+#include "sys/objdir.h"
processor_t s_processors[SMP_PROCESSORS_MAX];
@@ -43,7 +44,7 @@ smp_init_bsp(void)
processor_t *bsp = &s_processors[0];
{
- jove_owned_obj_t *processor_objdir_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_PROCESSORS_I);
+ jove_owned_obj_t *processor_objdir_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_PROCESSORS_I);
obj_settype(processor_objdir_obj, JOVE_OBJ_OBJDIR);
obj_setvalue(processor_objdir_obj, (uintptr_t)&s_processor_objdir);
@@ -58,12 +59,23 @@ smp_init_bsp(void)
paging_pml4_init();
}
-processor_t *processor_current(void)
+inline processor_t *processor_current(void)
{
return (processor_t*)msr_get_gs_base();
}
-jove_owned_obj_t *processor_pcb(processor_t *processor)
+inline jove_owned_obj_t *processor_getpcb(processor_t *processor)
{
return processor->pcb_obj;
}
+
+void
+processor_setpcb(processor_t *processor, jove_owned_obj_t *pcb_obj)
+{
+ pcb_t *pcb = obj_deref(pcb_obj);
+ if(processor->pcb) {
+ obj_release(processor_getpcb(processor));
+ }
+ processor->pcb_obj = pcb_obj;
+ processor->pcb = pcb;
+}
diff --git a/arch/x86_64/lib/printf.c b/arch/x86_64/lib/printf.c
index 794a592..db47f6b 100644
--- a/arch/x86_64/lib/printf.c
+++ b/arch/x86_64/lib/printf.c
@@ -2,6 +2,7 @@
#include "lib/printf.h"
#include "lib/virtterm.h"
#include "proc/init.h"
+#include "sys/objdir.h"
int
kvprintf(const char *fmt, va_list ap)
@@ -11,11 +12,11 @@ kvprintf(const char *fmt, va_list ap)
int wlen = (r > 256 ? 256 : r);
{
- jove_owned_obj_t *serial_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_SERIAL_COM_I);
+ jove_owned_obj_t *serial_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_SERIAL_COM_I);
serial_com_write(serial_obj, buffer, wlen);
obj_release(serial_obj);
- jove_owned_obj_t *vt_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_VIRTTERM_I);
+ jove_owned_obj_t *vt_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_VIRTTERM_I);
vt_write(vt_obj, buffer, wlen);
obj_release(vt_obj);
}
diff --git a/arch/x86_64/main.c b/arch/x86_64/main.c
index 6e2fcb8..4a40707 100644
--- a/arch/x86_64/main.c
+++ b/arch/x86_64/main.c
@@ -18,7 +18,7 @@
int errno = 0;
PAGEALIGN jove_objdir_t _rootdir;
-void *_rootdir_obj = &_rootdir.entries[ROOTDIR_DIR_I];
+void *_rootdir_obj = &_rootdir.entries[INIT_ROOTDIR_DIR_I];
struct init_payload _init_payload;
diff --git a/arch/x86_64/proc/init.c b/arch/x86_64/proc/init.c
index 3787c7b..155cff6 100644
--- a/arch/x86_64/proc/init.c
+++ b/arch/x86_64/proc/init.c
@@ -5,6 +5,7 @@
#include "jove.h"
#include "hal/obj.h"
#include "lib/string.h"
+#include "sys/objdir.h"
#include "panic/panic.h"
#include "lib/printf.h"
#include "arch/x86_64/lib/elf.h"
@@ -50,7 +51,7 @@ init_setup(void)
kpanic("Kernel commandline is missing 'init' arg.\n");
}
- jove_owned_obj_t *initrd_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_INITRD_I);
+ jove_owned_obj_t *initrd_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_INITRD_I);
jove_owned_obj_t *init_obj = initrd_seek(initrd_obj, init_path);
if(init_obj == NULL) {
kpanic("init: Cannot find file '%s' in initrd.\n", init_path);
@@ -69,7 +70,7 @@ init_setup(void)
kpanic("init: Either passed file '%s' is not an ELF file or is not loadable.\n", init_path);
}
- jove_owned_obj_t *init_pagedir = objdir_getlocal(_rootdir_obj, ROOTDIR_PAGEDIR_I);
+ jove_owned_obj_t *init_pagedir = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_PAGEDIR_I);
page_t *pml4 = obj_deref(init_pagedir);
size_t last_base = 0;
@@ -133,7 +134,7 @@ init_setup(void)
memcpy((void*)last_base, &_init_payload, sizeof(struct init_payload));
- jove_owned_obj_t *message_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_MESSAGE_I);
+ jove_owned_obj_t *message_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_MESSAGE_I);
obj_settype(message_obj, JOVE_OBJ_MESSAGE);
obj_setvalue(message_obj, last_base | 1);
obj_release(message_obj);
@@ -144,13 +145,9 @@ init_setup(void)
extern void _syscall_entry(void);
msr_set_lstar(_syscall_entry);
- //Setup KSP for syscalls
- jove_owned_obj_t *pcb_obj = process_current();
- pcb_t *pcb = obj_deref(pcb_obj);
-
- obj_release(pcb_obj);
obj_release(_rootdir_obj);
+ //Setup KSP for syscalls
uintptr_t usp = 0x00007FFFFFFFFFF8;
uintptr_t uip = init_ehdr->e_entry;
diff --git a/arch/x86_64/proc/process.c b/arch/x86_64/proc/process.c
index d5513bc..5935303 100644
--- a/arch/x86_64/proc/process.c
+++ b/arch/x86_64/proc/process.c
@@ -1,4 +1,5 @@
#include "process.h"
+#include "hal/memory.h"
#include "proc/process.h"
#include "arch/x86_64/hal/obj.h"
#include "arch/x86_64/hal/smp.h"
@@ -8,51 +9,34 @@
#include "lib/string.h"
#include "proc/init.h"
#include "jove.h"
+#include "proc/scheduler.h"
PAGEALIGN uint8_t s_init_iopb[0x2000];
PAGEALIGN char _init_pcb_bytes[0x1000] = { 0 };
-pcb_t *pcb_tree;
+
+int
+_pcb_new_arch(pcb_t *pcb)
+{
+ return 0;
+}
void
processing_setup(void (*process_main))
{
- pcb_t *init_pcb = (pcb_t*)&_init_pcb_bytes;
- pcb_tree = init_pcb;
-
- memset(s_init_iopb, 0xFF, 0x2000);
- uintptr_t ksp = ((uintptr_t)&_init_pcb_bytes) + 0xFF8;
-
- init_pcb->header.tree_node.get_key = (void*)pcb_getpid;
- init_pcb->header.tree_node.color = 1;
- init_pcb->header.rootdir = _rootdir_obj;
- init_pcb->header.pagedir = obj_release(objdir_getlocal(_rootdir_obj, ROOTDIR_PAGEDIR_I));
+ jove_owned_obj_t *init_pcb_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_PCB_I);
+ obj_settype(init_pcb_obj, JOVE_OBJ_PCB);
+ obj_setvalue(init_pcb_obj, phys_fromvirt((uintptr_t)&_init_pcb_bytes));
+
+ pcb_new(init_pcb_obj, sizeof(_init_pcb_bytes), _rootdir_obj);
- init_pcb->header.pid = 1;
- init_pcb->header.state = PCB_STATE_RUNNING;
-
- init_pcb->ksp = (void*)ksp;
-
- jove_owned_obj_t *iopb_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_IOPB_I);
+ jove_owned_obj_t *iopb_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_IOPB_I);
obj_settype(iopb_obj, JOVE_OBJ_IOPB);
obj_setvalue(iopb_obj, (uintptr_t)s_init_iopb);
- init_pcb->iopb = obj_release(iopb_obj);
- processor_t *proc = processor_current();
- proc->tss.rsp[0] = (uintptr_t)init_pcb->ksp;
- memcpy(proc->iopb, s_init_iopb, 0x2000);
-
- {
- jove_owned_obj_t *process_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_PCB_I);
- obj_settype(process_obj, JOVE_OBJ_PCB);
- obj_setvalue(process_obj, (uintptr_t)init_pcb);
+ memset(s_init_iopb, 0xFF, 0x2000);
+ pcb_t *init_pcb = obj_deref(init_pcb_obj);
- proc->pcb_obj = process_obj;
- proc->pcb = init_pcb;
- }
+ init_pcb->iopb = obj_release(iopb_obj);
- __asm__ volatile("\
- movq %0, %%rsp; \
- xorq %%rbp, %%rbp; \
- jmpq %1"::
- "r"(init_pcb->ksp), "r"(process_main));
+ scheduler_init(init_pcb_obj, process_main);
}
diff --git a/arch/x86_64/proc/process.h b/arch/x86_64/proc/process.h
index 6a0aa96..5004b49 100644
--- a/arch/x86_64/proc/process.h
+++ b/arch/x86_64/proc/process.h
@@ -2,19 +2,14 @@
#define _JOVE_x86_64_HAL_PROCESS_H 1
#include "proc/process.h"
-#include "arch/x86_64/x86_64.h"
#include "lib/rbtree.h"
typedef struct process_control_block
{
- struct pcb_expected_header header;
+ struct pcb_header header;
jove_obj_t *iopb;
-
- int killed;
- struct cpu_context context;
- void *ksp;
char kstack[];
} pcb_t;
diff --git a/arch/x86_64/proc/scheduler.c b/arch/x86_64/proc/scheduler.c
new file mode 100644
index 0000000..23e54af
--- /dev/null
+++ b/arch/x86_64/proc/scheduler.c
@@ -0,0 +1,20 @@
+#include "proc/scheduler.h"
+#include "arch/x86_64/hal/gdt.h"
+#include "process.h"
+#include "../hal/smp.h"
+#include <string.h>
+
+void
+_scheduler_switch_pcb_arch(pcb_t *target)
+{
+ processor_t *proc = processor_current();
+ proc->tss.rsp[0] = (uintptr_t)target->header.ksp;
+
+ if(target->iopb) {
+ proc->tss.iopb = sizeof(struct tss);
+ jove_owned_obj_t *iopb_obj = obj_take(target->iopb);
+ memcpy(proc->iopb, obj_deref(iopb_obj), sizeof(proc->iopb));
+ }else{
+ proc->tss.iopb = 0xff;
+ }
+}
diff --git a/arch/x86_64/proc/switch.s b/arch/x86_64/proc/switch.s
new file mode 100644
index 0000000..d571c66
--- /dev/null
+++ b/arch/x86_64/proc/switch.s
@@ -0,0 +1,9 @@
+.global scheduler_switch
+.type scheduler_switch @function
+
+scheduler_switch:
+ movq %rsp, (%rdi)
+ movq %rsi, %rsp
+ retq
+
+.size scheduler_switch, . - scheduler_switch
diff --git a/arch/x86_64/sys/syscall.c b/arch/x86_64/sys/syscall.c
index b584756..1e06e61 100644
--- a/arch/x86_64/sys/syscall.c
+++ b/arch/x86_64/sys/syscall.c
@@ -50,5 +50,5 @@ void _syscall_entry(void)
sysretq"
::
[pcb] "i"(offsetof(processor_t, pcb)),
- [ksp] "i"(offsetof(pcb_t, ksp)));
+ [ksp] "i"(offsetof(struct pcb_header, ksp)));
}
diff --git a/boot/initrd.c b/boot/initrd.c
index f9bf47e..84636c3 100644
--- a/boot/initrd.c
+++ b/boot/initrd.c
@@ -7,6 +7,7 @@
#include "lib/string.h"
#include "hal/obj.h"
#include "hal/memory.h"
+#include "sys/objdir.h"
extern uintptr_t _initrd_module;
@@ -71,7 +72,7 @@ void initrd_setup(void)
{
kprintf("Loading initrd from bootloader:\n");
{
- jove_owned_obj_t *initrd_objdir_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_INITRD_I);
+ jove_owned_obj_t *initrd_objdir_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_INITRD_I);
obj_settype(initrd_objdir_obj, JOVE_OBJ_OBJDIR);
obj_setvalue(initrd_objdir_obj, (uintmax_t)&s_initrd_objdir);
diff --git a/boot/limine/framebuffer.c b/boot/limine/framebuffer.c
index 87b124a..a7ee04c 100644
--- a/boot/limine/framebuffer.c
+++ b/boot/limine/framebuffer.c
@@ -3,6 +3,7 @@
#include "lib/printf.h"
#include "limine.h"
#include "proc/init.h"
+#include "sys/objdir.h"
#include "hal/framebuffer.h"
extern struct limine_framebuffer_response *_limine_framebuffers;
@@ -73,7 +74,7 @@ fb_init()
fb->address = fb_virt;
{
- jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_FRAMEBUFFER_I);
+ jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_FRAMEBUFFER_I);
obj_settype(fb_obj, JOVE_OBJ_FRAMEBUFFER);
obj_setvalue(fb_obj, (uintptr_t)fb);
obj_release(fb_obj);
diff --git a/boot/limine/memorymap.c b/boot/limine/memorymap.c
index e470e14..48f3f33 100644
--- a/boot/limine/memorymap.c
+++ b/boot/limine/memorymap.c
@@ -31,7 +31,7 @@ void
mem_setup_regions(void)
{
{
- jove_owned_obj_t *region_objdir_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_FREEMEMORY_I);
+ jove_owned_obj_t *region_objdir_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_FREEMEMORY_I);
obj_settype(region_objdir_obj, JOVE_OBJ_OBJDIR);
obj_setvalue(region_objdir_obj, (uintptr_t)&s_region_objdir);
obj_release(region_objdir_obj);
diff --git a/config.h b/config.h
index c732d01..ae33c41 100644
--- a/config.h
+++ b/config.h
@@ -11,6 +11,8 @@
#define FRAMEBUFFER_MAX_WIDTH 1920
#define FRAMEBUFFER_MAX_HEIGHT 1080
+#define PCB_MINSIZE 0x1000
+
#define INIT_STACK_PAGES 2
#define LOCKSTACK_MAX 64
diff --git a/hal/memory.h b/hal/memory.h
index 84cb7f2..1aec7e9 100644
--- a/hal/memory.h
+++ b/hal/memory.h
@@ -32,6 +32,7 @@ typedef struct jove_obj_untyped
} jove_untyped_t;
#define JOVE_UNTYPED_MINSIZE 0x10
+#define JOVE_SMHEM_MAXPAGES 0xFFF
void mem_setup_regions(void);
@@ -57,6 +58,8 @@ size_t untyped_size(jove_owned_obj_t *tgt);
int untyped_split(jove_owned_obj_t *tgt, jove_owned_obj_t *dst, size_t bytes);
int untyped_merge(jove_owned_obj_t *a, jove_owned_obj_t *b);
+int pagedir_new(jove_owned_obj_t *untyped_obj);
+
void pagedir_invlpg(virtaddr_t vptr);
virtaddr_t *pagedir_get_mapping(
@@ -82,5 +85,6 @@ int pagedir_unmap_untyped_table(
int pagedir_unmap_shmem_frame(
jove_owned_obj_t *tgt, uintptr_t vptr);
+int shmem_new(jove_owned_obj_t *untyped_obj);
#endif
diff --git a/hal/obj.h b/hal/obj.h
index 68f4bdc..5a48eb2 100644
--- a/hal/obj.h
+++ b/hal/obj.h
@@ -17,6 +17,7 @@ typedef struct jove_objdir
/*Locks the mutex of the kernel object provided. Returns the locked version. */
jove_owned_obj_t *obj_take(jove_obj_t *obj);
jove_owned_obj_t *obj_trytake(jove_obj_t *obj);
+jove_obj_t *obj_asunowned(jove_owned_obj_t *obj);
/*Unlocks the mutex of the kernel object provided. Returns the unlocked version. */
jove_obj_t *obj_release(jove_owned_obj_t *obj);
@@ -32,23 +33,4 @@ void obj_settype(jove_owned_obj_t *obj, uint8_t type);
uintmax_t obj_getvalue(jove_owned_obj_t *obj);
void obj_setvalue(jove_owned_obj_t *obj, uintmax_t value);
-/*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/hal/shmem.c b/hal/shmem.c
new file mode 100644
index 0000000..3785c2e
--- /dev/null
+++ b/hal/shmem.c
@@ -0,0 +1,20 @@
+#include "api/error.h"
+#include "hal/obj.h"
+#include "lib/string.h"
+#include "memory.h"
+
+int
+shmem_new(jove_owned_obj_t *untyped_obj)
+{
+ jove_untyped_t *untyped = obj_deref(untyped_obj);
+ if((uintptr_t)untyped & 0xFFF) return -EALIGN;
+ if(untyped->limit & 0xFFF) return -EBADSIZE;
+
+ size_t limit_pages = untyped->limit >> 12;
+ if(limit_pages > JOVE_SMHEM_MAXPAGES) return -ETOOBIG;
+
+ obj_setvalue(untyped_obj, (uintptr_t)untyped | limit_pages);
+ obj_settype(untyped_obj, JOVE_OBJ_SHMEMORY);
+ memset(untyped, 0, untyped->limit);
+ return 0;
+}
diff --git a/hal/smp.h b/hal/smp.h
index 6713665..8efe180 100644
--- a/hal/smp.h
+++ b/hal/smp.h
@@ -2,12 +2,15 @@
#define _JOVE_HAL_SMP_H 1
#include "obj.h"
+#include "proc/process.h"
typedef struct processor processor_t;
processor_t *processor_current(void);
jove_owned_obj_t *processor_objdir(processor_t *processor);
-jove_owned_obj_t *processor_pcb(processor_t *processor);
+jove_owned_obj_t *processor_getpcb(processor_t *processor);
+
+void processor_setpcb(processor_t *processor, jove_owned_obj_t *pcb_obj);
#endif
diff --git a/lib/rbtree.c b/lib/rbtree.c
index dc9caf1..a63df4d 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -1,4 +1,6 @@
#include "rbtree.h"
+#include "api/error.h"
+#include "errno.h"
static inline int
s_direction(const struct rbtree_node *node)
@@ -26,10 +28,27 @@ s_rotate(struct rbtree_node *sub, int dir)
return new_root;
}
-void
-rbtree_insert(struct rbtree_node *root, struct rbtree_node *node)
+struct rbtree_node *
+rbtree_search(struct rbtree_node *parent, intmax_t key)
{
- struct rbtree_node *parent = root;
+ errno = 0;
+ intmax_t parent_key = parent->get_key(parent);
+ if(parent_key == key) return parent;
+ int searchdir = parent_key < key;
+ if(parent->children[searchdir])
+ return rbtree_search(parent->children[searchdir], key);
+
+ errno = ENOTFOUND;
+ return 0;
+}
+
+struct rbtree_node *
+rbtree_insert(struct rbtree_node *parent, struct rbtree_node *node)
+{
+ node->color = 1;
+ if(parent == 0) return node;
+
+ //Seek to the correct b-tree leaf.
int direction;
while(1) {
direction = parent->get_key(parent) < node->get_key(node);
@@ -37,20 +56,19 @@ rbtree_insert(struct rbtree_node *root, struct rbtree_node *node)
parent = parent->children[direction];
}
- node->color = 1;
parent->children[direction] = node;
node->parent = parent;
//Rebalance the tree
do {
//Tree is already balanced, return
- if(parent->color == 0) return;
+ if(parent->color == 0) return parent;
struct rbtree_node *gparent = parent->parent;
//Parent is the root node, set parent to black.
if(!gparent) {
parent->color = 0;
- return;
+ return parent;
}
direction = s_direction(parent);
@@ -68,7 +86,7 @@ rbtree_insert(struct rbtree_node *root, struct rbtree_node *node)
s_rotate(gparent, 1-direction);
parent->color = 0;
gparent->color = 1;
- return;
+ return parent;
}
//Both the parent and uncle are red. Push up the red and iterate up.
@@ -79,6 +97,7 @@ rbtree_insert(struct rbtree_node *root, struct rbtree_node *node)
} while((parent = node->parent));
//Tree is balanced now.
+ return parent;
}
diff --git a/lib/rbtree.h b/lib/rbtree.h
index 22c44f8..1187e5c 100644
--- a/lib/rbtree.h
+++ b/lib/rbtree.h
@@ -12,6 +12,8 @@ struct rbtree_node
intmax_t (*get_key)(struct rbtree_node*);
};
-void rbtree_insert(struct rbtree_node *parent, struct rbtree_node *node);
+struct rbtree_node *rbtree_search(struct rbtree_node *parent, intmax_t key);
+
+struct rbtree_node *rbtree_insert(struct rbtree_node *parent, struct rbtree_node *node);
#endif
diff --git a/lib/virtterm.c b/lib/virtterm.c
index 8518530..ce759be 100644
--- a/lib/virtterm.c
+++ b/lib/virtterm.c
@@ -5,6 +5,7 @@
#include "proc/init.h"
#include "jove.h"
#include "hal/framebuffer.h"
+#include "sys/objdir.h"
#include "lib/printf.h"
#include "lib/psf.h"
#include "lib/string.h"
@@ -86,7 +87,7 @@ vt_init()
return;
}
- jove_owned_obj_t *initrd_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_INITRD_I);
+ jove_owned_obj_t *initrd_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_INITRD_I);
if(obj_gettype(initrd_obj) != JOVE_OBJ_OBJDIR) {
kprintf("Initrd is not present. VTT is disabled.\n");
obj_release(initrd_obj);
@@ -110,16 +111,16 @@ vt_init()
return;
}
- s_init_vtty.fb_obj = ROOTDIR_FRAMEBUFFER_I;
+ s_init_vtty.fb_obj = INIT_ROOTDIR_FRAMEBUFFER_I;
s_init_vtty.cursor_fg = 0x00FFFFFF;
{
- jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_FRAMEBUFFER_I);
+ jove_owned_obj_t *fb_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_FRAMEBUFFER_I);
s_init_vtty.width = fb_width(fb_obj) / 9;
s_init_vtty.height = fb_height(fb_obj) / s_font->char_height;
obj_release(fb_obj);
- jove_owned_obj_t *vt_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_VIRTTERM_I);
+ jove_owned_obj_t *vt_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_VIRTTERM_I);
obj_settype(vt_obj, JOVE_OBJ_VIRTTERM);
obj_setvalue(vt_obj, (uintmax_t)&s_init_vtty);
obj_release(vt_obj);
diff --git a/proc/init.c b/proc/init.c
index 4389187..10f8a01 100644
--- a/proc/init.c
+++ b/proc/init.c
@@ -1,4 +1,5 @@
#include "init.h"
+#include "sys/objdir.h"
#include "hal/memory.h"
#include "panic/panic.h"
@@ -7,7 +8,7 @@ objpath_part_t s_last_region = JOVE_OBJDIR_ENTRIES-1;
jove_owned_obj_t
init_pop_alloc(void)
{
- jove_owned_obj_t *freemem_dir = objdir_trygetlocal(_rootdir_obj, ROOTDIR_FREEMEMORY_I);
+ jove_owned_obj_t *freemem_dir = objdir_trygetlocal(_rootdir_obj, INIT_ROOTDIR_FREEMEMORY_I);
if(freemem_dir == 0) {
kpanic("Untyped directory is locked!\n");
}
diff --git a/proc/process.c b/proc/process.c
index e811cb6..137e35c 100644
--- a/proc/process.c
+++ b/proc/process.c
@@ -1,38 +1,86 @@
#include "process.h"
+#include "api/process.h"
#include "hal/smp.h"
+#include "sys/objdir.h"
+#include <string.h>
+
+struct rbtree_node *pcb_tree;
+pid_t __next_pid = 1;
+
+int
+pcb_new(jove_owned_obj_t *pcb_obj, size_t size, jove_owned_obj_t *rootdir_obj)
+{
+ struct pcb_header *pcb_header = obj_deref(pcb_obj);
+
+ memset(pcb_header, 0, size);
+
+ pcb_header->size = size;
+ pcb_header->pid = __next_pid++;
+ pcb_header->rootdir = obj_asunowned(rootdir_obj);
+
+ pcb_header->tree_node.get_key = (void*)pcb_getpid;
+ pcb_tree = rbtree_insert(pcb_tree, &pcb_header->tree_node);
+
+ pcb_header->state = PCB_STATE_EMBRYO;
+ pcb_header->ksp = (void*)pcb_obj + size - sizeof(uintmax_t);
+ return _pcb_new_arch((pcb_t*)pcb_header);
+}
+
+pcb_t *pcb_frompid(pid_t pid)
+{
+ return (pcb_t*)rbtree_search((struct rbtree_node*)pcb_tree, pid);
+}
jove_owned_obj_t*
process_current(void)
{
- return processor_pcb(((processor_t*)processor_current()));
+ return processor_getpcb(((processor_t*)processor_current()));
}
pid_t
pcb_getpid(pcb_t *pcb)
{
- return ((struct pcb_expected_header*)pcb)->pid;
+ return ((struct pcb_header*)pcb)->pid;
}
jove_obj_t*
pcb_getrootdir(pcb_t *pcb)
{
- return ((struct pcb_expected_header*)pcb)->rootdir;
+ return ((struct pcb_header*)pcb)->rootdir;
}
-jove_obj_t*
-pcb_getpagedir(pcb_t *pcb)
+jove_owned_obj_t*
+pcb_getpagedir(jove_owned_obj_t *rootdir_obj)
+{
+ return objdir_getlocal(rootdir_obj, PCB_ROOTDIR_PAGEDIR_I);
+}
+
+jove_owned_obj_t*
+pcb_getself(jove_owned_obj_t *rootdir_obj)
{
- return ((struct pcb_expected_header*)pcb)->pagedir;
+ return objdir_getlocal(rootdir_obj, PCB_ROOTDIR_SELF_I);
}
enum pcb_state
pcb_getstate(pcb_t *pcb)
{
- return ((struct pcb_expected_header*)pcb)->state;
+ return ((struct pcb_header*)pcb)->state;
}
intmax_t
pcb_getstatecode(pcb_t *pcb)
{
- return ((struct pcb_expected_header*)pcb)->state_code;
+ return ((struct pcb_header*)pcb)->state_code;
+}
+
+void*
+pcb_getksp(pcb_t *pcb)
+{
+ return ((struct pcb_header*)pcb)->ksp;
+}
+
+void**
+pcb_getksp_ref(pcb_t *pcb)
+{
+ return &((struct pcb_header*)pcb)->ksp;
}
diff --git a/proc/process.h b/proc/process.h
index ed40a4f..950f63e 100644
--- a/proc/process.h
+++ b/proc/process.h
@@ -5,49 +5,51 @@
#include "lib/rbtree.h"
#include "api/process.h"
-enum pcb_state
-{
- _PCB_STATE_INVALID = 0,
- PCB_STATE_DEAD,
- PCB_STATE_READY,
- PCB_STATE_RUNNING,
- PCB_STATE_WAITING,
- PCB_STATE_BLOCKED_MAIL
-};
-
struct pcb_mailbox
{
jove_obj_t *obj;
pid_t pid;
};
-struct pcb_expected_header
+struct pcb_header
{
struct rbtree_node tree_node;
- struct pcb_expected_header *sched_next;
+ struct pcb_header *sched_next;
+ size_t size;
pid_t pid;
jove_obj_t *rootdir;
- jove_obj_t *pagedir;
enum pcb_state state;
intmax_t state_code;
struct pcb_mailbox send, recv;
+
+ void *ksp;
};
typedef struct process_control_block pcb_t;
jove_owned_obj_t *process_current(void);
-void pcb_new(pcb_t *pcb);
+int pcb_new(jove_owned_obj_t *pcb_obj, size_t size, jove_owned_obj_t *rootdir_obj);
+int _pcb_new_arch(pcb_t *pcb);
+
+pcb_t *pcb_frompid(pid_t pid);
pid_t pcb_getpid(pcb_t *pcb);
jove_obj_t *pcb_getrootdir(pcb_t *pcb);
-jove_obj_t *pcb_getpagedir(pcb_t *pcb);
+jove_owned_obj_t *pcb_getpagedir(jove_owned_obj_t *rootdir_obj);
+jove_owned_obj_t *pcb_getself(jove_owned_obj_t *rootdir_obj);
+
enum pcb_state pcb_getstate(pcb_t *pcb);
intmax_t pcb_getstatecode(pcb_t *pcb);
-extern pcb_t *pcb_tree;
+void *pcb_getksp(pcb_t *pcb);
+void **pcb_getksp_ref(pcb_t *pcb);
+
+pcb_t *pcb_frompid(pid_t pid);
+
+extern struct rbtree_node *pcb_tree;
#endif
diff --git a/proc/scheduler.c b/proc/scheduler.c
index 852cfef..875bcc4 100644
--- a/proc/scheduler.c
+++ b/proc/scheduler.c
@@ -1,3 +1,55 @@
#include "scheduler.h"
+#include "api/error.h"
+#include "hal/smp.h"
+#include "sys/objdir.h"
+#include "proc/init.h"
+#include "proc/process.h"
+static struct pcb_header *s_ready_queue;
+static inline int
+s_scheduler_yield_pcb(processor_t *proc, pcb_t *current_pcb, pcb_t *target_pcb)
+{
+ jove_owned_obj_t *target_rootdir = obj_take(pcb_getrootdir(target_pcb));
+ jove_owned_obj_t *target_pcb_obj = pcb_getself(target_rootdir);
+
+ processor_setpcb(proc, target_pcb_obj);
+
+ obj_release(target_rootdir);
+ _scheduler_switch_pcb_arch(target_pcb);
+ scheduler_switch(pcb_getksp_ref(current_pcb), pcb_getksp(target_pcb));
+
+ return 0;
+}
+
+
+int scheduler_yield(pid_t target_pid)
+{
+ processor_t *proc = processor_current();
+ pcb_t *current_pcb = obj_deref(processor_getpcb(proc));
+ pcb_t *target_pcb = (pcb_t*)((struct pcb_header*)current_pcb)->sched_next;
+
+ if(target_pid != 0) {
+ pcb_t *target_pcb = pcb_frompid(target_pid);
+ }
+ if(target_pcb == 0) {
+ return -EBADPROC;
+ }
+
+ return s_scheduler_yield_pcb(proc, current_pcb, target_pcb);
+}
+
+void scheduler_init(jove_owned_obj_t *pcb_obj, void *process_main)
+{
+ struct pcb_header *pcb_header = obj_deref(pcb_obj);
+ pcb_header->state = PCB_STATE_RUNNING;
+ pcb_header->sched_next = pcb_header;
+
+ processor_t *proc = processor_current();
+ processor_setpcb(proc, pcb_obj);
+
+ __asm__("movq %0, %%rsp; \
+ xorq %%rbp, %%rbp; \
+ jmp %1"::
+ "m"(pcb_header->ksp), "r"(process_main));
+}
diff --git a/proc/scheduler.h b/proc/scheduler.h
index 6f1b6b2..0371e86 100644
--- a/proc/scheduler.h
+++ b/proc/scheduler.h
@@ -1,6 +1,14 @@
#ifndef _JOVE_PROC_SCHEDULER_H
#define _JOVE_PROC_SCHEDULER_H 1
+#include "process.h"
+
+void scheduler_init(jove_owned_obj_t *pcb_obj, void *process_main);
+
+void scheduler_switch(void *this_sp, void *other_sp);
+void _scheduler_switch_pcb_arch(pcb_t *target);
+
+int scheduler_yield(pid_t target);
#endif
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;
}