summaryrefslogtreecommitdiff
path: root/src/arch/x86
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2017-10-17 14:33:05 -0600
committerAaron Durbin <adurbin@chromium.org>2017-10-18 19:56:21 +0000
commitf46a9a0d3ad3157de3e354b4314fe9c5c3b69dd2 (patch)
tree44a006b52578155e632db4b7304cb61bb486e850 /src/arch/x86
parentc672043766dabc2bbaebc770fb20e0f63e5eedcb (diff)
arch/x86: restore forwarding table on resume for EARLY_EBDA_INIT
In commit c06a3f72 (arch/x86: initialize EBDA in S3 and S0/S5 path) the BDA and EBDA are wiped in the resume path. However, the coreboot table forwarding entry wasn't taken into account so that was wiped which resulted in cbmem not working on the resume path. Fix this by stashing the forwarding table in cbmem and restoring it on the resume path. Change-Id: I142503535a78635fbb1c698fc7d032c1a2921813 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: https://review.coreboot.org/22078 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Matt DeVillier <matt.devillier@gmail.com> Reviewed-by: Furquan Shaikh <furquan@google.com>
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/tables.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/arch/x86/tables.c b/src/arch/x86/tables.c
index 7b06550cc5..fc5870d9f4 100644
--- a/src/arch/x86/tables.c
+++ b/src/arch/x86/tables.c
@@ -18,6 +18,7 @@
#include <console/console.h>
#include <cpu/cpu.h>
#include <bootmem.h>
+#include <bootstate.h>
#include <boot/tables.h>
#include <boot/coreboot_tables.h>
#include <arch/pirq_routing.h>
@@ -194,7 +195,45 @@ static unsigned long write_smbios_table(unsigned long rom_table_end)
* in case our data structures grow beyond 0x400. Only GDT
* and the coreboot table use low_tables.
*/
-static uintptr_t forwarding_table = 0x500;
+#define FORWARDING_TABLE_ADDR ((uintptr_t)0x500)
+static uintptr_t forwarding_table = FORWARDING_TABLE_ADDR;
+
+/*
+ * For EARLY_EBDA_INIT the BDA area will be wiped on the resume path which
+ * has the forwarding table entry. Therefore, when tables are written an
+ * entry is placed in cbmem that can be restored on OS resume to the proper
+ * location.
+ */
+static void stash_forwarding_table(uintptr_t addr, size_t sz)
+{
+ void *cbmem_addr = cbmem_add(CBMEM_ID_CBTABLE_FWD, sz);
+
+ if (cbmem_addr == NULL) {
+ printk(BIOS_ERR, "Unable to allocate CBMEM forwarding entry.\n");
+ return;
+ }
+
+ memcpy(cbmem_addr, (void *)addr, sz);
+}
+
+#if IS_ENABLED(CONFIG_EARLY_EBDA_INIT)
+static void restore_forwarding_table(void *dest)
+{
+ const struct cbmem_entry *fwd_entry;
+
+ fwd_entry = cbmem_entry_find(CBMEM_ID_CBTABLE_FWD);
+
+ if (fwd_entry == NULL) {
+ printk(BIOS_ERR, "Unable to restore CBMEM forwarding entry.\n");
+ return;
+ }
+
+ memcpy(dest, cbmem_entry_start(fwd_entry), cbmem_entry_size(fwd_entry));
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY,
+ restore_forwarding_table, (void *)FORWARDING_TABLE_ADDR);
+#endif
void arch_write_tables(uintptr_t coreboot_table)
{
@@ -217,6 +256,9 @@ void arch_write_tables(uintptr_t coreboot_table)
sz = write_coreboot_forwarding_table(forwarding_table, coreboot_table);
+ if (IS_ENABLED(CONFIG_EARLY_EBDA_INIT))
+ stash_forwarding_table(forwarding_table, sz);
+
forwarding_table += sz;
/* Align up to page boundary for historical consistency. */
forwarding_table = ALIGN_UP(forwarding_table, 4*KiB);