summaryrefslogtreecommitdiffstats
path: root/usr.sbin/acpi
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-05-14 16:52:39 +0000
committernjl <njl@FreeBSD.org>2004-05-14 16:52:39 +0000
commitadf833a8306dc102a42f8a38e1037c6c0600d2e7 (patch)
tree607275475e588141db00040e313fd90478719185 /usr.sbin/acpi
parent9e176d6b088944d5708b4305e1dd373cd544708a (diff)
downloadFreeBSD-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.c71
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.h11
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);
OpenPOWER on IntegriCloud