diff options
| author | Jon Santmyer <jon@jonsantmyer.com> | 2026-10-09 10:24:41 -0400 |
|---|---|---|
| committer | Jon Santmyer <jon@jonsantmyer.com> | 2026-10-09 10:24:41 -0400 |
| commit | cc23ea5a4b38807e79aceb23e6f43e965926618f (patch) | |
| tree | 90142bb44186f4dad7bbd82d3d53655b835c822b | |
| parent | 434ddcd907832b1febc7d70e4faa52109c7eb3bd (diff) | |
| download | jove-kernel-cc23ea5a4b38807e79aceb23e6f43e965926618f.tar.gz jove-kernel-cc23ea5a4b38807e79aceb23e6f43e965926618f.tar.bz2 jove-kernel-cc23ea5a4b38807e79aceb23e6f43e965926618f.zip | |
add basic scheduler logic. rename init rootdir indexes
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 @@ -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); @@ -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 @@ -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; +} @@ -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 @@ -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; } |
