#include #include #include #include static bool checksum_rsdp(const struct rsdp *rsdp) { size_t chksm = 0; for (uint8_t *byte = (uint8_t*) rsdp; byte < (uint8_t*)rsdp + sizeof(*rsdp); byte++) chksm += *byte; return (chksm & 0xFF) == 0; } static bool checksum_xsdp(const struct xsdp *rsdp) { return true; size_t chksm = 0; for (uint8_t *byte = (uint8_t*) rsdp; byte < (uint8_t*)rsdp + sizeof(*rsdp); byte++) chksm += *byte; return (chksm & 0xFF) == 0; } static bool checksum_sdt(const struct acpi_sdt_header *header) { uint8_t chksm = 0; for (size_t i = 0; i < header->len; i++) { chksm += ((int8_t *) header)[i]; } return chksm == 0; } void print_rsdp(const struct rsdp *rsdp) { vga_puts("sig: "); vga_putsn(rsdp->signature, 8); vga_putc('\n'); vga_puts("checksum: "); vga_putn(rsdp->checksum); vga_putc(' '); vga_puts(checksum_rsdp(rsdp) ? "PASS" : "FAIL"); vga_putc('\n'); vga_puts("oem id: "); vga_putsn(rsdp->oemid, 6); vga_putc('\n'); vga_puts("revision: "); vga_putn(rsdp->revision); vga_putc('\n'); vga_puts("addr: "); vga_putx(rsdp->rsdt_address); vga_putc('\n'); } struct fadt *find_facp(struct xsdt *root_sdt) { if (root_sdt == NULL) return NULL; size_t entries = (root_sdt->header.len - sizeof(root_sdt->header)) / 4; for (size_t i = 0; i < entries; i++) { struct acpi_sdt_header *header = (struct acpi_sdt_header *) root_sdt->sdt_pointers[i]; if (memcmp(header->signature, "FACP", 4) == 0 && checksum_sdt(header)) { return (struct fadt *) header; } } return NULL; } struct xsdp *find_rsdp() { struct xsdp *rsdp = NULL; char *ebda = (char*)((uintptr_t) *(uint16_t *)0x40e << 4); for (char *ptr = ebda; ptr < ebda + 128; ptr += 16) { if (memcmp(ptr, "RSD PTR ", 8) == 0 && checksum_xsdp((struct xsdp*) ptr)) { rsdp = (struct xsdp *) ptr; } } for (char *ptr = (char*)0x000E0000; ptr < (char*)0x000FFFFF; ptr += 16) { if (memcmp(ptr, "RSD PTR ", 8) == 0 && checksum_xsdp((struct xsdp*) ptr)) { if (rsdp == NULL) rsdp = (struct xsdp *) ptr; } } //print_rsdp(rsdp); return rsdp; }