1
0
Fork 0

fix/kernel: Fixed ACPI tables

This commit is contained in:
Kevin Alavik 2025-06-01 14:46:22 +02:00
parent c15b93e001
commit 49867193d5
Signed by: cmpsb
GPG key ID: 10D1CC0526FDC6D7
6 changed files with 73 additions and 63 deletions

View file

@ -69,6 +69,12 @@ ifeq ($(CONFIG_ENABLE_FLANTERM),y)
CFLAGS += -I../external/flanterm/ -DFLANTERM_SUPPORT=1 CFLAGS += -I../external/flanterm/ -DFLANTERM_SUPPORT=1
endif endif
ifeq ($(CONFIG_LARGE_PAGES),y)
CFLAGS += -DLARGE_PAGES=1
else
CFLAGS += -DLARGE_PAGES=0
endif
EXCLUDE_SRCS := \ EXCLUDE_SRCS := \
src/mm/heap/ff.c \ src/mm/heap/ff.c \
../external/flanterm/flanterm.c \ ../external/flanterm/flanterm.c \

View file

@ -5,15 +5,15 @@ menu "Build"
prompt "Build Mode" prompt "Build Mode"
default BUILD_MODE_DEBUG default BUILD_MODE_DEBUG
config BUILD_MODE_DEBUG config BUILD_MODE_DEBUG
bool "Debug" bool "Debug"
help help
Build with debug symbols and no optimizations. Build with debug symbols and no optimizations.
config BUILD_MODE_RELEASE config BUILD_MODE_RELEASE
bool "Release" bool "Release"
help help
Build with optimizations and no debug symbols. Build with optimizations and no debug symbols.
endchoice endchoice
endmenu endmenu
@ -23,10 +23,10 @@ menu "Memory"
prompt "Kernel Heap Algorithm" prompt "Kernel Heap Algorithm"
default KERNEL_HEAP_FF default KERNEL_HEAP_FF
config KERNEL_HEAP_FF config KERNEL_HEAP_FF
bool "First-Fit" bool "First-Fit"
help help
Use the First-Fit memory allocation algorithm (ff.c). Use the First-Fit memory allocation algorithm (ff.c).
endchoice endchoice
@ -52,3 +52,12 @@ menu "Extras"
help help
Includes support for the Flanterm terminal emulator. Useful for debugging real hardware. Includes support for the Flanterm terminal emulator. Useful for debugging real hardware.
endmenu 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

View file

@ -112,7 +112,8 @@ uint64_t *pmget(void)
return (uint64_t *)HIGHER_HALF(cr3); 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() bool _supports_large_pages()
{ {
uint32_t eax, ebx, ecx, edx; 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"); __asm__ volatile("invlpg (%0)" ::"r"(virt) : "memory");
return 0; 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 */ /* Map virtual to physical address */
int vmap(uint64_t *pagemap, uint64_t virt, uint64_t phys, uint64_t flags) int vmap(uint64_t *pagemap, uint64_t virt, uint64_t phys, uint64_t flags)

View file

@ -35,6 +35,10 @@ extern struct limine_mp_response *mp_response;
extern struct flanterm_context *ft_ctx; extern struct flanterm_context *ft_ctx;
#endif // FLANTERM_SUPPORT #endif // FLANTERM_SUPPORT
#ifndef LARGE_PAGES
#define LARGE_PAGES 0
#endif // LARGE_PAGES
#define LOG_SEPARATOR "----------------------------------------" #define LOG_SEPARATOR "----------------------------------------"
#endif // EMK_H #endif // EMK_H

View file

@ -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); vmap(ctx->pagemap, new->start + (i * PAGE_SIZE), page, new->flags);
} }
memset((void *)new->start, PAGE_SIZE * pages, 0);
return (void *)new->start; return (void *)new->start;
} }
region = region->next; 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); vmap(ctx->pagemap, new->start + (i * PAGE_SIZE), page, new->flags);
} }
memset((void *)new->start, PAGE_SIZE * pages, 0);
return (void *)new->start; return (void *)new->start;
} }

View file

@ -1,28 +1,14 @@
/* EMK 1.0 Copyright (c) 2025 Piraterna */
#include <sys/acpi.h> #include <sys/acpi.h>
#include <boot/emk.h> #include <boot/emk.h>
#include <lib/string.h> #include <lib/string.h>
#include <util/log.h> #include <util/log.h>
#include <sys/kpanic.h> #include <sys/kpanic.h>
#include <mm/vmm.h> #include <mm/vmm.h>
#include <mm/heap.h>
static int acpi_uses_xsdt = 0; static int acpi_uses_xsdt = 0;
static void *acpi_rsdt_ptr = NULL; 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) void acpi_init(void)
{ {
if (!rsdp_response || !rsdp_response->address) if (!rsdp_response || !rsdp_response->address)
@ -31,53 +17,47 @@ void acpi_init(void)
} }
acpi_rsdp_t *rsdp = (acpi_rsdp_t *)vallocat(kvm_ctx, 1, VALLOC_RW, rsdp_response->address); 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_uses_xsdt = 1;
acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp; acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp;
acpi_rsdt_ptr = acpi_vtable(xsdp->xsdt_address); acpi_rsdt_ptr = (acpi_xsdt_t *)HIGHER_HALF(xsdp->xsdt_address);
log_early("Using XSDT"); log_early("XSDT found at %p", acpi_rsdt_ptr);
} return;
else
{
acpi_uses_xsdt = 0;
acpi_rsdt_ptr = acpi_vtable(rsdp->rsdt_address);
log_early("Using RSDT");
} }
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) void *acpi_find_table(const char *name)
{ {
if (!acpi_rsdt_ptr || !name) if (!acpi_uses_xsdt)
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
{ {
acpi_rsdt_t *rsdt = (acpi_rsdt_t *)acpi_rsdt_ptr; acpi_rsdt_t *rsdt = (acpi_rsdt_t *)acpi_rsdt_ptr;
uint32_t entries = (rsdt->sdt.length - sizeof(rsdt->sdt)) / 4; uint32_t entries = (rsdt->sdt.length - sizeof(rsdt->sdt)) / 4;
for (uint32_t i = 0; i < entries; i++) 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 *)HIGHER_HALF(*((uint32_t *)rsdt->table + i));
acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)acpi_vtable(phys_addr);
if (!memcmp(sdt->signature, name, 4)) 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;
} }
} }