diff --git a/credits.txt b/credits.txt deleted file mode 100644 index 85e89bf..0000000 --- a/credits.txt +++ /dev/null @@ -1 +0,0 @@ -- Thanks to Raph and https://github.com/SILD-Project/soaplin for most APIC related code \ No newline at end of file diff --git a/kernel/src/emk.c b/kernel/src/emk.c index fc652f1..d214a92 100644 --- a/kernel/src/emk.c +++ b/kernel/src/emk.c @@ -18,6 +18,7 @@ #include #endif // FLANTERM_SUPPORT #include +#include __attribute__((used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3); __attribute__((used, section(".limine_requests"))) static volatile struct limine_memmap_request memmap_request = { @@ -166,6 +167,14 @@ void emk_entry(void) *c = 32; kfree(c); + /* Setup ACPI (and TODO APIC) */ + rsdp_response = rsdp_request.response; + if (!rsdp_response) + { + kpanic(NULL, "Failed to get RSDP request"); + } + acpi_init(); + /* Finished */ log_early("%s", LOG_SEPARATOR); uint32_t uptime = 0; diff --git a/kernel/src/sys/acpi.c b/kernel/src/sys/acpi.c new file mode 100644 index 0000000..1f36ac0 --- /dev/null +++ b/kernel/src/sys/acpi.c @@ -0,0 +1,65 @@ +/* EMK 1.0 Copyright (c) 2025 Piraterna */ +#include +#include +#include +#include +#include +#include + +static int acpi_uses_xsdt = 0; +static void *acpi_rsdt_ptr = NULL; + +void acpi_init(void) +{ + if (!rsdp_response || !rsdp_response->address) + { + kpanic(NULL, "No RSDP provided"); + } + + 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!"); + + if (rsdp->revision != 0) + { + acpi_uses_xsdt = 1; + 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; + } + + 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_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_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 diff --git a/kernel/src/sys/acpi.h b/kernel/src/sys/acpi.h new file mode 100644 index 0000000..623c297 --- /dev/null +++ b/kernel/src/sys/acpi.h @@ -0,0 +1,60 @@ +/* EMK 1.0 Copyright (c) 2025 Piraterna */ +#ifndef ACPI_H +#define ACPI_H + +#include +#include +#include + +typedef struct acpi_rsdp +{ + char signature[8]; + uint8_t checksum; + char oem_id[6]; + uint8_t revision; + uint32_t rsdt_address; +} __attribute__((packed)) acpi_rsdp_t; + +typedef struct acpi_xsdp +{ + char signature[8]; + uint8_t checksum; + char oem_id[6]; + uint8_t revision; + uint32_t rsdt_address; + uint32_t resv; + uint32_t length; + uint64_t xsdt_address; + uint8_t extended_checksum; + uint8_t reserved[3]; +} __attribute__((packed)) acpi_xsdp_t; + +typedef struct acpi_sdt_header +{ + char signature[4]; + uint32_t length; + uint8_t revision; + uint8_t checksum; + char oem_id[6]; + char oem_table_id[8]; + uint32_t oem_revision; + uint32_t creator_id; + 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); + +#endif // ACPI_H \ No newline at end of file