static void * map_table(vm_paddr_t pa, int offset, const char *sig) { ACPI_TABLE_HEADER *header; vm_offset_t length; void *table; header = pmap_mapbios(pa, sizeof(ACPI_TABLE_HEADER)); if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) { pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER)); return (NULL); } length = header->Length; pmap_unmapbios((vm_offset_t)header, sizeof(ACPI_TABLE_HEADER)); table = pmap_mapbios(pa, length); if (ACPI_FAILURE(AcpiTbChecksum(table, length))) { if (bootverbose) printf("ACPI: Failed checksum for table %s\n", sig); #if (ACPI_CHECKSUM_ABORT) pmap_unmapbios(table, length); return (NULL); #endif } return (table); }
/* Unmap a table previously mapped via acpi_map_table(). */ void acpi_unmap_table(void *table) { ACPI_TABLE_HEADER *header; header = (ACPI_TABLE_HEADER *)table; pmap_unmapbios((vm_offset_t)table, header->Length); }
/* * Free data structures allocated during acpi_pxm_init. */ void acpi_pxm_free(void) { if (srat_physaddr == 0) return; pmap_unmapbios((vm_offset_t)cpus, sizeof(*cpus) * max_cpus); srat_physaddr = 0; cpus = NULL; }
/* * See if a given ACPI table is the requested table. Returns the * length of the able if it matches or zero on failure. */ static int probe_table(vm_paddr_t address, const char *sig) { ACPI_TABLE_HEADER *table; table = pmap_mapbios(address, sizeof(ACPI_TABLE_HEADER)); if (table == NULL) { if (bootverbose) printf("ACPI: Failed to map table at 0x%jx\n", (uintmax_t)address); return (0); } if (bootverbose) printf("Table '%.4s' at 0x%jx\n", table->Signature, (uintmax_t)address); if (strncmp(table->Signature, sig, ACPI_NAME_SIZE) != 0) { pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER)); return (0); } pmap_unmapbios((vm_offset_t)table, sizeof(ACPI_TABLE_HEADER)); return (1); }
/* Check BIOS date. If 1998 or older, disable ACPI. */ int acpi_machdep_quirks(int *quirks) { char *va; int year; /* BIOS address 0xffff5 contains the date in the format mm/dd/yy. */ va = pmap_mapbios(0xffff0, 16); sscanf(va + 11, "%2d", &year); pmap_unmapbios((vm_offset_t)va, 16); /* * Date must be >= 1/1/1999 or we don't trust ACPI. Note that this * check must be changed by my 114th birthday. */ if (year > 90 && year < 99) *quirks = ACPI_Q_BROKEN; return (0); }
void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length) { pmap_unmapbios((vm_offset_t)LogicalAddress, Length); }
/* * Return the physical address of the requested table or zero if one * is not found. */ vm_paddr_t acpi_find_table(const char *sig) { ACPI_PHYSICAL_ADDRESS rsdp_ptr; ACPI_TABLE_RSDP *rsdp; ACPI_TABLE_XSDT *xsdt; ACPI_TABLE_HEADER *table; vm_paddr_t addr; int i, count; if (resource_disabled("acpi", 0)) return (0); /* * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn * calls pmap_mapbios() to find the RSDP, we assume that we can use * pmap_mapbios() to map the RSDP. */ if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) return (0); rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); if (rsdp == NULL) { if (bootverbose) printf("ACPI: Failed to map RSDP\n"); return (0); } addr = 0; if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { /* * AcpiOsGetRootPointer only verifies the checksum for * the version 1.0 portion of the RSDP. Version 2.0 has * an additional checksum that we verify first. */ if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { if (bootverbose) printf("ACPI: RSDP failed extended checksum\n"); return (0); } xsdt = map_table(rsdp->XsdtPhysicalAddress, 2, ACPI_SIG_XSDT); if (xsdt == NULL) { if (bootverbose) printf("ACPI: Failed to map XSDT\n"); pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); return (0); } count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / sizeof(UINT64); for (i = 0; i < count; i++) if (probe_table(xsdt->TableOffsetEntry[i], sig)) { addr = xsdt->TableOffsetEntry[i]; break; } acpi_unmap_table(xsdt); } pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); if (addr == 0) { if (bootverbose) printf("ACPI: No %s table found\n", sig); return (0); } if (bootverbose) printf("%s: Found table at 0x%jx\n", sig, (uintmax_t)addr); /* * Verify that we can map the full table and that its checksum is * correct, etc. */ table = map_table(addr, 0, sig); if (table == NULL) return (0); acpi_unmap_table(table); return (addr); }