#include #include extern kernel_ctx_t ctx; rsdp_t *acpi_find_rsdp() { char *ptr = (char *)(KERNEL_VMA + BIOS_START); const char sig[RSDP_SIG_LEN] = RSDP_SIG; for (; (uint32_t)ptr - KERNEL_VMA <= BIOS_END; ptr += 16) { int i = 0; for (; i < RSDP_SIG_LEN; i++) if (ptr[i] != sig[i]) break; if (i == RSDP_SIG_LEN) return (rsdp_t *)ptr; } return 0; } uint8_t acpi_checksum(void *s, int size) { uint32_t sum = 0; for (int i = 0; i < size; i++) { sum += ((uint8_t *)s)[i]; } return (sum & 0xFF) == 0; } void *acpi_find_sdt(rsdt_t *rsdt, const char *sig) { int entries = (rsdt->hdr.Length - sizeof(sdt_hdr_t)) / 4; for (int i = 0; i < entries; i++) { const char *ptr = (const char *)rsdt->other_tables[i]; int j = 0; for (; j < 4; j++) if (ptr[j] != sig[j]) break; if (j == 4) return (void *)ptr; } return 0; } bool acpi_init() { rsdp_t *rsdp = acpi_find_rsdp(); if (!rsdp) { LOG("Invalid RSDP\n"); return FALSE; } if (!acpi_checksum(rsdp, sizeof(rsdp_t))) { LOG("Invalid RSDP checksum\n"); return FALSE; } if (rsdp->Revision == 0) LOG("Using ACPI version 1.0\n") else if (rsdp->Revision == 2) { LOG("ACPI versions higher than 1.0 are not currently supported!\n"); return FALSE; } rsdt_t *rsdt = (rsdt_t *)(rsdp->RsdtAddress); if (!rsdt) { LOG("Invalid RSDT\n"); return FALSE; } if (!acpi_checksum(rsdt, rsdt->hdr.Length)) { LOG("Invalid RSDT checksum\n"); return FALSE; } ctx.rsdt = rsdt; LOG("RSDT is valid\n"); void *mcfg = acpi_find_sdt(rsdt, "MCFG"); if (!mcfg) LOG("PCIe not supported\n"); return TRUE; }