From 00d3053746bd51db407ad1c407a9b662d068e93c Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Thu, 19 Dec 2002 08:06:53 +0000 Subject: [PATCH] o Use sysctl machdep.acpi_root to get the physical address of the RSDP. Scan the first 1MB on i386 if the sysctl fails, o Extend struct ACPIrsdp with the ACPI 2.0 fields which involves changing a prior reserved field into the ACPI revision, o Only calculate the RSDP checksum on the first 20 bytes to remain compatible with ACPI 1.0 tables; we don't check the extended checksum covering the whole table, o Use the length field in the RSDP to map the RSDP into the address space so that we don't have to know about future extensions here. --- usr.sbin/acpi/acpidump/acpi.c | 2 +- usr.sbin/acpi/acpidump/acpi_user.c | 45 ++++++++++++++++++++++-------- usr.sbin/acpi/acpidump/acpidump.c | 2 +- usr.sbin/acpi/acpidump/acpidump.h | 8 ++++-- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c index da5c3861b52b..daba8a23eaa1 100644 --- a/usr.sbin/acpi/acpidump/acpi.c +++ b/usr.sbin/acpi/acpidump/acpi.c @@ -327,7 +327,7 @@ acpi_print_rsd_ptr(struct ACPIrsdp *rp) printf(BEGIN_COMMENT); printf("RSD PTR: Checksum=%d, OEMID=", rp->sum); acpi_print_string(rp->oem, 6); - printf(", RsdtAddress=0x%08x\n", rp->addr); + printf(", RsdtAddress=0x%08x\n", rp->rsdt_addr); printf(END_COMMENT); } diff --git a/usr.sbin/acpi/acpidump/acpi_user.c b/usr.sbin/acpi/acpidump/acpi_user.c index c6a8d997053f..8361ef68a168 100644 --- a/usr.sbin/acpi/acpidump/acpi_user.c +++ b/usr.sbin/acpi/acpidump/acpi_user.c @@ -41,6 +41,8 @@ #include "acpidump.h" +static char machdep_acpi_root[] = "machdep.acpi_root"; + static int acpi_mem_fd = -1; struct acpi_user_mapping { @@ -98,23 +100,42 @@ acpi_user_find_mapping(vm_offset_t pa, size_t size) struct ACPIrsdp * acpi_find_rsd_ptr() { - int i; - u_int8_t buf[sizeof(struct ACPIrsdp)]; + struct ACPIrsdp rsdp; + u_long addr; + int len; 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(struct ACPIrsdp) - 16); - /* Verify checksum before accepting it. */ - if (acpi_checksum(buf, sizeof(struct ACPIrsdp))) - continue; - return (acpi_map_physical(i, sizeof(struct ACPIrsdp))); - } + len = sizeof(addr); + if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) { + pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr); + if (memcmp(rsdp.signature, "RSD PTR ", 8)) + errx(1, "sysctl %s does not point to RSDP\n", + machdep_acpi_root); + len = 20; /* size of ACPI 1.0 table */ + if (acpi_checksum(&rsdp, len)) + warnx("RSDP has invalid checksum\n"); + if (rsdp.revision > 0) + len = rsdp.length; + return (acpi_map_physical(addr, len)); } +#if !defined(__ia64__) + for (addr = 0UL; addr < 1024UL * 1024UL; addr += 16UL) { + pread(acpi_mem_fd, &rsdp, 8, addr); + if (memcmp(rsdp.signature, "RSD PTR ", 8)) + continue; + /* Read the entire table. */ + pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr); + len = 20; /* size of ACPI 1.0 table */ + if (acpi_checksum(&rsdp, len)) + continue; + if (rsdp.revision > 0) + len = rsdp.length; + return (acpi_map_physical(addr, len)); + } +#endif + return (0); } diff --git a/usr.sbin/acpi/acpidump/acpidump.c b/usr.sbin/acpi/acpidump/acpidump.c index a68756868976..df6ce1f61e5f 100644 --- a/usr.sbin/acpi/acpidump/acpidump.c +++ b/usr.sbin/acpi/acpidump/acpidump.c @@ -58,7 +58,7 @@ asl_dump_from_devmem() errx(1, "Can't find ACPI information\n"); acpi_print_rsd_ptr(rp); - rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->addr); + rsdp = (struct ACPIsdt *) acpi_map_sdt(rp->rsdt_addr); if (memcmp(rsdp->signature, "RSDT", 4) || acpi_checksum(rsdp, rsdp->len)) errx(1, "RSDT is corrupted\n"); diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h index 796246ec3530..49d28efeec3e 100644 --- a/usr.sbin/acpi/acpidump/acpidump.h +++ b/usr.sbin/acpi/acpidump/acpidump.h @@ -51,8 +51,12 @@ struct ACPIrsdp { u_char signature[8]; u_char sum; u_char oem[6]; - u_char res; - u_int32_t addr; + u_char revision; + u_int32_t rsdt_addr; + u_int32_t length; + u_int64_t xsdt_addr; + u_char xsum; + u_char _reserved_[3]; } __packed; /* System Description Table */