aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/arch/x86/tables.c44
-rw-r--r--src/commonlib/include/commonlib/cbmem_id.h2
2 files changed, 45 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);
diff --git a/src/commonlib/include/commonlib/cbmem_id.h b/src/commonlib/include/commonlib/cbmem_id.h
index 2c9b3c3600..2595655b4d 100644
--- a/src/commonlib/include/commonlib/cbmem_id.h
+++ b/src/commonlib/include/commonlib/cbmem_id.h
@@ -25,6 +25,7 @@
#define CBMEM_ID_AMDMCT_MEMINFO 0x494D454E
#define CBMEM_ID_CAR_GLOBALS 0xcac4e6a3
#define CBMEM_ID_CBTABLE 0x43425442
+#define CBMEM_ID_CBTABLE_FWD 0x43425443
#define CBMEM_ID_CONSOLE 0x434f4e53
#define CBMEM_ID_COVERAGE 0x47434f56
#define CBMEM_ID_EHCI_DEBUG 0xe4c1deb9
@@ -80,6 +81,7 @@
{ CBMEM_ID_AMDMCT_MEMINFO, "AMDMEM INFO" }, \
{ CBMEM_ID_CAR_GLOBALS, "CAR GLOBALS" }, \
{ CBMEM_ID_CBTABLE, "COREBOOT " }, \
+ { CBMEM_ID_CBTABLE_FWD, "COREBOOTFWD" }, \
{ CBMEM_ID_CONSOLE, "CONSOLE " }, \
{ CBMEM_ID_COVERAGE, "COVERAGE " }, \
{ CBMEM_ID_EHCI_DEBUG, "USBDEBUG " }, \