diff options
-rw-r--r-- | src/arch/x86/tables.c | 44 | ||||
-rw-r--r-- | src/commonlib/include/commonlib/cbmem_id.h | 2 |
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 " }, \ |