summaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
authorJon Santmyer <jon@jonsantmyer.com>2025-08-10 15:40:19 -0400
committerJon Santmyer <jon@jonsantmyer.com>2025-08-10 15:40:19 -0400
commitc4f8ef91f18d854a4ede7a94e95b2eab898d6963 (patch)
treec2772c4f380a684b6fa347f03b13f9476bf9500c /arch/x86_64
parentb905869a35f062a4e5072f10bec3a2ba3db0e365 (diff)
downloadjove-kernel-c4f8ef91f18d854a4ede7a94e95b2eab898d6963.tar.gz
jove-kernel-c4f8ef91f18d854a4ede7a94e95b2eab898d6963.tar.bz2
jove-kernel-c4f8ef91f18d854a4ede7a94e95b2eab898d6963.zip
working usermode objdir iteration
Diffstat (limited to 'arch/x86_64')
-rw-r--r--arch/x86_64/lock.s19
-rw-r--r--arch/x86_64/memory.c16
-rw-r--r--arch/x86_64/page_directory.c11
-rw-r--r--arch/x86_64/processor.c12
-rw-r--r--arch/x86_64/sse.s46
-rw-r--r--arch/x86_64/syscall-invoke-mapping.c124
-rw-r--r--arch/x86_64/syscall.c32
-rw-r--r--arch/x86_64/untyped_retype_page.c13
-rw-r--r--arch/x86_64/usermode.c38
9 files changed, 265 insertions, 46 deletions
diff --git a/arch/x86_64/lock.s b/arch/x86_64/lock.s
new file mode 100644
index 0000000..b63f078
--- /dev/null
+++ b/arch/x86_64/lock.s
@@ -0,0 +1,19 @@
+.global _mtx_acquire
+.type _mtx_acquire @function
+_mtx_acquire:
+ lock btsw $0, (%rdi)
+ jc .spin
+ ret
+.spin:
+ pause
+ testb $1, (%rdi)
+ jnz .spin
+ jmp _mtx_acquire
+.size _mtx_acquire, . - _mtx_acquire
+
+.global _mtx_release
+.type _mtx_release @function
+_mtx_release:
+ movb $0, (%rdi)
+ ret
+.size _mtx_release, . - _mtx_release
diff --git a/arch/x86_64/memory.c b/arch/x86_64/memory.c
new file mode 100644
index 0000000..b32d4e7
--- /dev/null
+++ b/arch/x86_64/memory.c
@@ -0,0 +1,16 @@
+#include "memory.h"
+#include "arch/x86_64/page.h"
+#include <stdint.h>
+
+void*
+ko_entry_data(objdir_entry_t *entry)
+{
+ if((intmax_t)entry->data < 0) return (void*)entry->data;
+ return vmem_phys_tovirt(entry->data);
+}
+
+uintptr_t
+ko_data_toentry(uintptr_t vptr)
+{
+ return vmem_ident_tophys((void*)vptr);
+}
diff --git a/arch/x86_64/page_directory.c b/arch/x86_64/page_directory.c
index 0506703..bcc71cf 100644
--- a/arch/x86_64/page_directory.c
+++ b/arch/x86_64/page_directory.c
@@ -6,6 +6,7 @@
#include "object.h"
#include "string.h"
#include "jove.h"
+#include <stdint.h>
physptr_t s_kpbase(void);
@@ -45,6 +46,12 @@ pmle_get_page(pmle_t entry)
return vmem_phys_tovirt(pptr);
}
+uint8_t
+pmle_level(pmle_t entry)
+{
+ return entry.osflg;
+}
+
__attribute__((aligned(0x1000))) pmle_t s_kernel_pml4[512]; // Page L4
__attribute__((aligned(0x1000))) pmle_t s_kernel_pml3[512]; // Page L3
__attribute__((aligned(0x1000))) pmle_t s_kernel_pml2[512]; // Page directory
@@ -107,8 +114,8 @@ vmem_setup(void)
//Add page mapping object to init directory.
uint8_t pm_i = _initDirectory.self.data++;
_initDirectory.entries[pm_i] = (objdir_entry_t) {
- .type = KO_MEMORY_MAPPING_PAGE,
- .data = kernel_pml4_base
+ .type = KO_MEMORY_MAPPING,
+ .data = kernel_pml4_base | 3
};
_initData.pm_object = pm_i;
}
diff --git a/arch/x86_64/processor.c b/arch/x86_64/processor.c
index b39ba63..666eb3d 100644
--- a/arch/x86_64/processor.c
+++ b/arch/x86_64/processor.c
@@ -88,9 +88,21 @@ processor_setup(void *_processor)
(uint32_t)((uintptr_t)_processor >> 32));
}
+void enable_fpu(void);
+void enable_sse(void);
+void enable_avx(void);
+
void
bsp_setup(void)
{
+#ifdef ENABLE_SSE
+ enable_fpu();
+ enable_sse();
+#endif
+#ifdef ENABLE_AVX
+ enable_avx();
+#endif
+
uint64_t pd_i = _initDirectory.self.data++;
_initDirectory.entries[pd_i] = (objdir_entry_t) {
diff --git a/arch/x86_64/sse.s b/arch/x86_64/sse.s
new file mode 100644
index 0000000..8065188
--- /dev/null
+++ b/arch/x86_64/sse.s
@@ -0,0 +1,46 @@
+.global enable_fpu
+.type enable_fpu @function
+enable_fpu:
+ fninit
+ fldcw [fcw_init]
+ ret
+.size enable_fpu, . - enable_fpu
+
+.global enable_sse
+.type enable_sse @function
+enable_sse:
+ movq %cr0, %rax
+ //Disable coprocessor emulation
+ and $0xFFFB, %ax
+ //Set coprocessor monitoring
+ or $0x22, %ax
+ //Save cr0
+ movq %rax, %cr0
+ movq %cr4, %rax
+ //Set CR4.OSFXR and CR4.OSXMMEXCEPT
+ or $3 << 9, %ax
+ movq %rax, %cr4
+ ret
+.size enable_sse, . - enable_sse
+
+.global enable_avx
+.type enable_avx, @function
+enable_avx:
+ pushq %rax
+ pushq %rcx
+ pushq %rdx
+
+ xorq %rcx, %rcx
+ xgetbv
+ or $7, %eax
+ xsetbv
+
+ popq %rdx
+ popq %rcx
+ popq %rax
+ ret
+.size enable_avx, . - enable_avx
+
+.data
+fcw_init:
+ .word 0x037F
diff --git a/arch/x86_64/syscall-invoke-mapping.c b/arch/x86_64/syscall-invoke-mapping.c
new file mode 100644
index 0000000..efecbdf
--- /dev/null
+++ b/arch/x86_64/syscall-invoke-mapping.c
@@ -0,0 +1,124 @@
+#include "syscall/handles.h"
+#include "arch/x86_64/syscall.h"
+#include "arch/x86_64/page.h"
+#include <stddef.h>
+#include "error.h"
+#include "lock.h"
+
+static int
+s_handle_invoke_mapping_release(
+ objdir_t *root_dir,
+ objdir_entry_t *target_entry,
+ uint8_t *payload,
+ size_t payload_at
+ )
+{
+ target_entry->data = 0;
+ target_entry->type = KO_NONE;
+ return 0;
+}
+
+static int
+s_handle_invoke_mapping_get(
+ objdir_t *root_dir,
+ objdir_entry_t *target_entry,
+ uint8_t *payload,
+ size_t payload_at
+ )
+{
+ pmli_t pmli;
+ SYSCALL_PAYLOAD_TAKEL(payload, payload_at, pmli, pmli_t);
+
+ 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;
+
+ 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;
+
+ pmle_t pmle = target_pml[pmli];
+ 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)
+ };
+ return 0;
+}
+
+static int
+s_handle_invoke_mapping_map(
+ objdir_t *root_dir,
+ objdir_entry_t *target_entry,
+ uint8_t *payload,
+ size_t payload_at
+ )
+{
+ uint8_t level = target_entry->data & 3;
+ pmle_t *target_pml = (pmle_t*)vmem_phys_tovirt(target_entry->data & ~3ULL);
+
+ 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;
+
+ 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;
+ mtx_acquire(&untyped_entry->lock);
+
+ if((untyped_entry->data & 0xFFF) != 0) {
+ mtx_release(&untyped_entry->lock);
+ return -KE_ALIGN;
+ }
+ size_t *untyped_data = (size_t*)untyped_entry->data;
+ size_t untyped_size = *untyped_data;
+ if(untyped_size != 0x1000) {
+ mtx_release(&untyped_entry->lock);
+ return -KE_BADSIZE;
+ }
+
+ pmle_t pmle = target_pml[pmli];
+ if(pmle.p) {
+ mtx_release(&untyped_entry->lock);
+ return -KE_OCCUPIED;
+ }
+
+ target_pml[pmli].value = vmem_ident_tophys((void*)untyped_entry->data) | PAGE_RW | PAGE_US | PAGE_PRESENT;
+ untyped_entry->type = KO_MEMORY_MAPPING;
+ untyped_entry->data |= level - 1;
+
+ mtx_release(&untyped_entry->lock);
+ return 0;
+}
+
+static int (*s_invoke_handles[])(objdir_t*, objdir_entry_t*, uint8_t*, size_t) = {
+ [INVOKE_MAPPING_RELEASE] = s_handle_invoke_mapping_release,
+ [INVOKE_MAPPING_GET] = s_handle_invoke_mapping_get,
+ [INVOKE_MAPPING_MAP] = s_handle_invoke_mapping_map,
+};
+
+static size_t s_invoke_handles_count = sizeof(s_invoke_handles) / sizeof(void*);
+
+int
+syscall_handle_invoke_mapping(
+ objdir_t *root_dir,
+ objdir_entry_t *target,
+ uint8_t *payload,
+ size_t payload_at
+ )
+{
+ 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);
+}
diff --git a/arch/x86_64/syscall.c b/arch/x86_64/syscall.c
index a563525..5582336 100644
--- a/arch/x86_64/syscall.c
+++ b/arch/x86_64/syscall.c
@@ -1,6 +1,36 @@
#include "arch/x86_64/processor.h"
+#include "syscall/handles.h"
+#include "print.h"
+#include "lock.h"
+#include "error.h"
#include <stddef.h>
-
+
+static inline int
+s_invoke_release(
+ objdir_t *root_dir,
+ objdir_entry_t *target,
+ uint8_t *payload,
+ size_t payload_at,
+ int (*invoke)(objdir_t*, objdir_entry_t*, uint8_t*, size_t))
+{
+ int e = invoke(root_dir, target, payload, payload_at);
+ mtx_release(&target->lock);
+ return e;
+}
+
+int
+_syscall_handler_arch(objdir_t *root_dir, objdir_entry_t *target, uint8_t *payload, size_t payload_at)
+{
+ switch(target->type) {
+ case KO_MEMORY_MAPPING:
+ return s_invoke_release(root_dir, target, payload, payload_at, syscall_handle_invoke_mapping);
+ default:
+ klogf("Missing implementation of invoke for type %i\n", target->type);
+ mtx_release(&target->lock);
+ return -KE_BADTYPE;
+ }
+}
+
__attribute__((naked))
void _syscall_entry(void)
{
diff --git a/arch/x86_64/untyped_retype_page.c b/arch/x86_64/untyped_retype_page.c
index 216d88d..32afe2c 100644
--- a/arch/x86_64/untyped_retype_page.c
+++ b/arch/x86_64/untyped_retype_page.c
@@ -36,16 +36,3 @@ int untyped_retype_page(objdir_entry_t *untyped_entry, void **dest)
#endif
return r;
}
-
-int
-untyped_retype_kernel_stack(objdir_entry_t *untyped_entry, objdir_entry_t *dest_entry)
-{
- int r = s_untyped_retype(untyped_entry, KERNEL_STACK_SIZE, 1, (void**)(&dest_entry->data));
- if(r != 0) return r;
-
- dest_entry->type = KO_KERNEL_STACK;
- #ifdef DBG_MEM
- klogf("Untyped block %p retyped to kernel stack at %p\n", untyped_entry->data, dest_entry->data);
- #endif
- return r;
-}
diff --git a/arch/x86_64/usermode.c b/arch/x86_64/usermode.c
index 9ce5ed3..66a641c 100644
--- a/arch/x86_64/usermode.c
+++ b/arch/x86_64/usermode.c
@@ -1,12 +1,10 @@
#include "arch/x86_64/object.h"
#include "object.h"
-#include "memory.h"
#include "bootargs.h"
#include "device/initrd.h"
#include "object.h"
#include "panic.h"
#include "string.h"
-#include "print.h"
#include "device/processor.h"
#include "arch/x86_64/page.h"
@@ -28,23 +26,6 @@ s_new_mapping(objdir_t *untyped_dir)
return 0;
}
-static uintptr_t
-s_new_kstack(objdir_t *untyped_dir, objdir_entry_t *dest_entry)
-{
- objdir_entry_t *untyped_entry = NULL;
- for(int i = 1; i < OBJECT_DIRECTORY_MAX_ENTRIES; i++) {
- untyped_entry = &untyped_dir->entries[i];
- if(untyped_entry->type != KO_MEMORY_UNTYPED) continue;
-
- int err = untyped_retype_kernel_stack(untyped_entry, dest_entry);
- if(err != 0) continue;
-
- uintptr_t ptr = dest_entry->data;
- return (uintptr_t)vmem_phys_tovirt(ptr);
- }
- return 0;
-}
-
static pmle_t*
s_ensure_mapping_layer(pmle_t *pml, objdir_t *untyped_dir, uintptr_t addr, uint8_t layer)
{
@@ -60,13 +41,14 @@ s_ensure_mapping_layer(pmle_t *pml, objdir_t *untyped_dir, uintptr_t addr, uint8
.p = 1,
.rw = 1,
.us = 1,
+ .osflg = (layer - 1) & 3,
.paddr = table_phys >> 12
};
__asm__ volatile("invlpg (%0)":: "r"(table_phys));
return vmem_phys_tovirt(table_phys);
}
-static void
+static uintptr_t
s_map_page(pmle_t *pml4, objdir_t *untyped_dir, uintptr_t addr)
{
pmle_t *pml3 = s_ensure_mapping_layer(pml4, untyped_dir, addr, 4);
@@ -82,9 +64,11 @@ s_map_page(pmle_t *pml4, objdir_t *untyped_dir, uintptr_t addr)
.p = 1,
.rw = 1,
.us = 1,
+ .osflg = 0,
.paddr = pptr >> 12
};
__asm__ volatile("invlpg (%0)":: "r"(addr));
+ return pptr;
}
__attribute__((noreturn))
@@ -114,11 +98,9 @@ init_load(void)
}
size_t tcb_diri = _initDirectory.self.data++;
- size_t kstack_diri = _initDirectory.self.data++;
size_t message_diri = _initDirectory.self.data++;
_initData.tcb_object = tcb_diri;
- _initData.kernel_stack_object = kstack_diri;
_initData.message_object = message_diri;
_initDirectory.entries[tcb_diri] = (objdir_entry_t) {
@@ -130,7 +112,7 @@ init_load(void)
objdir_t *untyped_dir = (objdir_t*)_initDirectory.entries[untyped_diri].data;
size_t pml4_diri = _initData.pm_object;
- pmle_t *pml4 = vmem_phys_tovirt(_initDirectory.entries[pml4_diri].data);
+ pmle_t *pml4 = vmem_phys_tovirt(_initDirectory.entries[pml4_diri].data & ~3ULL);
//Reserve and map pages for init binary
size_t init_size = initrd_file_size(init_header);
@@ -150,11 +132,7 @@ init_load(void)
uintptr_t sp = stack_base + 0xFF0;
//Create a kernel stack for the init TCB
- uintptr_t ksp_base = (uintptr_t)s_new_kstack(untyped_dir, &_initDirectory.entries[kstack_diri]);
- _initDirectory.entries[kstack_diri] = (objdir_entry_t) {
- .type = KO_KERNEL_STACK,
- .data = ksp_base
- };
+ uintptr_t ksp_base = (uintptr_t)s_init_tcb.kstack;
s_init_tcb.ksp = ksp_base + 0xFF0;
processor_t *proc = (processor_t*)processor_current();
@@ -164,10 +142,10 @@ init_load(void)
uintptr_t message_base = init_base + (init_pages << 12);
message_base += ((~(message_base & 0xFFF)) & 0xFFF) + 1;
- s_map_page(pml4, untyped_dir, message_base);
+ uintptr_t message_phys = s_map_page(pml4, untyped_dir, message_base);
_initDirectory.entries[message_diri] = (objdir_entry_t) {
.type = KO_MESSAGE,
- .data = message_base
+ .data = (uintptr_t)vmem_phys_tovirt(message_phys)
};
_initData.message_object_address = message_base;