From f46a9a0d3ad3157de3e354b4314fe9c5c3b69dd2 Mon Sep 17 00:00:00 2001 From: Aaron Durbin Date: Tue, 17 Oct 2017 14:33:05 -0600 Subject: 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 Reviewed-on: https://review.coreboot.org/22078 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Furquan Shaikh --- src/arch/x86/tables.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'src/arch/x86/tables.c') 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 #include #include +#include #include #include #include @@ -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); -- cgit v1.2.3