[SeaBIOS] [PATCH] coreboot: update memory table before handling execution to payload/system
Krystian Hebel
krystian.hebel at 3mdeb.com
Mon Nov 5 13:27:10 CET 2018
SeaBIOS modifies its internal e820 structure, but does not propagate
these changes back to coreboot tables. This resulted in multiple errors
in MemTest86 when run on 2 GB platforms, probably because of some
memory-mapped devices.
This patch copies back modified e820 tables before booting an OS or
a payload.
Change-Id: I16a3f059695717daedb1e997ce4e62018c7e02b3
Signed-off-by: Krystian Hebel <krystian.hebel at 3mdeb.com>
---
src/e820map.c | 2 ++
src/e820map.h | 2 ++
src/fw/coreboot.c | 50 +++++++++++++++++++++++++++++++++++++++++++----
3 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/src/e820map.c b/src/e820map.c
index 39445cf6399d..2d2de6094b14 100644
--- a/src/e820map.c
+++ b/src/e820map.c
@@ -148,5 +148,7 @@ e820_remove(u64 start, u64 size)
void
e820_prepboot(void)
{
+ // Synchronize memory maps.
+ coreboot_update_memtable();
dump_map();
}
diff --git a/src/e820map.h b/src/e820map.h
index de8b523003c5..78bf1ce76572 100644
--- a/src/e820map.h
+++ b/src/e820map.h
@@ -23,4 +23,6 @@ void e820_prepboot(void);
extern struct e820entry e820_list[];
extern int e820_count;
+extern void coreboot_update_memtable(void);
+
#endif // e820map.h
diff --git a/src/fw/coreboot.c b/src/fw/coreboot.c
index 7c0954b5398c..aa07baad3a7f 100644
--- a/src/fw/coreboot.c
+++ b/src/fw/coreboot.c
@@ -189,10 +189,6 @@ coreboot_preinit(void)
e820_add(m->start, m->size, type);
}
- // Ughh - coreboot likes to set a map at 0x0000-0x1000, but this
- // confuses grub. So, override it.
- e820_add(0, 16*1024, E820_RAM);
-
struct cb_cbmem_ref *cbref = find_cb_subtable(cbh, CB_TAG_CBMEM_CONSOLE);
if (cbref) {
cbcon = (void*)(u32)cbref->cbmem_addr;
@@ -567,3 +563,49 @@ cbfs_payload_setup(void)
boot_add_cbfs(cfile->fhdr, desc, bootprio_find_named_rom(filename, 0));
}
}
+
+// Mirror changes done on e820 to coreboot tables.
+void
+coreboot_update_memtable(void)
+{
+ if (!CONFIG_COREBOOT)
+ return;
+
+ // Find coreboot table.
+ struct cb_header *cbh = find_cb_table();
+ if (!cbh) {
+ dprintf(1, "Unable to find coreboot table!\n");
+ return;
+ }
+ char *end = (char *)cbh + sizeof(*cbh) + cbh->table_bytes;
+ dprintf(3, "Now attempting to find coreboot memory map\n");
+ struct cb_memory *dst = find_cb_subtable(cbh, CB_TAG_MEMORY);
+ if (!dst) {
+ dprintf(1, "Unable to find coreboot memory table!\n");
+ return;
+ }
+
+ // Remove old memory table, overwriting it with following subtables
+ // and append an updated memory table to the end.
+ u32 old_size = dst->size;
+ char *src = (char *)dst + old_size;
+ memcpy(dst, src, (end - src));
+ dst = (struct cb_memory *)(end - old_size);
+ u32 new_size = e820_count * sizeof(struct e820entry);
+ dst->tag = CB_TAG_MEMORY;
+ // Tables are binary compatible, except that CB_MEM_TABLE became
+ // E820_RESERVED.
+ memcpy((char*)dst + sizeof(struct cb_memory), e820_list, new_size);
+ new_size += sizeof(struct cb_memory);
+ dst->size = new_size;
+
+ // Update header fields (size and checksum).
+ cbh->table_bytes += new_size - old_size;
+ cbh->table_checksum = ipchksum((char*)cbh + sizeof(*cbh), cbh->table_bytes);
+ cbh->header_checksum = 0;
+ cbh->header_checksum = ipchksum((char*)cbh, sizeof(*cbh));
+
+ // Ughh - coreboot likes to set a map at 0x0000-0x1000, but this
+ // confuses grub. So, override it in e820 only.
+ e820_add(0, 16*1024, E820_RAM);
+}
--
2.17.1
More information about the SeaBIOS
mailing list