diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2013-09-29 08:35:23 +0300 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2013-10-03 16:25:18 +0300 |
commit | c656bd8bb04abdec8256d1ba0014bc5159a861bc (patch) | |
tree | bf3204b3be68981e3a3f6f2aad4a1636ff671627 | |
parent | d15a0bf4d9bc5926f4dbee86f21007717c16b7d6 (diff) | |
download | seabios-c656bd8bb04abdec8256d1ba0014bc5159a861bc.tar.gz |
biostables: support looking up RSDP
Will be used when it's loaded from QEMU.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r-- | src/fw/biostables.c | 41 | ||||
-rw-r--r-- | src/util.h | 1 |
2 files changed, 35 insertions, 7 deletions
diff --git a/src/fw/biostables.c b/src/fw/biostables.c index a3ee827..c7d498d 100644 --- a/src/fw/biostables.c +++ b/src/fw/biostables.c @@ -60,22 +60,35 @@ copy_mptable(void *pos) memcpy((void*)newpos + length, (void*)p->physaddr, mpclength); } -static void -copy_acpi_rsdp(void *pos) +static int +get_acpi_rsdp_length(void *pos, unsigned size) { - if (RsdpAddr) - return; struct rsdp_descriptor *p = pos; if (p->signature != RSDP_SIGNATURE) - return; + return -1; u32 length = 20; + if (length > size) + return -1; if (checksum(pos, length) != 0) - return; + return -1; if (p->revision > 1) { length = p->length; + if (length > size) + return -1; if (checksum(pos, length) != 0) - return; + return -1; } + return length; +} + +static void +copy_acpi_rsdp(void *pos) +{ + if (RsdpAddr) + return; + int length = get_acpi_rsdp_length(pos, -1); + if (length < 0) + return; void *newpos = malloc_fseg(length); if (!newpos) { warn_noalloc(); @@ -118,3 +131,17 @@ copy_table(void *pos) copy_acpi_rsdp(pos); copy_smbios(pos); } + +void *find_acpi_rsdp(void) +{ + extern u8 zonefseg_start[], zonefseg_end[]; + unsigned long start = (unsigned long)zonefseg_start; + unsigned long end = (unsigned long)zonefseg_end; + unsigned long pos; + + for (pos = ALIGN(start, 0x10); pos <= ALIGN_DOWN(end, 0x10); pos += 0x10) + if (get_acpi_rsdp_length((void *)pos, end - pos) >= 0) + return (void *)pos; + + return NULL; +} @@ -72,6 +72,7 @@ void acpi_reboot(void); // fw/biostable.c void copy_smbios(void *pos); void copy_table(void *pos); +void *find_acpi_rsdp(void); // fw/coreboot.c extern const char *CBvendor, *CBpart; |