/* * Public interfaces */ ACPI_TABLE_RSDP * acpi_find_rsd_ptr(void) { ACPI_TABLE_RSDP *rsdp; char buf[20]; u_long addr; size_t len; acpi_user_init(); addr = 0; /* Attempt to use kenv or sysctl to find RSD PTR record. */ if (kenv(KENV_GET, hint_acpi_0_rsdp, buf, 20) == 0) addr = strtoul(buf, NULL, 0); if (addr == 0) { len = sizeof(addr); if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) != 0) addr = 0; } if (addr != 0 && (rsdp = acpi_get_rsdp(addr)) != NULL) return (rsdp); return (acpi_scan_rsd_ptr()); }
int acpi_detect(void) { struct ACPIrsdp *rp; struct ACPIsdt *rsdp; u_long addr; size_t len; if (!acpi0_present()) { warnx("no acpi0 device located"); return -1; } acpi_user_init(); /* Attempt to use sysctl to find RSD PTR record. */ len = sizeof(addr); if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) != 0) { warnx("cannot find ACPI information"); return -1; } rp = acpi_get_rsdp(addr); if (rp == NULL) { warnx("cannot find ACPI information: sysctl %s does not point to RSDP", machdep_acpi_root); return -1; } if (rp->revision < 2) { rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->rsdt_addr); if (memcmp(rsdp->signature, "RSDT", 4) != 0 || acpi_checksum(rsdp, rsdp->len) != 0) errx(1, "RSDT is corrupted"); addr_size = sizeof(uint32_t); } else { rsdp = (struct ACPIsdt *)acpi_map_sdt(rp->xsdt_addr); if (memcmp(rsdp->signature, "XSDT", 4) != 0 || acpi_checksum(rsdp, rsdp->len) != 0) errx(1, "XSDT is corrupted"); addr_size = sizeof(uint64_t); } ncpu = 0; acpi_handle_rsdt(rsdp); return (ncpu == 0 ? 1 : ncpu); }
/* * Public interfaces */ ACPI_TABLE_RSDP * acpi_find_rsd_ptr(void) { int i; uint8_t buf[sizeof(ACPI_TABLE_RSDP)]; acpi_user_init(); for (i = 0; i < 1024 * 1024; i += 16) { read(acpi_mem_fd, buf, 16); if (!memcmp(buf, "RSD PTR ", 8)) { /* Read the rest of the structure */ read(acpi_mem_fd, buf + 16, sizeof(ACPI_TABLE_RSDP) - 16); /* Verify checksum before accepting it. */ if (acpi_checksum(buf, sizeof(ACPI_TABLE_RSDP))) continue; return (acpi_map_physical(i, sizeof(ACPI_TABLE_RSDP))); } } return acpi_scan_rsd_ptr(); }