#include #include #include #include #include struct rsdp *acpi_locate_rsdp() { char *ptr = (char *)BIOS_START; char *str = RSDP_SIG; while ((uint32_t)ptr <= (uint32_t)BIOS_END - RSDP_SIG_LEN) { int i; for (i = 0; i < RSDP_SIG_LEN; i++) { if (ptr[i] != str[i]) break; } if (i == RSDP_SIG_LEN) { return (struct rsdp *)ptr; } ptr++; } return 0; } int acpi_validate_rsdp_checksum(struct rsdp *s) { uint8_t *bytes = (uint8_t *)s; uint8_t sum = 0; for (int i = 0; i < RSDP_SIZE; i++) { sum += bytes[i]; } return (sum & 0x0F) == 0; } int acpi_validate_sdt_checksum(struct ACPISDTHeader *s) { uint8_t sum = 0; for (uint32_t i = 0; i < s->Length; i++) { sum += ((char *)s)[i]; } return sum == 0; } void *acpi_locate_sdt(struct rsdt *rsdt, const char sig[4]) { int entries = (rsdt->h.Length - sizeof(rsdt->h)) / 4; for (int i = 0; i < entries; i++) { struct ACPISDTHeader *h = (struct ACPISDTHeader *) rsdt->other_sdt[i]; if (!strncmp(h->Signature, sig, 4)) { if (acpi_validate_sdt_checksum(h)) return (void *) h; else return 0; } } return 0; } int acpi_init(struct kernel_context *ctx) { struct rsdp *found_rsdp = acpi_locate_rsdp(); if (!found_rsdp) { set_color(VGA_COLOR_RED); printf("Failed to find RSDP signature\n"); return 0; } if (found_rsdp->Revision == ACPI_VER_1) { if (!acpi_validate_rsdp_checksum(found_rsdp)) { set_color(VGA_COLOR_RED); printf("RSDP has an invalid checksum\n"); return 0; } ctx->rsdp = found_rsdp; ctx->xsdp = 0; if (!acpi_validate_sdt_checksum((struct ACPISDTHeader *)found_rsdp->RsdtAddress)) { set_color(VGA_COLOR_RED); printf("RSDT has an invalid checksum\n"); return 0; } ctx->rsdt = (struct rsdt*)found_rsdp->RsdtAddress; } else if (found_rsdp->Revision == ACPI_VER_OTHER) { set_color(VGA_COLOR_RED); printf("ACPI versions higher than 1.0 are not yet supported because I'm lazy\n"); return 0; } else { set_color(VGA_COLOR_RED); printf("Invalid RSDP\n"); return 0; } printf("[KERNEL] Using ACPI v1.0\n"); struct fadt *fadt = acpi_locate_sdt(ctx->rsdt, "FACP"); if (!fadt) { set_color(VGA_COLOR_RED); printf("Failed to find FADT\n"); return 0; } printf("[KERNEL] Found FADT at 0x%x\n", fadt); if (fadt->Flags & 1) printf("[KERNEL] Legacy devices are supported\n"); else { /* set_color(VGA_COLOR_RED); printf("Legacy devices are not supported. I'm too lazy to support modern devices, bye bye.\n"); goto halt; */ } return 1; }