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.
This commit is contained in:
Nate Lawson 2004-05-14 16:52:39 +00:00
parent b666b593eb
commit 8fc0f4c675
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129230
2 changed files with 53 additions and 29 deletions

View File

@ -92,51 +92,64 @@ acpi_user_find_mapping(vm_offset_t pa, size_t size)
return (map); 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 * Public interfaces
*/ */
struct ACPIrsdp * struct ACPIrsdp *
acpi_find_rsd_ptr(void) acpi_find_rsd_ptr(void)
{ {
struct ACPIrsdp rsdp; struct ACPIrsdp *rsdp;
u_long addr; u_long addr;
size_t len; size_t len;
acpi_user_init(); acpi_user_init();
/* Attempt to use sysctl to find RSD PTR record */ /* Attempt to use sysctl to find RSD PTR record. */
len = sizeof(addr); len = sizeof(addr);
if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) { if (sysctlbyname(machdep_acpi_root, &addr, &len, NULL, 0) == 0) {
pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr); if ((rsdp = acpi_get_rsdp(addr)) != NULL)
if (memcmp(rsdp.signature, "RSD PTR ", 8) != 0) return (rsdp);
errx(1, "sysctl %s does not point to RSDP", else
machdep_acpi_root); warnx("sysctl %s does not point to RSDP",
len = 20; /* size of ACPI 1.0 table */ machdep_acpi_root);
if (acpi_checksum(&rsdp, len))
warnx("RSDP has invalid checksum");
if (rsdp.revision > 0)
len = rsdp.length;
return (acpi_map_physical(addr, len));
} }
#if !defined(__ia64__) && !defined(__amd64__) #if defined(__i386__)
/* On ia32, scan physical memory for RSD PTR if above failed */ /*
for (addr = 0UL; addr < 1024UL * 1024UL; addr += 16UL) { * On ia32, scan physical memory for the RSD PTR if above failed.
pread(acpi_mem_fd, &rsdp, 8, addr); * According to section 5.2.2 of the ACPI spec, we only consider
if (memcmp(rsdp.signature, "RSD PTR ", 8)) * two regions for the base address:
continue; * 1. EBDA (0x0 - 0x3FF)
/* Read the entire table. */ * 2. High memory (0xE0000 - 0xFFFFF)
pread(acpi_mem_fd, &rsdp, sizeof(rsdp), addr); */
len = 20; /* size of ACPI 1.0 table */ for (addr = RSDP_EBDA_START; addr < RSDP_EBDA_END; addr += 16)
if (acpi_checksum(&rsdp, len)) if ((rsdp = acpi_get_rsdp(addr)) != NULL)
continue; return (rsdp);
if (rsdp.revision > 0) for (addr = RSDP_HI_START; addr < RSDP_HI_END; addr += 16)
len = rsdp.length; if ((rsdp = acpi_get_rsdp(addr)) != NULL)
return (acpi_map_physical(addr, len)); return (rsdp);
}
#endif #endif
return (0); return (NULL);
} }
void * void *

View File

@ -293,6 +293,17 @@ struct ECDTbody {
u_char ec_id[1]; /* Variable length name string */ u_char ec_id[1]; /* Variable length name string */
} __packed; } __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 */ /* Find and map the RSD PTR structure and return it for parsing */
struct ACPIsdt *sdt_load_devmem(void); struct ACPIsdt *sdt_load_devmem(void);