diff --git a/kernel-src/arch/x86-64/acpi.c b/kernel-src/arch/x86-64/acpi.c index ce071525..596b3196 100644 --- a/kernel-src/arch/x86-64/acpi.c +++ b/kernel-src/arch/x86-64/acpi.c @@ -37,43 +37,46 @@ void *arch_acpi_findtable(char *sig, int n) { return NULL; } +static void *map_table(void *physical) { + // TODO map according to header length entry + uintmax_t pageoffset = (uintptr_t)physical % PAGE_SIZE; + void *virt = vmm_map(NULL, PAGE_SIZE * 16, VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC, physical); + __assert(virt); + return (void *)((uintptr_t)virt + pageoffset); +} + void arch_acpi_init() { // FIXME search if no response __assert(rsdpreq.response); - rsdp_t *rsdp = rsdpreq.response->address; - uintmax_t pageoffset = (uintptr_t)rsdp % PAGE_SIZE; - - // map rsdp - // make sure it doesn't cross a page boundary - // TODO support this - __assert(ROUND_DOWN((uintptr_t)rsdp, PAGE_SIZE) == ROUND_DOWN((uintptr_t)rsdp - 1 + sizeof(rsdp_t), PAGE_SIZE)); - - void *virt = vmm_map(NULL, sizeof(rsdp_t), VMM_FLAGS_PHYSICAL, ARCH_MMU_FLAGS_READ | ARCH_MMU_FLAGS_NOEXEC, FROM_HHDM(rsdp)); - __assert(virt); - rsdp = (rsdp_t *)((uintptr_t)virt + pageoffset); + rsdp_t *rsdp = map_table(FROM_HHDM(rsdpreq.response->address)); if (rsdp->revision == 0) { - printf("\e[93mACPI version 1.0 -- Using RSDT instead of XSDT.\e[0m\n"); - rsdt_t *rsdt = MAKE_HHDM((rsdt_t *)(uint64_t)rsdp->rsdt); + printf("\e[93macpi: version 1.0 -- Using RSDT instead of XSDT.\e[0m\n"); + rsdt_t *rsdt = map_table((void *)(uint64_t)rsdp->rsdt); __assert(arch_acpi_checksumok(rsdt)); + headercount = (rsdt->header.length - sizeof(sdtheader_t)) / sizeof(uint32_t); headers = alloc(sizeof(sdtheader_t *) * headercount); __assert(headers); + // TODO map according to the header length entry for (size_t i = 0; i < headercount; ++i) { - void *addr = MAKE_HHDM((void *)(uint64_t)rsdt->tables[i]); + // map it + void *addr = map_table((void *)(uint64_t)rsdt->tables[i]); if (arch_acpi_checksumok(addr)) headers[i] = addr; } } else { - xsdt_t *xsdt = MAKE_HHDM((xsdt_t *)rsdp->xsdt); + xsdt_t *xsdt = map_table((void *)rsdp->xsdt); __assert(arch_acpi_checksumok(xsdt)); + headercount = (xsdt->header.length - sizeof(sdtheader_t)) / sizeof(uint64_t); headers = alloc(sizeof(sdtheader_t *) * headercount); __assert(headers); for (size_t i = 0; i < headercount; ++i) { - void *addr = MAKE_HHDM((void *)xsdt->tables[i]); + // map it + void *addr = map_table((void *)xsdt->tables[i]); if (arch_acpi_checksumok(addr)) headers[i] = addr; }