From 858a52c06a4615bd58a6a906333f2ad707d41c0a Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Tue, 19 Aug 2025 15:04:04 -0400 Subject: usermode pager --- apps/init/arch/x86_64/paging.c | 109 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 apps/init/arch/x86_64/paging.c (limited to 'apps/init/arch/x86_64/paging.c') diff --git a/apps/init/arch/x86_64/paging.c b/apps/init/arch/x86_64/paging.c new file mode 100644 index 0000000..6c1c386 --- /dev/null +++ b/apps/init/arch/x86_64/paging.c @@ -0,0 +1,109 @@ +#include "../../memory.h" +#include "jove/object-dir.h" +#include "jove/jove.h" +#include +#include + +KernelObjectPageMap init_pagemap; +unsigned d_cache[3] = { -1, -1, -1 }; +uintptr_t vptr_cache = 0; + +KernelObjectUntyped work_page; + +#define PMLI_SHL(d) (((4 - d) * 9) + 3) +#define PMLI_DL(v, d) ((v >> PMLI_SHL(d)) % 512) + +uint64_t +pager_write_path(uintptr_t vptr, uint8_t depth) +{ + uint64_t r = 0; + if(depth >= 4) return -1; + + uint16_t *path = (uint16_t*)&r; + for(uint8_t i = 0; i < depth; i++) path[i] = PMLI_DL(vptr, i); + return r; +} + +bool +pager_depth_exists(uintptr_t vptr, uint8_t depth) +{ + uint64_t path = pager_write_path(vptr, depth); + if(path == -1) return false; + + return jove_pagemap_exists(&init_pagemap, depth, (uint16_t*)&path); +} +/* Places new page in work_page. */ +JoveError +pager_alloc_page_untyped(void) +{ + uint8_t lastmemb = jove_objdir_lastmemb(&untypedDirectory); + if(jove_errno) { + JoveError err = jove_errno; + jove_errno = EJOVE_OK; + return err; + } + + KernelObjectUntyped last_untyped; + _jove_alloc_untyped_inplace(&last_untyped, &untypedDirectory, lastmemb); + + if(jove_untyped_size(&last_untyped) == 0x1000) { + jove_objdir_move(&untypedDirectory, lastmemb, &__rootdir, work_page.typed.membi); + return EJOVE_OK; + } + + return jove_untyped_split_inplace(&last_untyped, 0x1000, &work_page); +} + +JoveError +pager_ensure_at_depth(uint8_t depth, uint16_t *path) +{ + int exists = jove_pagemap_exists(&init_pagemap, depth, path); + if(exists) { + return EJOVE_OK; + } + + JoveError pagealloc_err = pager_alloc_page_untyped(); + if(pagealloc_err) { + jove_kprintf("Failed to allocate page with error %i\n", pagealloc_err); + return pagealloc_err; + } + return jove_pagemap_map(&init_pagemap, depth, path, &work_page); +} + +#define PAGER_CACHE_ENSURE_DEPTH(path_seg, d) \ + if(path_seg[d] != d_cache[d]) { \ + JoveError d_err = pager_ensure_at_depth(d, path_seg); \ + if(d_err) return d_err; \ + d_cache[d] = path_seg[d]; \ + } + +JoveError +pager_ensure(uintptr_t vptr) +{ + uint64_t path = pager_write_path(vptr, 3); + if(path == -1) return EJOVE_BADARG; + + vptr &= ~0xFFFULL; + uint16_t *path_seg = (uint16_t*)&path; + jove_kprintf("%x:%x:%x:%x\n", path_seg[0], path_seg[1], path_seg[2], path_seg[3]); + + PAGER_CACHE_ENSURE_DEPTH(path_seg, 0); + PAGER_CACHE_ENSURE_DEPTH(path_seg, 1); + PAGER_CACHE_ENSURE_DEPTH(path_seg, 2); + if(vptr != vptr_cache) { + return pager_ensure_at_depth(3, path_seg); + } + return EJOVE_OK; +} + +void +pager_setup(void) +{ + _jove_alloc_objdir_inplace(&untypedDirectory, &__rootdir, INIT_OBJECT_UNTYPED_DIR); + _jove_alloc_pagemap_inplace(&init_pagemap, &__rootdir, INIT_OBJECT_PAGEMAP); + + size_t lastfree = jove_objdir_lastmemb(&__rootdir) + 1; + _jove_alloc_untyped_inplace(&work_page, &__rootdir, lastfree++); + + pager_ensure(0x00000000F0000000); +} -- cgit v1.2.1