summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/syscall-invoke-mapping.c
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-08-17 14:16:55 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-08-17 14:16:55 -0400
commit7ee9347560768641096df68c545ac085a20233e4 (patch)
tree5b567f2e98cd9e6aeee33eeecd7fbf6f2fafdeab /arch/x86_64/syscall-invoke-mapping.c
parentf466364b8a3858e7b3f19258d142851cb4a7e6d6 (diff)
downloadjove-kernel-7ee9347560768641096df68c545ac085a20233e4.tar.gz
jove-kernel-7ee9347560768641096df68c545ac085a20233e4.tar.bz2
jove-kernel-7ee9347560768641096df68c545ac085a20233e4.zip
working usermode pager. fix usermode interrupts
Diffstat (limited to 'arch/x86_64/syscall-invoke-mapping.c')
-rw-r--r--arch/x86_64/syscall-invoke-mapping.c58
1 files changed, 41 insertions, 17 deletions
diff --git a/arch/x86_64/syscall-invoke-mapping.c b/arch/x86_64/syscall-invoke-mapping.c
index efecbdf..5b79239 100644
--- a/arch/x86_64/syscall-invoke-mapping.c
+++ b/arch/x86_64/syscall-invoke-mapping.c
@@ -4,6 +4,9 @@
#include <stddef.h>
#include "error.h"
#include "lock.h"
+#include "string.h"
+#include "memory.h"
+#include "print.h"
static int
s_handle_invoke_mapping_release(
@@ -13,6 +16,9 @@ s_handle_invoke_mapping_release(
size_t payload_at
)
{
+#ifdef DBG_SYSCALL
+ klogf("release mapping %p\n", target_entry);
+#endif
target_entry->data = 0;
target_entry->type = KO_NONE;
return 0;
@@ -29,25 +35,29 @@ s_handle_invoke_mapping_get(
pmli_t pmli;
SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t);
- if(pmli > 511) return -KE_OOB;
+ if(pmli > 511) return KE_OOB;
uint8_t level = target_entry->data & 3;
pmle_t *target_pml = (pmle_t*)vmem_phys_tovirt(target_entry->data & ~3ULL);
- if(level == 3 && pmli > 255) return -KE_OOB;
- if(level == 0) return -KE_BADOBJ;
-
+ if(level == 3 && pmli > 255) return KE_OOB;
+ if(level < 0) return KE_BADOBJ;
+
size_t dest_pathw;
objdir_entry_t *dest_entry;
SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, dest_pathw, dest_entry);
- if(dest_entry->type != KO_NONE) return -KE_FULL;
+
+ if(dest_entry->type != KO_NONE) return KE_FULL;
pmle_t pmle = target_pml[pmli];
- if(!pmle.p) return -KE_DNE;
+ if(!pmle.p) return KE_DNE;
*dest_entry = (objdir_entry_t) {
.type = KO_MEMORY_MAPPING,
.data = (((uintptr_t)target_pml[pmli].paddr) << 12ULL) | (level - 1)
};
+#ifdef DBG_SYSCALL
+ klogf("Get pml%i %p[%i] -> %p\n", level, target_pml, pmli, dest_entry->data & ~3ULL);
+#endif
return 0;
}
@@ -65,37 +75,47 @@ s_handle_invoke_mapping_map(
pmli_t pmli;
SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t);
- if(pmli > 511) return -KE_OOB;
- if(level == 3 && pmli > 255) return -KE_OOB;
+ if(pmli > 511) return KE_OOB;
+ if(level == 3 && pmli > 255) return KE_OOB;
+ if(level < 0) return KE_BADOBJ;
size_t untyped_pathw;
objdir_entry_t *untyped_entry;
SYSCALL_PAYLOAD_TAKEOBJ(payload, payload_at, untyped_pathw, untyped_entry);
- if(untyped_entry->type != KO_MEMORY_UNTYPED) return -KE_BADOBJ;
+ if(untyped_entry->type != KO_MEMORY_UNTYPED) return KE_BADOBJ;
mtx_acquire(&untyped_entry->lock);
if((untyped_entry->data & 0xFFF) != 0) {
mtx_release(&untyped_entry->lock);
- return -KE_ALIGN;
+ return KE_ALIGN;
}
- size_t *untyped_data = (size_t*)untyped_entry->data;
- size_t untyped_size = *untyped_data;
+
+ uintptr_t untyped_phys = untyped_entry->data;
+ size_t *untyped = ko_entry_data(untyped_entry);
+ size_t untyped_size = *untyped;
if(untyped_size != 0x1000) {
mtx_release(&untyped_entry->lock);
- return -KE_BADSIZE;
+ return KE_BADSIZE;
}
pmle_t pmle = target_pml[pmli];
if(pmle.p) {
mtx_release(&untyped_entry->lock);
- return -KE_OCCUPIED;
+ return KE_OCCUPIED;
}
- target_pml[pmli].value = vmem_ident_tophys((void*)untyped_entry->data) | PAGE_RW | PAGE_US | PAGE_PRESENT;
+ target_pml[pmli].value = untyped_phys | PAGE_RW | PAGE_US | PAGE_PRESENT;
+ if(level != 0) {
+ memset(untyped, 0, 0x1000);
+ }
untyped_entry->type = KO_MEMORY_MAPPING;
untyped_entry->data |= level - 1;
+#ifdef DBG_SYSCALL
+ klogf("map %p[%p] to pml%i %p[%i]\n", untyped_entry, untyped_phys, level, target_pml, pmli);
+#endif
+
mtx_release(&untyped_entry->lock);
return 0;
}
@@ -119,6 +139,10 @@ syscall_handle_invoke_mapping(
uint8_t funcid;
SYSCALL_PAYLOAD_TAKEL(payload, payload_at, funcid, uint8_t);
- if(funcid >= s_invoke_handles_count) return -KE_BADFUNC;
- return s_invoke_handles[funcid](root_dir, target, payload, payload_at);
+ if(funcid >= s_invoke_handles_count) return KE_BADFUNC;
+ int r = s_invoke_handles[funcid](root_dir, target, payload, payload_at);
+#ifdef DBG_SYSCALL
+ klogf("Call returns %i\n", r);
+#endif
+ return r;
}