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:
Marcel Moolenaar 2002-12-19 08:06:53 +00:00
parent 24c9ad6bed
commit 00d3053746
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=108082
4 changed files with 41 additions and 16 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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");

View File

@ -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 */