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.
This commit is contained in:
parent
24c9ad6bed
commit
00d3053746
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user