From 6da70f16c584ee897a4ac4f51d016a615c84042b Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Fri, 18 Sep 2026 15:46:18 -0400 Subject: cleanup for real hw attempt --- Makefile | 2 - api/error.h | 2 + api/init.h | 7 +- api/obj.h | 2 +- api/syscall.h | 31 +++++++ arch/x86_64/boot/limine/framebuffer.c | 49 +++++------ arch/x86_64/hal/paging.c | 158 ++++++++++++++++++++++++++++------ arch/x86_64/hal/paging.h | 4 + arch/x86_64/hal/serial_com.c | 2 +- arch/x86_64/hal/smp.c | 14 +-- arch/x86_64/hal/uacpi.c | 15 ---- arch/x86_64/main.c | 6 +- arch/x86_64/sys/init.c | 91 ++++++++------------ boot/limine/framebuffer.c | 2 + boot/limine/memorymap.c | 21 ++++- boot/limine/start.c | 6 +- boot/limine/uacpi.c | 10 --- hal/memory.h | 10 ++- hal/uacpi.c | 46 ---------- hal/uacpi.h | 6 -- sys/syscall.c | 16 ++-- sys/syscall.h | 6 +- sys/syscall_pagedir.c | 81 ++++++++++++++++- sys/syscall_untyped.c | 2 +- uacpi | 1 - uacpi.mk | 20 ----- 26 files changed, 370 insertions(+), 240 deletions(-) delete mode 100644 arch/x86_64/hal/uacpi.c delete mode 100644 boot/limine/uacpi.c delete mode 100644 hal/uacpi.c delete mode 100644 hal/uacpi.h delete mode 160000 uacpi delete mode 100644 uacpi.mk diff --git a/Makefile b/Makefile index 237843f..99f625d 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,6 @@ SFILES += $(foreach dir, $(CDIRS), $(wildcard arch/$(TARGET_MACHINE)/$(dir)/*.s) OBJFILES := $(patsubst %.c,%.o,$(CFILES)) OBJFILES += $(patsubst %.s,%.o,$(SFILES)) -OBJFILES += uacpi.a DEPFILES := $(patsubst %.c,%.d,$(CFILES)) CLEAN_DEPENDS = @@ -37,7 +36,6 @@ $(INCDIR): $(BIN): ${OBJFILES} $(LD) $(LDFLAGS) ${OBJFILES} -o $(BIN) -include uacpi.mk -include ${DEPFILES} .PHONY: clean diff --git a/api/error.h b/api/error.h index 229c6c8..5e0e936 100644 --- a/api/error.h +++ b/api/error.h @@ -13,5 +13,7 @@ #define EALIGN 10 #define EEXIST 11 #define EBUSY 12 +#define EEMPTY 13 +#define EFULL 14 #endif diff --git a/api/init.h b/api/init.h index d23327f..ef538b4 100644 --- a/api/init.h +++ b/api/init.h @@ -6,14 +6,19 @@ enum { ROOTDIR_PROCESSORS_I, ROOTDIR_PAGEDIR_I, ROOTDIR_UNTYPED_I, + ROOTDIR_HWMEMORY_I, ROOTDIR_PCB_I, ROOTDIR_IOPB_I, - ROOTDIR_ACPI_I, ROOTDIR_INTERRUPTS_I, ROOTDIR_INITRD_I, ROOTDIR_MESSAGE_I, }; +struct init_payload +{ + void *rsdp; +}; + #define ROOTDIR_SERIAL_COM_I 0x80 #define ROOTDIR_FRAMEBUFFER_I 0x81 #define ROOTDIR_VIRTTERM_I 0x82 diff --git a/api/obj.h b/api/obj.h index 10f7b65..04513c1 100644 --- a/api/obj.h +++ b/api/obj.h @@ -10,7 +10,7 @@ enum JOVE_OBJ_OBJDIR, JOVE_OBJ_PAGEDIR, JOVE_OBJ_PROCESSOR, - JOVE_OBJ_ACPI_TABLE, + JOVE_OBJ_HWMEMORY, JOVE_OBJ_INT_HANDLE, JOVE_OBJ_PROCESS, JOVE_OBJ_INITRD_FILE, diff --git a/api/syscall.h b/api/syscall.h index 8c35270..4bb2eb2 100644 --- a/api/syscall.h +++ b/api/syscall.h @@ -115,6 +115,37 @@ struct syscall_pagedir_map objpath_part_t untyped_path[]; }; +/**If a page frame is present at the virtual address, the kernel will: + * mark the page frame as not present. + * untype the page frame and move it to the none path. + * return 0. + * If a page frame is not present at the virtual address, the kernel will return EEMPTY. + * Follows the rules defined by struct syscall_pagedir_unmap + * */ +#define SYSCALL_PAGEDIR_UNMAP_FRAME 2 + +/**If a page table is present at the virtual address, one of two things will happen: + * If the page table has present entries, the kernel will return EBUSY. + * Otherwise, the kernel will: + * mark the page table as not present. + * untype the page frame and move it to the none path. + * return 0. + * If a page table is not present at the virtual address, the kernel will return EEMPTY. + * Follows the rules defined by the struct syscall_pagedir_unmap + * */ +#define SYSCALL_PAGEDIR_UNMAP_TABLE 3 + +/**If the virtual address is above JOVE_USER_MEMORY_LIMIT, the kernel will return EBADARG. + * If none_pathlen exceeds the length of the message, the kernel will return ETOOBIG. + * If none_path does not point to a JOVE_OBJ_NONE object, the kernel will return EBADOBJ. + * */ +struct syscall_pagedir_unmap +{ + uintptr_t virtual_address; + uint16_t none_pathlen; + objpath_part_t none_path[]; +}; + #define SYSCALL_VTT_WRITE 0 #endif diff --git a/arch/x86_64/boot/limine/framebuffer.c b/arch/x86_64/boot/limine/framebuffer.c index 85c3f43..637a7fc 100644 --- a/arch/x86_64/boot/limine/framebuffer.c +++ b/arch/x86_64/boot/limine/framebuffer.c @@ -14,47 +14,38 @@ #define FRAMEBUFFER_MAX_HUGEPAGES ((FRAMEBUFFER_MAX_PAGES + 511) / 512) #define FRAMEBUFFER_MAX_GIANTPAGES ((FRAMEBUFFER_MAX_HUGEPAGES + 511) / 512) -PAGEALIGN static page_t fb_pml2[FRAMEBUFFER_MAX_GIANTPAGES][512]; -PAGEALIGN static page_t fb_pml1[FRAMEBUFFER_MAX_HUGEPAGES][512]; +PAGEALIGN static page_t fb_pages[FRAMEBUFFER_MAX_GIANTPAGES + FRAMEBUFFER_MAX_HUGEPAGES][512]; -extern page_t _kernel_pml3[512]; +extern page_t _kernel_pml4[512]; void* fb_remap(uintptr_t fb_address, size_t fb_bytes) { - memset(fb_pml2, 0, 0x1000 * FRAMEBUFFER_MAX_GIANTPAGES); - memset(fb_pml1, 0, 0x1000 * FRAMEBUFFER_MAX_HUGEPAGES); - fb_address &= ~IDENT_VIRT_BASE; - size_t fb_pages = (fb_bytes + 4095) >> 12; - size_t fb_hugepages = (fb_pages + 511) >> 9; - size_t fb_giantpages = (fb_hugepages + 511) >> 9; + size_t fb_numpages = (fb_bytes + 4095) >> 12; - if(fb_pages > FRAMEBUFFER_MAX_PAGES) { + if(fb_numpages > FRAMEBUFFER_MAX_PAGES) { kprintf("Framebuffer is too big! Please recompile the kernel with a bigger framebuffer allowance!"); return NULL; } - for(size_t pml2 = 0; pml2 < fb_giantpages; pml2++) { - uintptr_t fb_pml2_pptr = KPTR_TOPHYS(&fb_pml2[pml2]); - _kernel_pml3[pml2].value = fb_pml2_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE; - } - - for(size_t pml1 = 0; pml1 < fb_hugepages; pml1++) { - size_t pml2 = pml1 >> 9; - size_t pml1_mod = pml1 % 512; - uintptr_t pml1_pptr = KPTR_TOPHYS(&fb_pml1[pml1]); - fb_pml2[pml2][pml1_mod].value = pml1_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE; - } - - for(size_t pml0 = 0; pml0 < fb_pages; pml0++) { - size_t pml1 = pml0 >> 9; - size_t pml0_mod = pml0 % 512; - uintptr_t pml0_pptr = fb_address + (pml0 << 12); - fb_pml1[pml1][pml0_mod].value = pml0_pptr | PAGE_PRESENT | PAGE_GLOBAL | PAGE_WRITEABLE | PAGE_WRITETHROUGH | PAGE_XD; + uintptr_t vptr = IDENT_VIRT_BASE | (511ULL << PMLI_SHL(3)); + size_t last_table = 0; + for(size_t page = 0; page < fb_numpages; page++) { + uintptr_t frame = fb_address + (page << 12); + uintptr_t frame_virt = vptr + (page << 12); + + int tblres = 0; + do { + uintptr_t tbl_frame = KPTR_TOPHYS(&fb_pages[last_table++]); + tblres = pagedir_map_table(_kernel_pml4, tbl_frame, frame_virt); + if(tblres == EHASMAP) last_table--; + } while(tblres == 0); + + pagedir_map_frame(_kernel_pml4, frame, frame_virt, + PAGE_GLOBAL | PAGE_WRITEABLE | PAGE_XD); } - uintptr_t fb_virt = IDENT_VIRT_BASE | (511ULL << PMLI_SHL(3)); - return (void*)fb_virt; + return (void*)vptr; } diff --git a/arch/x86_64/hal/paging.c b/arch/x86_64/hal/paging.c index 7b45005..47c79f3 100644 --- a/arch/x86_64/hal/paging.c +++ b/arch/x86_64/hal/paging.c @@ -1,5 +1,6 @@ #include "paging.h" #include "arch/x86_64/x86_64.h" +#include "hal/memory.h" #include "jove.h" #include "init.h" #include "config.h" @@ -73,45 +74,91 @@ s_int_handle_pf_early(struct int_stackframe *frame) hcf(); } -int pagedir_map_frame( - jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, - uintptr_t vptr, struct syscall_pagedir_flags flg) +static page_t* +s_pagedir_get_pml1(page_t *pml4, uintptr_t vptr) { - page_t *pml4 = obj_deref(tgt); - uintptr_t frame = obj_getvalue(untyped_obj); - + errno = 0; size_t pml4i = PML4I(vptr); - if(!pml4[pml4i].p) return ENOMAP; + if(!pml4[pml4i].p) { + errno = ENOMAP; + return 0; + } page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].paddr << 12) | IDENT_VIRT_BASE); size_t pml3i = PML3I(vptr); - if(!pml3[pml3i].p) return ENOMAP; + if(!pml3[pml3i].p) { + errno = ENOMAP; + return 0; + } page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].paddr << 12) | IDENT_VIRT_BASE); size_t pml2i = PML2I(vptr); - if(!pml2[pml2i].p) return ENOMAP; + if(!pml2[pml2i].p) { + errno = ENOMAP; + return 0; + } + + return (page_t*)(((uintptr_t)pml2[pml2i].paddr << 12) | IDENT_VIRT_BASE); +} + +int pagedir_map_frame(page_t *pml4, + uintptr_t pptr, uintptr_t vptr, + uintmax_t flg) +{ + page_t *pml1 = s_pagedir_get_pml1(pml4, vptr); + if(!pml1) + return errno; - page_t *pml1 = (page_t*)(((uintptr_t)pml2[pml2i].paddr << 12) | IDENT_VIRT_BASE); size_t pml1i = PML1I(vptr); if(pml1[pml1i].p) return EEXIST; - pml1[pml1i].value = frame | - PAGE_PRESENT | - PAGE_USER | - (flg.writeable ? PAGE_WRITETHROUGH : 0) | - (flg.executable ? 0 : PAGE_XD); + pml1[pml1i].value = pptr | PAGE_PRESENT | flg; + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); return 0; } -int pagedir_map_table( +int pagedir_map_untyped_frame( jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, uintptr_t vptr, struct syscall_pagedir_flags flg) { - page_t *target_table = NULL; page_t *pml4 = obj_deref(tgt); uintptr_t frame = obj_getvalue(untyped_obj); - void *frame_ident = obj_deref(untyped_obj); + return pagedir_map_frame(pml4, frame, vptr, + (flg.writeable ? PAGE_WRITEABLE : 0) | + (flg.executable ? PAGE_XD : 0)); +} + +int pagedir_unmap_untyped_frame( + jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr) +{ + page_t *pml4 = obj_deref(tgt); + + size_t pml4i = PML4I(vptr); + if(!pml4[pml4i].p) return ENOMAP; + + page_t *pml1 = s_pagedir_get_pml1(pml4, vptr); + size_t pml1i = PML1I(vptr); + if(!pml1[pml1i].p) return ENOMAP; + + uintptr_t untyped_pptr = (pml1[pml1i].paddr << 12); + + obj_settype(dst, JOVE_OBJ_UNTYPED); + obj_setvalue(dst, untyped_pptr); + + jove_untyped_t *untyped_data = obj_deref(dst); + untyped_data->limit = 0x1000; + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + + return 0; +} + +int pagedir_map_table(page_t *pml4, + uintptr_t pptr, uintptr_t vptr) +{ + page_t *target_table = NULL; + + void *frame_ident = (void*)(pptr | IDENT_VIRT_BASE); memset(frame_ident, 0, 0x1000); size_t pml4i = PML4I(vptr); @@ -136,14 +183,77 @@ int pagedir_map_table( return EHASMAP; map_table: - target_table->value = frame | + target_table->value = pptr | PAGE_PRESENT | - PAGE_USER | - (flg.writeable ? PAGE_WRITETHROUGH : 0) | - (flg.executable ? 0 : PAGE_XD); + (pptr > IDENT_VIRT_BASE ? 0 : PAGE_USER) | + PAGE_WRITEABLE; + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); return 0; } +int pagedir_map_untyped_table( + jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, + uintptr_t vptr, struct syscall_pagedir_flags flg) +{ + page_t *pml4 = obj_deref(tgt); + uintptr_t frame = obj_getvalue(untyped_obj); + + return pagedir_map_table(pml4, frame, vptr); +} + +int pagedir_unmap_untyped_table( + jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr) +{ + page_t *target_table = NULL; + page_t *pml4 = obj_deref(tgt); + + //If the PML4 entry does not exist at this virtual ptr, the user may be + //trying to unmap the entire address space. We don't support this. + size_t pml4i = PML4I(vptr); + if(!pml4[pml4i].p) { + return ENOMAP; + } + target_table = &pml4[pml4i]; + + //Try to unmap the pml4 entry if the pml3 entry does not exist. + page_t *pml3 = (page_t*)(((uintptr_t)pml4[pml4i].paddr << 12) | IDENT_VIRT_BASE); + size_t pml3i = PML3I(vptr); + if(!pml3[pml3i].p) { + goto unmap_table; + } + target_table = &pml3[pml3i]; + + //Try to unmap the pml3 entry if the pml2 entry does not exist. + page_t *pml2 = (page_t*)(((uintptr_t)pml3[pml3i].paddr << 12) | IDENT_VIRT_BASE); + size_t pml2i = PML2I(vptr); + if(!pml2[pml2i].p) { + goto unmap_table; + } + //We are unmapping a pml2 entry. + target_table = &pml2[pml2i]; + +unmap_table: +{ + uintptr_t frame = target_table->paddr << 12; + page_t *target_vals = (page_t*)(frame | IDENT_VIRT_BASE); + + //Check that the page table at our target entry is empty. + //If it's not, we return an error saying that the entry contains a map. + for(size_t i = 0; i < 512; i++) { + if(target_vals[i].p) return EHASMAP; + } + + //Populate the none object with an untyped object at the free'd page frame. + obj_settype(dst, JOVE_OBJ_UNTYPED); + obj_setvalue(dst, frame); + + jove_untyped_t *untyped = obj_deref(dst); + untyped->limit = 0x1000; + + __asm__ volatile("invlpg (%0)":: "r"(vptr): "memory"); + return 0; +} +} void paging_pml4_init(void) @@ -196,7 +306,7 @@ paging_pml4_init(void) uintptr_t kernel_rodata_off = kernel_text_off + kernel_text_pages; for(size_t i = 0; i < kernel_rodata_pages; i++) { size_t off = i + kernel_rodata_off; - uintptr_t page_off = kernel_text_start_pptr + (off << 12); + uintptr_t page_off = kernel_rodata_start_pptr + (i << 12); _kernel_pml1[off].value = page_off | PAGE_PRESENT | PAGE_GLOBAL | PAGE_XD; } @@ -210,7 +320,7 @@ paging_pml4_init(void) uintptr_t kernel_data_off = kernel_rodata_off + kernel_rodata_pages; for(size_t i = 0; i < kernel_data_pages; i++) { size_t off = i + kernel_data_off; - uintptr_t page_off = kernel_text_start_pptr + (off << 12); + uintptr_t page_off = kernel_data_start_pptr + (i << 12); _kernel_pml1[off].value = page_off | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_GLOBAL | PAGE_XD; } diff --git a/arch/x86_64/hal/paging.h b/arch/x86_64/hal/paging.h index 754ac99..3e16003 100644 --- a/arch/x86_64/hal/paging.h +++ b/arch/x86_64/hal/paging.h @@ -1,3 +1,4 @@ +#include "api/syscall.h" #ifndef _JOVE_x86_64_HAL_PAGING_H #define _JOVE_x86_64_HAL_PAGING_H 1 @@ -51,6 +52,9 @@ extern void *_kernel_physptr; #define KERNEL_VIRT_BASE 0xFFFFFFFF80000000ULL #define KPTR_TOPHYS(v) (((uintptr_t)v) - KERNEL_VIRT_BASE + (uintptr_t)_kernel_physptr) +int pagedir_map_frame(page_t *pml4, uintptr_t pptr, uintptr_t vptr, uintmax_t flags); +int pagedir_map_table(page_t *pml4, uintptr_t pptr, uintptr_t vptr); + uintptr_t paging_get_pml4(void); void paging_pml4_init(void); diff --git a/arch/x86_64/hal/serial_com.c b/arch/x86_64/hal/serial_com.c index 5d7de24..8454c8a 100644 --- a/arch/x86_64/hal/serial_com.c +++ b/arch/x86_64/hal/serial_com.c @@ -64,7 +64,7 @@ void serial_com_init(void) { if(serial_com_init_port(SERIAL_COM1, 3)) { - hcf(); + return; } { diff --git a/arch/x86_64/hal/smp.c b/arch/x86_64/hal/smp.c index 85ba4ec..682c6e6 100644 --- a/arch/x86_64/hal/smp.c +++ b/arch/x86_64/hal/smp.c @@ -5,13 +5,13 @@ #include "config.h" #include "jove.h" #include "lib/printf.h" +#include "lib/string.h" #include "paging.h" #include "msr.h" -processor_t s_processors[SMP_PROCESSORS_MAX] = { 0 }; +processor_t s_processors[SMP_PROCESSORS_MAX]; -PAGEALIGN -jove_objdir_t s_processor_objdir = { 0 }; +PAGEALIGN jove_objdir_t s_processor_objdir; extern void gdt_setup(processor_t *processor); @@ -38,10 +38,9 @@ init_processor(processor_t *processor, jove_owned_obj_t *obj) void smp_init_bsp(void) { - idt_init(); - paging_pml4_init(); + memset(s_processors, 0, sizeof(s_processors)); + memset(&s_processor_objdir, 0, 0x1000); - kprintf("%p\n", _rootdir_obj); processor_t *bsp = &s_processors[0]; { jove_owned_obj_t *processor_objdir_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_PROCESSORS_I); @@ -54,6 +53,9 @@ smp_init_bsp(void) obj_release(bsp_obj); obj_release(processor_objdir_obj); } + + paging_pml4_init(); + idt_init(); } processor_t *processor_current(void) diff --git a/arch/x86_64/hal/uacpi.c b/arch/x86_64/hal/uacpi.c deleted file mode 100644 index 052f849..0000000 --- a/arch/x86_64/hal/uacpi.c +++ /dev/null @@ -1,15 +0,0 @@ -#include "lib/printf.h" -#include "uacpi/kernel_api.h" -#include "paging.h" - -void *uacpi_kernel_map(uacpi_phys_addr addr, uacpi_size len) -{ - //kprintf("UACPI kernel map %p -> %p\n", addr, (uintptr_t)addr | IDENT_VIRT_BASE); - return (void*)(addr | IDENT_VIRT_BASE); -} - -void uacpi_kernel_unmap(void *addr, uacpi_size len) -{ - (void)addr; - (void)len; -} diff --git a/arch/x86_64/main.c b/arch/x86_64/main.c index a35a465..7467843 100644 --- a/arch/x86_64/main.c +++ b/arch/x86_64/main.c @@ -12,16 +12,16 @@ #include "hal/memory.h" #include "hal/framebuffer.h" #include "hal/process.h" -#include "hal/uacpi.h" #include "boot/initrd.h" #include "boot/cmdline.h" -#include "uacpi/uacpi.h" int errno = 0; PAGEALIGN jove_objdir_t _rootdir; void *_rootdir_obj = &_rootdir.entries[ROOTDIR_DIR_I]; +struct init_payload _init_payload; + static void kernel_process_entry(void); void @@ -56,8 +56,6 @@ kernel_entry(void) static void kernel_process_entry(void) { - uacpi_kernel_init(); - init_setup(); kpanic("Reached the end of kernel main!\n"); } diff --git a/arch/x86_64/sys/init.c b/arch/x86_64/sys/init.c index c55eabe..40c3240 100644 --- a/arch/x86_64/sys/init.c +++ b/arch/x86_64/sys/init.c @@ -12,15 +12,9 @@ #include "boot/cmdline.h" #include "boot/initrd.h" -PAGEALIGN static page_t s_init_program_pml3[512]; -PAGEALIGN static page_t s_init_program_pml2[512]; -PAGEALIGN static page_t s_init_program_pml1[512]; -PAGEALIGN static uint8_t s_init_program_pages[INIT_PROGRAM_PAGES_MAX][0x1000]; - -PAGEALIGN static page_t s_init_stack_pml3[512]; -PAGEALIGN static page_t s_init_stack_pml2[512]; -PAGEALIGN static page_t s_init_stack_pml1[512]; -PAGEALIGN static uint8_t s_init_stack_pages[INIT_STACK_PAGES][0x1000]; +PAGEALIGN static uint8_t s_init_program_pages[INIT_PROGRAM_PAGES_MAX + 3][0x1000]; +PAGEALIGN static uint8_t s_init_stack_pages[INIT_STACK_PAGES + 3][0x1000]; +PAGEALIGN static uint8_t s_init_message_page[0x1000]; static int elf_is_valid(struct elf_header *ehdr) @@ -54,24 +48,6 @@ elf_is_valid(struct elf_header *ehdr) void init_setup(void) { - memset(s_init_program_pml3, 0, 0x1000); - memset(s_init_program_pml2, 0, 0x1000); - memset(s_init_program_pml1, 0, 0x1000); - - memset(s_init_stack_pml3, 0, 0x1000); - memset(s_init_stack_pml2, 0, 0x1000); - memset(s_init_stack_pml1, 0, 0x1000); - - uintptr_t init_program_pml3_pptr = KPTR_TOPHYS(&s_init_program_pml3); - uintptr_t init_program_pml2_pptr = KPTR_TOPHYS(&s_init_program_pml2); - uintptr_t init_program_pml1_pptr = KPTR_TOPHYS(&s_init_program_pml1); - uintptr_t init_program_pml0_pptr = KPTR_TOPHYS(&s_init_program_pages); - - uintptr_t init_stack_pml3_pptr = KPTR_TOPHYS(&s_init_stack_pml3); - uintptr_t init_stack_pml2_pptr = KPTR_TOPHYS(&s_init_stack_pml2); - uintptr_t init_stack_pml1_pptr = KPTR_TOPHYS(&s_init_stack_pml1); - uintptr_t init_stack_pml0_pptr = KPTR_TOPHYS(&s_init_stack_pages); - //Get the init file data from the initrd. const char *init_path = cmdline_getarg("init"); if(init_path == NULL) { @@ -102,6 +78,7 @@ init_setup(void) size_t last_base = 0; //Load the init ELF + size_t last_page = 0; for(size_t i = 0; i < init_ehdr->e_phnum; i++) { struct elf_phdr *phdr = init_data + init_ehdr->e_phoff + i * init_ehdr->e_phentsize; if(phdr->p_type != PT_LOAD) continue; @@ -109,28 +86,26 @@ init_setup(void) uintptr_t base = phdr->p_vaddr; size_t limit = phdr->p_memsz; + if(last_base < base + limit) last_base = base + limit; uintptr_t page_base = base & ~0xFFFULL; - size_t pml3i = (page_base >> PMLI_SHL(3)) & 0x1FF; - size_t pml2i = (page_base >> PMLI_SHL(2)) & 0x1FF; - size_t pml1i = (page_base >> PMLI_SHL(1)) & 0x1FF; - size_t base_pml0i = (page_base >> PMLI_SHL(0)) & 0x1FF; - - pml4[pml3i].value = init_program_pml3_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER; - s_init_program_pml3[pml2i].value = init_program_pml2_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER; - s_init_program_pml2[pml1i].value = init_program_pml1_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER; - size_t pages = (limit + 4095) / 4096; - for(size_t pmlo = 0; pmlo < pages; pmlo++) { - size_t pml0i = base_pml0i + pmlo; - if(pml0i > INIT_PROGRAM_PAGES_MAX) { + for(size_t i = 0; i < pages; i++) { + uintptr_t page_virt = page_base + (i << 12); + if(last_page > INIT_PROGRAM_PAGES_MAX) { kpanic("init: Program exceeds maximum program pages in the same hugepage frame!\n"); } - if(last_base < base + limit) last_base = base + limit; - uintptr_t pml0_pptr = init_program_pml0_pptr + (pml0i << 12); - s_init_program_pml1[pml0i].value = pml0_pptr | PAGE_PRESENT | PAGE_USER | PAGE_WRITEABLE; + int tblres = 0; + do { + uintptr_t tbl_frame = KPTR_TOPHYS(&s_init_program_pages[last_page++]); + tblres = pagedir_map_table(pml4, tbl_frame, page_virt); + if(tblres == EHASMAP) last_page--; + }while(!tblres); + + pagedir_map_frame(pml4, KPTR_TOPHYS(&s_init_program_pages[last_page++]), page_virt, + PAGE_WRITEABLE | PAGE_USER); } //Copy data from section if SHT_PROGBITS @@ -138,22 +113,32 @@ init_setup(void) } //Map the stack - pml4[255].value = init_stack_pml3_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER | PAGE_XD; - s_init_stack_pml3[511].value = init_stack_pml2_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER | PAGE_XD; - s_init_stack_pml2[511].value = init_stack_pml1_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER | PAGE_XD; - for(size_t pmlo = 0; pmlo < INIT_STACK_PAGES; pmlo++) { - size_t pml0i = 511 - pmlo; - uintptr_t page_pptr = init_stack_pml0_pptr + (pmlo << 12); - - s_init_stack_pml1[pml0i].value = page_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER | PAGE_XD; + size_t stack_base = 0x00007FFFFFFFF000; + int stack_mapres = 0; + + last_page = 0; + for(size_t i = 0; i < INIT_STACK_PAGES; i++) { + uintptr_t page_virt = stack_base - (i << 12); + int tblres = 0; + + do { + uintptr_t tbl_frame = KPTR_TOPHYS(&s_init_stack_pages[last_page++]); + tblres = pagedir_map_table(pml4, tbl_frame, page_virt); + if(tblres == EHASMAP) last_page--; + }while(!tblres); + + pagedir_map_frame(pml4, KPTR_TOPHYS(&s_init_stack_pages[last_page++]), page_virt, + PAGE_WRITEABLE | PAGE_USER | PAGE_XD); } //Map the syscall message. last_base = (last_base + 0xFFF) & ~0xFFF; - size_t last_page = (last_base >> 12) & 0x1FF; - uintptr_t message_pptr = init_program_pml0_pptr + (last_page << 12); - s_init_program_pml1[last_page].value = message_pptr | PAGE_PRESENT | PAGE_WRITEABLE | PAGE_USER | PAGE_XD; + uintptr_t message_pptr = KPTR_TOPHYS(s_init_message_page); + pagedir_map_frame(pml4, message_pptr, last_base, + PAGE_WRITEABLE | PAGE_USER | PAGE_XD); + extern struct init_payload _init_payload; + memcpy((void*)last_base, &_init_payload, sizeof(struct init_payload)); jove_owned_obj_t *message_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_MESSAGE_I); obj_settype(message_obj, JOVE_OBJ_MESSAGE); diff --git a/boot/limine/framebuffer.c b/boot/limine/framebuffer.c index 71d4c48..3758167 100644 --- a/boot/limine/framebuffer.c +++ b/boot/limine/framebuffer.c @@ -58,6 +58,8 @@ fb_init() struct limine_framebuffer *fb = _limine_framebuffers->framebuffers[0]; size_t fb_bytes = fb->width * fb->height * (fb->bpp / 8); void *fb_virt = fb_remap((uintptr_t)fb->address, fb_bytes); + + //void *fb_virt = fb->address; if(fb_virt == NULL) { kprintf("Unable to remap framebuffer.\n"); return; diff --git a/boot/limine/memorymap.c b/boot/limine/memorymap.c index 72c8de3..25dcc61 100644 --- a/boot/limine/memorymap.c +++ b/boot/limine/memorymap.c @@ -1,4 +1,5 @@ #include "hal/obj.h" +#include "jove.h" #include "limine.h" #include "hal/memory.h" #include "hal/obj.h" @@ -7,7 +8,10 @@ #include "lib/printf.h" extern struct limine_memmap_response *_limine_memmap_resp; + +PAGEALIGN static jove_objdir_t s_untyped_objdir; +static jove_objdir_t s_hwmemory_objdir; #define MEMMAP_MAX_ENTRIES 255 @@ -40,7 +44,7 @@ mem_setup_untyped(void) kprintf("Memory map provided by Limine:\n"); size_t untyped_i = 0; - size_t acpi_i = 0; + size_t hwmem_i = 0; uintptr_t highest_phys = 0; for(size_t i = 0; i < _limine_memmap_resp->entry_count; i++) { @@ -70,6 +74,21 @@ mem_setup_untyped(void) break; } } + if(entry->type == LIMINE_MEMMAP_RESERVED | + entry->type == LIMINE_MEMMAP_ACPI_NVS | + entry->type == LIMINE_MEMMAP_ACPI_TABLES) + { + size_t hw_pages = entry->length >> 12; + if(hw_pages > 4095) { + klogf("HW memory page is too big!\n", ""); + } + + jove_owned_obj_t *hwmem_obj = obj_take(&s_hwmemory_objdir.entries[hwmem_i++]); + obj_settype(hwmem_obj, JOVE_OBJ_HWMEMORY); + obj_setvalue(hwmem_obj, entry->base | (entry->length >> 12)); + + obj_release(hwmem_obj); + } } kprintf("Highest physical address: %p\n", highest_phys); } diff --git a/boot/limine/start.c b/boot/limine/start.c index 9fffb0b..803c1de 100644 --- a/boot/limine/start.c +++ b/boot/limine/start.c @@ -1,6 +1,7 @@ #include #include +#include "api/init.h" #include "boot/cmdline.h" #include "limine.h" @@ -64,7 +65,6 @@ void *_kernel_physptr = NULL; void *_initrd_module = NULL; struct limine_framebuffer_response *_limine_framebuffers; struct limine_memmap_response *_limine_memmap_resp = NULL; -struct limine_rsdp_response *_limine_rsdp_resp = NULL; __attribute__((noreturn)) void @@ -73,7 +73,9 @@ _start(void) _kernel_physptr = (void*)executable_address_req.response->physical_base; _limine_memmap_resp = memmap_req.response; _limine_framebuffers = framebuffer_request.response; - _limine_rsdp_resp = rsdp_request.response; + + extern struct init_payload _init_payload; + _init_payload.rsdp = (void*)((uintptr_t)rsdp_request.response->address & 0xFFFFFFFF); if(module_req.response->module_count > 0) { _initrd_module = module_req.response->modules[0]->address; diff --git a/boot/limine/uacpi.c b/boot/limine/uacpi.c deleted file mode 100644 index 93b4fd1..0000000 --- a/boot/limine/uacpi.c +++ /dev/null @@ -1,10 +0,0 @@ -#include "uacpi/kernel_api.h" -#include "limine.h" - -extern struct limine_rsdp_response *_limine_rsdp_resp; - -uacpi_status uacpi_kernel_get_rsdp(uacpi_phys_addr *out_rsdp_address) -{ - *out_rsdp_address = (uintptr_t)_limine_rsdp_resp->address; - return UACPI_STATUS_OK; -} diff --git a/hal/memory.h b/hal/memory.h index f1cf9db..7577c17 100644 --- a/hal/memory.h +++ b/hal/memory.h @@ -22,11 +22,17 @@ 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 untyped_retype(jove_owned_obj_t *tgt, uint8_t newtype); -int pagedir_map_frame( +int pagedir_map_untyped_frame( jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, uintptr_t vptr, struct syscall_pagedir_flags flg); -int pagedir_map_table( +int pagedir_map_untyped_table( jove_owned_obj_t *tgt, jove_owned_obj_t *untyped_obj, uintptr_t vptr, struct syscall_pagedir_flags flg); +int pagedir_unmap_untyped_frame( + jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr); +int pagedir_unmap_untyped_table( + jove_owned_obj_t *tgt, jove_owned_obj_t *dst, uintptr_t vptr); + + #endif diff --git a/hal/uacpi.c b/hal/uacpi.c deleted file mode 100644 index 5aea792..0000000 --- a/hal/uacpi.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "arch/x86_64/hal/obj.h" -#include "init.h" -#include "uacpi/uacpi.h" -#include "lib/printf.h" -#include "uacpi/tables.h" -#include - -jove_objdir_t s_acpi_objdir = { 0 }; - -void uacpi_kernel_log(uacpi_log_level lvl, const uacpi_char* fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - - kvprintf(fmt, ap); - - va_end(ap); -} - -void -uacpi_kernel_init(void) -{ - uint8_t uacpi_buffer[1024]; - uacpi_setup_early_table_access(uacpi_buffer, 1024); - - jove_owned_obj_t *acpi_objdir_obj = objdir_getlocal(_rootdir_obj, ROOTDIR_ACPI_I); - obj_settype(acpi_objdir_obj, JOVE_OBJ_OBJDIR); - obj_setvalue(acpi_objdir_obj, (uintptr_t)&s_acpi_objdir); - - size_t num_tables = uacpi_table_count(); - for(size_t i = 0; i < num_tables; i++) { - uacpi_table table; - uacpi_status get_res = uacpi_table_get_by_index(i, &table); - - if(get_res != UACPI_STATUS_OK) { - kprintf("uacpi: Failed to get table %i with code %s\n", i, uacpi_status_to_string(get_res)); - continue; - } - - jove_owned_obj_t *table_obj = objdir_getlocal(acpi_objdir_obj, i); - obj_settype(table_obj, JOVE_OBJ_ACPI_TABLE); - obj_setvalue(table_obj, table.virt_addr); - obj_release(table_obj); - } - obj_release(acpi_objdir_obj); -} diff --git a/hal/uacpi.h b/hal/uacpi.h deleted file mode 100644 index a3790c0..0000000 --- a/hal/uacpi.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _JOVE_UACPI_H -#define _JOVE_UACPI_H 1 - -void uacpi_kernel_init(void); - -#endif diff --git a/sys/syscall.c b/sys/syscall.c index 5670bbb..f41f3f6 100644 --- a/sys/syscall.c +++ b/sys/syscall.c @@ -44,8 +44,8 @@ static const syscall_handle_t s_syscall_handles[128] = { [JOVE_OBJ_OBJDIR] = _syscall_handle_objdir, [JOVE_OBJ_PAGEDIR] = _syscall_handle_generic, [JOVE_OBJ_PROCESSOR] = _syscall_handle_generic, + [JOVE_OBJ_HWMEMORY] = _syscall_handle_generic, [JOVE_OBJ_PROCESS] = _syscall_handle_generic, - [JOVE_OBJ_ACPI_TABLE] = _syscall_handle_generic, [JOVE_OBJ_INT_HANDLE] = _syscall_handle_generic, [JOVE_OBJ_INITRD_FILE] = _syscall_handle_generic, [JOVE_OBJ_FRAMEBUFFER] = _syscall_handle_generic, @@ -67,19 +67,19 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) jove_owned_obj_t *objdir = pcb_rootdir(pcb); jove_owned_obj_t *message_obj = objdir_trygetobj(objdir, message_path, message_pathlen); + int sysret = 0; + if(message_obj == NULL) { klogf("Process %i tried to call syscall with bad message %P : %s\n", pcb_pid(pcb), message_path, message_pathlen, errstr(errno)); + sysret = -errno; goto release_premsg; - return errno; } - int sysret = 0; - if(obj_gettype_linked(message_obj) != JOVE_OBJ_MESSAGE) { klogf("Process %i tried to call syscall with invalid object %P\n", pcb_pid(pcb), message_path, message_pathlen); - sysret = EBADOBJ; + sysret = -EBADOBJ; goto release_return; } @@ -91,7 +91,7 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) if(bytes_needed > messagelen) { //Target path exceeds message length. klogf("Process %i tried to call syscall with target path too big for message.\n", pcb_pid(pcb)); - sysret = ETOOSMALL; + sysret = -ETOOSMALL; goto release_return; } jove_owned_obj_t *target = objdir_trygetobj(objdir, header->path, header->pathlen); @@ -99,7 +99,7 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) //Could not find payload target in pcb rootdir. klogf("Process %i tried to call syscall with bad target path %P : %s\n", pcb_pid(pcb), header->path, header->pathlen, errstr(errno)); - sysret = errno; + sysret = -errno; goto release_return; } @@ -114,7 +114,7 @@ syscall_handler(uintmax_t message_path_raw, uint16_t message_pathlen) if(call_handle == NULL) { klogf("Process %i tried to call syscall on object %P which doesn't support syscalls!\n", pcb_pid(pcb), header->path, header->pathlen); - sysret = EBADOBJ; + sysret = -EBADOBJ; }else sysret = call_handle( pcb_obj, objdir, message_obj, target, diff --git a/sys/syscall.h b/sys/syscall.h index 2044069..9f56447 100644 --- a/sys/syscall.h +++ b/sys/syscall.h @@ -8,20 +8,20 @@ #define CHECK_TOOSMALL(required, present, fail_msg) \ do { if(present < required) { \ kprintf("%s: %s\n", __func__, fail_msg); \ - return ETOOSMALL; \ + return -ETOOSMALL; \ } } while(0) #define CHECK_OBJEXISTS(obj, fail_msg) \ do { if(obj == NULL) { \ kprintf("%s: %s\n", __func__, fail_msg); \ - return EBADOBJ; \ + return -EBADOBJ; \ } } while(0) #define CHECK_OBJTYPE(obj, type, fail_msg) \ do { if(obj_gettype(obj) != type) { \ kprintf("%s: %s\n", __func__, fail_msg); \ obj_release(obj); \ - return EBADOBJ; \ + return -EBADOBJ; \ } } while(0) #define SYSCALL_FUNCTION_ARGS \ diff --git a/sys/syscall_pagedir.c b/sys/syscall_pagedir.c index 144a02b..f80da76 100644 --- a/sys/syscall_pagedir.c +++ b/sys/syscall_pagedir.c @@ -1,3 +1,4 @@ +#include "api/syscall.h" #include "hal/memory.h" #include "jove.h" #include "lib/printf.h" @@ -26,10 +27,10 @@ s_syscall_pagedir_map( "Message too small for untyped path."); errno = 0; - jove_owned_obj_t *untyped_obj = objdir_getobj(objdir, + jove_owned_obj_t *untyped_obj = objdir_trygetobj(objdir, payload->untyped_path, payload->untyped_pathlen); if(errno) { - kprintf("%s: Untyped path does not point to a valid object.\n", __func__); + kprintf("%s: Untyped obj failed for the reason: %s\n", __func__, errstr(errno)); return errno; } @@ -52,6 +53,42 @@ s_syscall_pagedir_map( return 0; } +static int +s_syscall_pagedir_unmap( + jove_owned_obj_t *objdir, + jove_owned_obj_t *target_obj, + size_t payload_bytes, + void *payload_data, + jove_owned_obj_t **none_ret) +{ + size_t bytes_needed = sizeof(struct syscall_pagedir_unmap); + CHECK_TOOSMALL(bytes_needed, payload_bytes, + "Message too small for payload"); + + struct syscall_pagedir_unmap *payload = payload_data; + if(payload->virtual_address > 0xFFFF800000000000ULL) { + kprintf("%s: Virtual address is above user limit.\n", __func__); + return EBADARG; + } + + bytes_needed += payload->none_pathlen * 2; + CHECK_TOOSMALL(bytes_needed, payload_bytes, + "Message too small for none path"); + + jove_owned_obj_t *none_obj = objdir_trygetobj(objdir, + payload->none_path, payload->none_pathlen); + if(errno) { + kprintf("%s: None obj retrieval failed for the reason: %s\n", + __func__, errstr(errno)); + return errno; + } + + CHECK_OBJTYPE(none_obj, JOVE_OBJ_NONE, + "None path does not point to none object."); + *none_ret = none_obj; + return 0; +} + static int s_syscall_pagedir_map_frame( jove_owned_obj_t *objdir, @@ -66,7 +103,7 @@ s_syscall_pagedir_map_frame( } struct syscall_pagedir_map *payload = payload_data; - sysret = pagedir_map_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags); + sysret = pagedir_map_untyped_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags); obj_release(untyped_obj); return sysret; } @@ -85,11 +122,43 @@ s_syscall_pagedir_map_table( } struct syscall_pagedir_map *payload = payload_data; - sysret = pagedir_map_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags); + sysret = pagedir_map_untyped_frame(target_obj, untyped_obj, payload->virtual_address, payload->flags); obj_release(untyped_obj); return sysret; } +static int +s_syscall_pagedir_unmap_frame( + jove_owned_obj_t *objdir, + jove_owned_obj_t *target_obj, + size_t payload_bytes, + void *payload_data) +{ + jove_owned_obj_t *none_obj; + int sysret = s_syscall_pagedir_unmap(objdir, target_obj, payload_bytes, payload_data, &none_obj); + + if(!sysret) return sysret; + struct syscall_pagedir_unmap *payload = payload_data; + + return pagedir_unmap_untyped_frame(target_obj, none_obj, payload->virtual_address); +} + +static int +s_syscall_pagedir_unmap_table( + jove_owned_obj_t *objdir, + jove_owned_obj_t *target_obj, + size_t payload_bytes, + void *payload_data) +{ + jove_owned_obj_t *none_obj; + int sysret = s_syscall_pagedir_unmap(objdir, target_obj, payload_bytes, payload_data, &none_obj); + + if(!sysret) return sysret; + struct syscall_pagedir_unmap *payload = payload_data; + + return pagedir_unmap_untyped_table(target_obj, none_obj, payload->virtual_address); +} + int _syscall_handle_pagedir( jove_owned_obj_t *pcb_obj, @@ -105,6 +174,10 @@ _syscall_handle_pagedir( return s_syscall_pagedir_map_frame(objdir, target_obj, bytes_left, payload); case SYSCALL_PAGEDIR_MAP_TABLE: return s_syscall_pagedir_map_table(objdir, target_obj, bytes_left, payload); + case SYSCALL_PAGEDIR_UNMAP_FRAME: + return s_syscall_pagedir_unmap_frame(objdir, target_obj, bytes_left, payload); + case SYSCALL_PAGEDIR_UNMAP_TABLE: + return s_syscall_pagedir_unmap_table(objdir, target_obj, bytes_left, payload); default: kprintf("syscall_handle_pagedir: Pagedir does not support syscall %i\n", header->callid); return EBADARG; diff --git a/sys/syscall_untyped.c b/sys/syscall_untyped.c index fcdb5f6..975faaa 100644 --- a/sys/syscall_untyped.c +++ b/sys/syscall_untyped.c @@ -72,7 +72,7 @@ int _syscall_handle_untyped( return s_syscall_untyped_merge(objdir, target_obj, payload_bytes, payload); default: kprintf("syscall_untyped: Untyped object does not support syscall %i\n", header->callid); - return EBADARG; + return -EBADARG; } return 0; } diff --git a/uacpi b/uacpi deleted file mode 160000 index f5f6cc2..0000000 --- a/uacpi +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f5f6cc29f85dd5db0dd79c47700c8f3ebce18be4 diff --git a/uacpi.mk b/uacpi.mk deleted file mode 100644 index 8e1e90c..0000000 --- a/uacpi.mk +++ /dev/null @@ -1,20 +0,0 @@ -UACPI_DIR := uacpi - -UACPI_CFILES := $(wildcard $(UACPI_DIR)/source/*.c) -UACPI_OFILES := $(patsubst %.c,%.o,$(UACPI_CFILES)) -UACPI_DFILES := $(patsubst %.c,%.d,$(UACPI_CFILES)) - -UACPI_IDIR := $(UACPI_DIR)/include - -CLEAN_DEPENDS += uacpi_clean - -CFLAGS += -DUACPI_BAREBONES_MODE -DUACPI_FORMATTED_LOGGING -I$(UACPI_IDIR) -DEPFILES += $(UACPI_DFILES) - -.PHONY: uacpi.a -uacpi.a: $(UACPI_OFILES) - ar rcs $@ $^ - -uacpi_clean: - -rm $(UACPI_OFILES) - -rm $(UACPI_DFILES) -- cgit v1.2.3