From 3b8639467fc5e96e14dab86cc4fa50ecdb50527a Mon Sep 17 00:00:00 2001 From: Kevin Alavik Date: Fri, 16 May 2025 07:39:40 +0200 Subject: [PATCH] fix/kernel: Started fixing bootstrap acpi parser --- kernel/src/emk.c | 8 +++ kernel/src/sys/acpi.c | 111 ++++++++++-------------------------------- kernel/src/sys/acpi.h | 15 +++++- 3 files changed, 48 insertions(+), 86 deletions(-) diff --git a/kernel/src/emk.c b/kernel/src/emk.c index c25685e..94078ba 100644 --- a/kernel/src/emk.c +++ b/kernel/src/emk.c @@ -171,5 +171,13 @@ void emk_entry(void) acpi_init(); log_early("Initialized ACPI"); + void *madt = acpi_find_table("MADT"); + if (!madt) + { + kpanic(NULL, "Failed to find MADT table"); + } + + log_early("Found MADT at %p", madt); + hlt(); } \ No newline at end of file diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c index a73a2c6..ef482ef 100644 --- a/kernel/src/sys/acpi.c +++ b/kernel/src/sys/acpi.c @@ -8,31 +8,6 @@ static int acpi_uses_xsdt = 0; static void *acpi_rsdt_ptr = NULL; -static uint8_t acpi_checksum(void *ptr, size_t len) -{ - uint8_t sum = 0; - uint8_t *data = (uint8_t *)ptr; - for (size_t i = 0; i < len; i++) - { - sum += data[i]; - } - return sum; -} - -static int acpi_validate_rsdp(acpi_rsdp_t *rsdp) -{ - return acpi_checksum(rsdp, sizeof(acpi_rsdp_t)) == 0; -} - -static int acpi_validate_xsdp(acpi_xsdp_t *xsdp) -{ - if (acpi_checksum(xsdp, sizeof(acpi_rsdp_t)) != 0) - return 0; - if (acpi_checksum(xsdp, xsdp->length) != 0) - return 0; - return 1; -} - void acpi_init(void) { if (!rsdp_response || !rsdp_response->address) @@ -40,81 +15,47 @@ void acpi_init(void) kpanic(NULL, "No RSDP provided"); } - acpi_rsdp_t *rsdp = (acpi_rsdp_t *)rsdp_response->address; - log_early("RSDP found at %p", rsdp); - if (strncmp(rsdp->signature, "RSD PTR ", 8) != 0) - { - kpanic(NULL, "Invalid RSDP signature"); - } + acpi_rsdp_t *rsdp = (acpi_rsdp_t *)HIGHER_HALF(rsdp_response->address); + if (memcmp(rsdp->signature, "RSD PTR", 7)) + kpanic(NULL, "Invalid RSDP signature!"); - if (rsdp->revision >= 2) + if (rsdp->revision != 0) { - acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp; - if (!acpi_validate_xsdp(xsdp)) - { - kpanic(NULL, "XSDP checksum validation failed"); - } acpi_uses_xsdt = 1; - acpi_rsdt_ptr = (void *)(uintptr_t)xsdp->xsdt_address; - } - else - { - if (!acpi_validate_rsdp(rsdp)) - { - kpanic(NULL, "RSDP checksum validation failed"); - } - acpi_uses_xsdt = 0; - acpi_rsdt_ptr = (void *)(uintptr_t)rsdp->rsdt_address; + acpi_xsdp_t *xsdp = (acpi_xsdp_t *)rsdp; + acpi_rsdt_ptr = (acpi_xsdt_t *)HIGHER_HALF(xsdp->xsdt_address); + log_early("XSDT found at %p", acpi_rsdt_ptr); + return; } - /* Validate RSDT/XSDT header */ - acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)acpi_rsdt_ptr; - if (acpi_checksum(sdt, sdt->length) != 0) - { - kpanic(NULL, "RSDT/XSDT checksum validation failed"); - } - - log_early("ACPI initialized, using %s at %p", - acpi_uses_xsdt ? "XSDT" : "RSDT", acpi_rsdt_ptr); + 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) + 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++) + { + acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)HIGHER_HALF(*((uint32_t *)rsdt->table + i)); + if (!memcmp(sdt->signature, name, 4)) + return (void *)sdt; + } return NULL; - - acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)acpi_rsdt_ptr; - uint32_t entries; - - if (acpi_uses_xsdt) - { - entries = (sdt->length - sizeof(acpi_sdt_header_t)) / sizeof(uint64_t); - } - else - { - entries = (sdt->length - sizeof(acpi_sdt_header_t)) / sizeof(uint32_t); } + 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 *table; - if (acpi_uses_xsdt) + acpi_sdt_header_t *sdt = (acpi_sdt_header_t *)HIGHER_HALF(*((uint64_t *)xsdt->table + i)); + if (!memcmp(sdt->signature, name, 4)) { - uint64_t *xsdt_entries = (uint64_t *)(sdt + 1); - table = (acpi_sdt_header_t *)(uintptr_t)xsdt_entries[i]; - } - else - { - uint32_t *rsdt_entries = (uint32_t *)(sdt + 1); - table = (acpi_sdt_header_t *)(uintptr_t)rsdt_entries[i]; - } - - if (strncmp(table->signature, name, 4) == 0) - { - if (acpi_checksum(table, table->length) == 0) - { - return table; - } + return (void *)sdt; } } diff --git a/kernel/src/sys/acpi.h b/kernel/src/sys/acpi.h index 3a87048..26ad17b 100644 --- a/kernel/src/sys/acpi.h +++ b/kernel/src/sys/acpi.h @@ -22,9 +22,10 @@ typedef struct acpi_xsdp char oem_id[6]; uint8_t revision; uint32_t rsdt_address; + uint32_t resv; uint32_t length; uint64_t xsdt_address; - uint8_t full_checksum; + uint8_t extended_checksum; uint8_t reserved[3]; } __attribute__((packed)) acpi_xsdp_t; @@ -41,6 +42,18 @@ typedef struct acpi_sdt_header uint32_t creator_revision; } __attribute__((packed)) acpi_sdt_header_t; +typedef struct acpi_rsdt +{ + acpi_sdt_header_t sdt; + char table[]; +} __attribute__((packed)) acpi_rsdt_t; + +typedef struct acpi_xsdt +{ + acpi_sdt_header_t sdt; + char table[]; +} __attribute__((packed)) acpi_xsdt_t; + void *acpi_find_table(const char *name); void acpi_init(void);