From 2c0d74e8e8303a902498ed62762d4fb008f0c008 Mon Sep 17 00:00:00 2001 From: Nate Lawson Date: Tue, 25 May 2004 05:52:48 +0000 Subject: [PATCH] Use the correct location of the EBDA for searching for the RSDP. The EBDA is the 1 KB area addressed by the 16 bit pointer at 0x40E. Pointed out by: robert.moore AT intel.com --- sys/boot/i386/libi386/biosacpi.c | 16 ++++++----- usr.sbin/acpi/acpidump/acpi_user.c | 46 +++++++++++++++++++----------- usr.sbin/acpi/acpidump/acpidump.h | 4 +-- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/sys/boot/i386/libi386/biosacpi.c b/sys/boot/i386/libi386/biosacpi.c index c8ee1c7c46d1..f9b2d774b054 100644 --- a/sys/boot/i386/libi386/biosacpi.c +++ b/sys/boot/i386/libi386/biosacpi.c @@ -84,22 +84,24 @@ biosacpi_detect(void) } /* - * Find the RSDP in low memory. + * Find the RSDP in low memory. See section 5.2.2 of the ACPI spec. */ static RSDP_DESCRIPTOR * biosacpi_find_rsdp(void) { RSDP_DESCRIPTOR *rsdp; + uint16_t *addr; - /* search the EBDA */ - if ((rsdp = biosacpi_search_rsdp((char *)0, 0x400)) != NULL) - return(rsdp); + /* EBDA is the 1 KB addressed by the 16 bit pointer at 0x40E. */ + addr = (uint16_t *)0x40E; + if ((rsdp = biosacpi_search_rsdp((char *)(*addr << 4), 0x400)) != NULL) + return (rsdp); - /* search the BIOS space */ + /* Check the upper memory BIOS space, 0xe0000 - 0xfffff. */ if ((rsdp = biosacpi_search_rsdp((char *)0xe0000, 0x20000)) != NULL) - return(rsdp); + return (rsdp); - return(NULL); + return (NULL); } static RSDP_DESCRIPTOR * diff --git a/usr.sbin/acpi/acpidump/acpi_user.c b/usr.sbin/acpi/acpidump/acpi_user.c index 7bb2d0af0b63..2166e884c800 100644 --- a/usr.sbin/acpi/acpidump/acpi_user.c +++ b/usr.sbin/acpi/acpidump/acpi_user.c @@ -121,6 +121,34 @@ acpi_get_rsdp(u_long addr) return (acpi_map_physical(addr, len)); } +static struct ACPIrsdp * +acpi_scan_rsd_ptr(void) +{ +#if defined(__i386__) + struct ACPIrsdp *rsdp; + u_long addr, end; + + /* + * 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 (1 KB area addressed by the 16 bit pointer at 0x40E + * 2. High memory (0xE0000 - 0xFFFFF) + */ + addr = RSDP_EBDA_PTR; + pread(acpi_mem_fd, &addr, sizeof(uint16_t), addr); + addr <<= 4; + end = addr + RSDP_EBDA_SIZE; + for (; addr < 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 /* __i386__ */ + return (NULL); +} + /* * Public interfaces */ @@ -143,23 +171,7 @@ acpi_find_rsd_ptr(void) machdep_acpi_root); } -#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 (NULL); + return (acpi_scan_rsd_ptr()); } void * diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h index e3256181cd53..6cd7a8e7b18a 100644 --- a/usr.sbin/acpi/acpidump/acpidump.h +++ b/usr.sbin/acpi/acpidump/acpidump.h @@ -299,8 +299,8 @@ struct ECDTbody { * 1. EBDA (0x0 - 0x3FF) * 2. High memory (0xE0000 - 0xFFFFF) */ -#define RSDP_EBDA_START 0 -#define RSDP_EBDA_END (0x400 - sizeof(struct ACPIrsdp)) +#define RSDP_EBDA_PTR 0x40E +#define RSDP_EBDA_SIZE (1024 - sizeof(struct ACPIrsdp)) #define RSDP_HI_START 0xE0000 #define RSDP_HI_END (0x100000 - sizeof(struct ACPIrsdp))