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:
parent
b666b593eb
commit
8fc0f4c675
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129230
@ -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 ((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 *
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user