From 49867193d557287fcd454366bc43a30b106cb2a4 Mon Sep 17 00:00:00 2001 From: Kevin Alavik Date: Sun, 1 Jun 2025 14:46:22 +0200 Subject: [PATCH] fix/kernel: Fixed ACPI tables --- kernel/GNUmakefile | 6 ++++ kernel/Kconfig | 33 ++++++++++------- kernel/src/arch/paging.c | 15 +++++++- kernel/src/boot/emk.h | 4 +++ kernel/src/mm/vmm.c | 2 -- kernel/src/sys/acpi.c | 76 +++++++++++++++------------------------- 6 files changed, 73 insertions(+), 63 deletions(-) diff --git a/kernel/GNUmakefile b/kernel/GNUmakefile index 7c7ae95..5935194 100644 --- a/kernel/GNUmakefile +++ b/kernel/GNUmakefile @@ -69,6 +69,12 @@ ifeq ($(CONFIG_ENABLE_FLANTERM),y) CFLAGS += -I../external/flanterm/ -DFLANTERM_SUPPORT=1 endif +ifeq ($(CONFIG_LARGE_PAGES),y) + CFLAGS += -DLARGE_PAGES=1 +else + CFLAGS += -DLARGE_PAGES=0 +endif + EXCLUDE_SRCS := \ src/mm/heap/ff.c \ ../external/flanterm/flanterm.c \ diff --git a/kernel/Kconfig b/kernel/Kconfig index e29327e..7155137 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -5,15 +5,15 @@ menu "Build" prompt "Build Mode" default BUILD_MODE_DEBUG - config BUILD_MODE_DEBUG - bool "Debug" - help - Build with debug symbols and no optimizations. + config BUILD_MODE_DEBUG + bool "Debug" + help + Build with debug symbols and no optimizations. - config BUILD_MODE_RELEASE - bool "Release" - help - Build with optimizations and no debug symbols. + config BUILD_MODE_RELEASE + bool "Release" + help + Build with optimizations and no debug symbols. endchoice endmenu @@ -23,10 +23,10 @@ menu "Memory" prompt "Kernel Heap Algorithm" default KERNEL_HEAP_FF - config KERNEL_HEAP_FF - bool "First-Fit" - help - Use the First-Fit memory allocation algorithm (ff.c). + config KERNEL_HEAP_FF + bool "First-Fit" + help + Use the First-Fit memory allocation algorithm (ff.c). endchoice @@ -52,3 +52,12 @@ menu "Extras" help Includes support for the Flanterm terminal emulator. Useful for debugging real hardware. endmenu + +menu "Experimental" + comment "These features are experimental and might break the kernel. Don't expect stability." + + config LARGE_PAGES + bool "Enable 2M Pages" + help + Adds support for vmap_large() +endmenu diff --git a/kernel/src/arch/paging.c b/kernel/src/arch/paging.c index 490d7d7..2b4fe60 100644 --- a/kernel/src/arch/paging.c +++ b/kernel/src/arch/paging.c @@ -112,7 +112,8 @@ uint64_t *pmget(void) return (uint64_t *)HIGHER_HALF(cr3); } -/* Map virtual to physical address (large), only use during paging init */ +/* Map virtual to physical address (large 2M pages) */ +#if LARGE_PAGES bool _supports_large_pages() { uint32_t eax, ebx, ecx, edx; @@ -150,6 +151,18 @@ int vmap_large(uint64_t *pagemap, uint64_t virt, uint64_t phys, uint64_t flags) __asm__ volatile("invlpg (%0)" ::"r"(virt) : "memory"); return 0; } +#else // LARGE_PAGES +bool _supports_large_pages() +{ + log_early("warning: Large pages are disabled in the kernel"); + return false; +} + +int vmap_large(uint64_t *, uint64_t, uint64_t, uint64_t) +{ + return -1; +} +#endif // LARGE_PAGES /* Map virtual to physical address */ int vmap(uint64_t *pagemap, uint64_t virt, uint64_t phys, uint64_t flags) diff --git a/kernel/src/boot/emk.h b/kernel/src/boot/emk.h index c55fde8..763e901 100644 --- a/kernel/src/boot/emk.h +++ b/kernel/src/boot/emk.h @@ -35,6 +35,10 @@ extern struct limine_mp_response *mp_response; extern struct flanterm_context *ft_ctx; #endif // FLANTERM_SUPPORT +#ifndef LARGE_PAGES +#define LARGE_PAGES 0 +#endif // LARGE_PAGES + #define LOG_SEPARATOR "----------------------------------------" #endif // EMK_H \ No newline at end of file diff --git a/kernel/src/mm/vmm.c b/kernel/src/mm/vmm.c index cf26189..afb0f2c 100644 --- a/kernel/src/mm/vmm.c +++ b/kernel/src/mm/vmm.c @@ -135,7 +135,6 @@ void *vallocat(vctx_t *ctx, size_t pages, uint64_t flags, uint64_t phys) vmap(ctx->pagemap, new->start + (i * PAGE_SIZE), page, new->flags); } - memset((void *)new->start, PAGE_SIZE * pages, 0); return (void *)new->start; } region = region->next; @@ -161,7 +160,6 @@ void *vallocat(vctx_t *ctx, size_t pages, uint64_t flags, uint64_t phys) vmap(ctx->pagemap, new->start + (i * PAGE_SIZE), page, new->flags); } - memset((void *)new->start, PAGE_SIZE * pages, 0); return (void *)new->start; } diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c index 8cc429f..1f36ac0 100644 --- a/kernel/src/sys/acpi.c +++ b/kernel/src/sys/acpi.c @@ -1,28 +1,14 @@ +/* EMK 1.0 Copyright (c) 2025 Piraterna */ #include #include #include #include #include #include -#include static int acpi_uses_xsdt = 0; static void *acpi_rsdt_ptr = NULL; -void *acpi_vtable(uint64_t phys) -{ - acpi_sdt_header_t *tmp = (acpi_sdt_header_t *)vallocat(kvm_ctx, 1, VALLOC_RW, phys); - if (!tmp) - { - kpanic(NULL, "Failed to map first page of ACPI table, got virt: %p", tmp); - return NULL; - } - - uint32_t full_size = tmp->length; - uint32_t page_count = (full_size + 0xFFF) / 0x1000; - return vallocat(kvm_ctx, page_count, VALLOC_RW, phys); -} - void acpi_init(void) { if (!rsdp_response || !rsdp_response->address) @@ -31,55 +17,49 @@ void acpi_init(void) } acpi_rsdp_t *rsdp = (acpi_rsdp_t *)vallocat(kvm_ctx, 1, VALLOC_RW, rsdp_response->address); - if (memcmp(rsdp->signature, "RSD PTR", 7) != 0) - kpanic(NULL, "Invalid RSDP signature! EMK depends on APIC 1.0 or higher"); - if (rsdp->revision >= 2) + if (memcmp(rsdp->signature, "RSD PTR", 7) != 0) + kpanic(NULL, "Invalid RSDP signature!"); + + if (rsdp->revision != 0) { acpi_uses_xsdt = 1; acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp; - acpi_rsdt_ptr = acpi_vtable(xsdp->xsdt_address); - log_early("Using XSDT"); - } - else - { - acpi_uses_xsdt = 0; - acpi_rsdt_ptr = acpi_vtable(rsdp->rsdt_address); - log_early("Using RSDT"); + acpi_rsdt_ptr = (acpi_xsdt_t *)HIGHER_HALF(xsdp->xsdt_address); + log_early("XSDT found at %p", acpi_rsdt_ptr); + return; } + + acpi_rsdt_ptr = (acpi_rsdt_t *)HIGHER_HALF(rsdp->rsdt_address); + log_early("RSDT found at %p", acpi_rsdt_ptr); } void *acpi_find_table(const char *name) { - if (!acpi_rsdt_ptr || !name) - return NULL; - - if (acpi_uses_xsdt) - { - acpi_xsdt_t *xsdt = (acpi_xsdt_t *)acpi_rsdt_ptr; - uint32_t entries = (xsdt->sdt.length - sizeof(xsdt->sdt)) / 8; - - for (uint32_t i = 0; i < entries; i++) - { - uint64_t phys_addr = ((uint64_t *)xsdt->table)[i]; - acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)acpi_vtable(phys_addr); - if (!memcmp(sdt->signature, name, 4)) - return sdt; - } - } - else + if (!acpi_uses_xsdt) { acpi_rsdt_t *rsdt = (acpi_rsdt_t *)acpi_rsdt_ptr; uint32_t entries = (rsdt->sdt.length - sizeof(rsdt->sdt)) / 4; - for (uint32_t i = 0; i < entries; i++) { - uint32_t phys_addr = ((uint32_t *)rsdt->table)[i]; - acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)acpi_vtable(phys_addr); + acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)HIGHER_HALF(*((uint32_t *)rsdt->table + i)); if (!memcmp(sdt->signature, name, 4)) - return sdt; + return (void *)sdt; + } + return NULL; + } + acpi_xsdt_t *xsdt = (acpi_xsdt_t *)acpi_rsdt_ptr; + log_early("XSDT address: %p", xsdt); + uint32_t entries = (xsdt->sdt.length - sizeof(xsdt->sdt)) / 8; + + for (uint32_t i = 0; i < entries; i++) + { + acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)HIGHER_HALF(*((uint64_t *)xsdt->table + i)); + if (!memcmp(sdt->signature, name, 4)) + { + return (void *)sdt; } } return NULL; -} +} \ No newline at end of file