acpi: don't rely on acpi tables being mapped

This commit is contained in:
Matheus
2024-07-27 23:57:24 -03:00
parent 803724141e
commit cbc3fc645e
+19 -16
View File
@@ -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;
}