diff options
author | njl <njl@FreeBSD.org> | 2004-05-14 16:52:39 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2004-05-14 16:52:39 +0000 |
commit | adf833a8306dc102a42f8a38e1037c6c0600d2e7 (patch) | |
tree | 607275475e588141db00040e313fd90478719185 /usr.sbin/acpi | |
parent | 9e176d6b088944d5708b4305e1dd373cd544708a (diff) | |
download | FreeBSD-src-adf833a8306dc102a42f8a38e1037c6c0600d2e7.zip FreeBSD-src-adf833a8306dc102a42f8a38e1037c6c0600d2e7.tar.gz |
Instead of scanning the entire lower 1 MB of RAM, only scan locations
where the RSD PTR can actually occur. According to section 5.2.2
of the ACPI spec, we only consider two regions for the base address:
1. EBDA (0x0 - 0x3FF)
2. High memory (0xE0000 - 0xFFFFF)
I don't know whether this fixes any actual problems but is more correct.
Diffstat (limited to 'usr.sbin/acpi')
-rw-r--r-- | usr.sbin/acpi/acpidump/acpi_user.c | 71 | ||||
-rw-r--r-- | usr.sbin/acpi/acpidump/acpidump.h | 11 |
2 files changed, 53 insertions, 29 deletions
diff --git a/usr.sbin/acpi/acpidump/acpi_user.c b/usr.sbin/acpi/acpidump/acpi_user.c index de1f1a5..a8e56a6 100644 --- a/usr.sbin/acpi/acpidump/acpi_user.c +++ b/usr.sbin/acpi/acpidump/acpi_user.c @@ -92,51 +92,64 @@ acpi_user_find_mapping(vm_offset_t pa, size_t size) return (map); } +static struct ACPIrsdp * +acpi_get_rsdp(u_long addr) +{ + struct ACPIrsdp rsdp; + size_t len; + + pread(acpi_mem_fd, &rsdp, 8, addr); + if (memcmp(rsdp.signature, "RSD PTR ", 8)) + return (NULL); + /* Read the entire table. */ + len = sizeof(rsdp); + pread(acpi_mem_fd, &rsdp, len, addr); + if (acpi_checksum(&rsdp, len)) + return (NULL); + if (rsdp.revision > 0) + len = rsdp.length; + return (acpi_map_physical(addr, len)); +} + /* * Public interfaces */ struct ACPIrsdp * acpi_find_rsd_ptr(void) { - struct ACPIrsdp rsdp; + struct ACPIrsdp *rsdp; u_long addr; size_t len; acpi_user_init(); - /* Attempt to use sysctl to find RSD PTR record */ + /* Attempt to use sysctl to find RSD PTR record. */ 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) != 0) - errx(1, "sysctl %s does not point to RSDP", - machdep_acpi_root); - len = 20; /* size of ACPI 1.0 table */ - if (acpi_checksum(&rsdp, len)) - warnx("RSDP has invalid checksum"); - if (rsdp.revision > 0) - len = rsdp.length; - return (acpi_map_physical(addr, len)); + if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) { + if ((rsdp = acpi_get_rsdp(addr)) != NULL) + return (rsdp); + else + warnx("sysctl %s does not point to RSDP", + machdep_acpi_root); } -#if !defined(__ia64__) && !defined(__amd64__) - /* On ia32, scan physical memory for RSD PTR if above failed */ - 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)); - } +#if defined(__i386__) + /* + * On ia32, scan physical memory for the RSD PTR if above failed. + * According to section 5.2.2 of the ACPI spec, we only consider + * two regions for the base address: + * 1. EBDA (0x0 - 0x3FF) + * 2. High memory (0xE0000 - 0xFFFFF) + */ + for (addr = RSDP_EBDA_START; addr < RSDP_EBDA_END; addr += 16) + if ((rsdp = acpi_get_rsdp(addr)) != NULL) + return (rsdp); + for (addr = RSDP_HI_START; addr < RSDP_HI_END; addr += 16) + if ((rsdp = acpi_get_rsdp(addr)) != NULL) + return (rsdp); #endif - return (0); + return (NULL); } void * diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h index 30508ee..e325618 100644 --- a/usr.sbin/acpi/acpidump/acpidump.h +++ b/usr.sbin/acpi/acpidump/acpidump.h @@ -293,6 +293,17 @@ struct ECDTbody { u_char ec_id[1]; /* Variable length name string */ } __packed; +/* + * Addresses to scan on ia32 for the RSD PTR. According to section 5.2.2 + * of the ACPI spec, we only consider two regions for the base address: + * 1. EBDA (0x0 - 0x3FF) + * 2. High memory (0xE0000 - 0xFFFFF) + */ +#define RSDP_EBDA_START 0 +#define RSDP_EBDA_END (0x400 - sizeof(struct ACPIrsdp)) +#define RSDP_HI_START 0xE0000 +#define RSDP_HI_END (0x100000 - sizeof(struct ACPIrsdp)) + /* Find and map the RSD PTR structure and return it for parsing */ struct ACPIsdt *sdt_load_devmem(void); |