aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2013-09-29 08:35:23 +0300
committerMichael S. Tsirkin <mst@redhat.com>2013-10-03 16:25:18 +0300
commitc656bd8bb04abdec8256d1ba0014bc5159a861bc (patch)
treebf3204b3be68981e3a3f6f2aad4a1636ff671627
parentd15a0bf4d9bc5926f4dbee86f21007717c16b7d6 (diff)
downloadseabios-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.c41
-rw-r--r--src/util.h1
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;
+}
diff --git a/src/util.h b/src/util.h
index 880c04a..bf983e5 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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;