fix/kernel: Fixed ACPI tables
This commit is contained in:
parent
c15b93e001
commit
49867193d5
6 changed files with 73 additions and 63 deletions
|
@ -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 \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,55 +17,49 @@ 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue