Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36291 )
Change subject: lib/romstage_handoff: Add methods to pass on romstage information ......................................................................
lib/romstage_handoff: Add methods to pass on romstage information
Add 2 generic function that can be used to pass on information from romstage to ramstage. The implementation is such that the saving can be done even if cbmem is not set up initially.
TODO: Does it need guarding because it needlessly increases .bss usage?
Change-Id: I71bbe1b776cbc74468a6218b315894602b6152ba Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/commonlib/include/commonlib/cbmem_id.h M src/include/romstage_handoff.h M src/lib/romstage_handoff.c 3 files changed, 79 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/91/36291/1
diff --git a/src/commonlib/include/commonlib/cbmem_id.h b/src/commonlib/include/commonlib/cbmem_id.h index 30bf88a..89d9478 100644 --- a/src/commonlib/include/commonlib/cbmem_id.h +++ b/src/commonlib/include/commonlib/cbmem_id.h @@ -77,6 +77,7 @@ #define CBMEM_ID_ROM2 0x524f4d32 #define CBMEM_ID_ROM3 0x524f4d33 #define CBMEM_ID_FMAP 0x464d4150 +#define CBMEM_ID_ROMSTAGE_SAVE 0xa7d1f2f3
#define CBMEM_ID_TO_NAME_TABLE \ { CBMEM_ID_ACPI, "ACPI " }, \ diff --git a/src/include/romstage_handoff.h b/src/include/romstage_handoff.h index db998ec..bbb0869 100644 --- a/src/include/romstage_handoff.h +++ b/src/include/romstage_handoff.h @@ -21,4 +21,11 @@ /* Return 1 if resuming or 0 if not. */ int romstage_handoff_is_resume(void);
+/* Returns 0 on success, 1 if the info was copied to a buffer to be migrated + to cbmem later on, < 0 on failure. */ +int save_romstage_info(void *info, size_t info_size); + +/* Return 0 on success, else < 0 on failure */ +int get_romstage_info(void *info, size_t info_size); + #endif /* ROMSTAGE_HANDOFF_H */ diff --git a/src/lib/romstage_handoff.c b/src/lib/romstage_handoff.c index 04ead0a..2f26194 100644 --- a/src/lib/romstage_handoff.c +++ b/src/lib/romstage_handoff.c @@ -77,3 +77,74 @@
return handoff->s3_resume; } + +static u8 save_buffer[256]; +static size_t used_buffer_size; +static int is_migrated; + +static void migrate_save_buffer(int is_recovery) +{ + if (used_buffer_size) + printk(BIOS_DEBUG, "Migrating the romstage save buffer to cbmem\n"); + is_migrated = 1; + save_romstage_info(save_buffer, used_buffer_size); +} + +ROMSTAGE_CBMEM_INIT_HOOK(migrate_save_buffer); + +int save_romstage_info(void *info, size_t save_size) +{ + const struct cbmem_entry *e; + + printk(BIOS_SPEW, "Romstage save: saving %p, size %zu\n", + info, save_size); + + e = cbmem_entry_find(CBMEM_ID_ROMSTAGE_SAVE); + if (e != NULL) { + if (cbmem_entry_size(e) > save_size) { + memcpy(cbmem_entry_start(e), info, save_size); + return 0; + } + cbmem_entry_remove(e); + } + + e = cbmem_entry_add(CBMEM_ID_ROMSTAGE_SAVE, save_size); + if (e == NULL && is_migrated) { + printk(BIOS_ERR, "Can't copy romstage save buffer to cbmem!\n"); + return -1; + } + + if (e != NULL) { + memcpy(cbmem_entry_start(e), info, save_size); + return 0; + } + + /* Cbmem is not yet up, save it for later */ + printk(BIOS_SPEW, "Romstage save: cbmem not yet up, saving info buffer for later\n"); + if (sizeof(save_buffer) < save_size) { + printk(BIOS_ERR, "Romstage save: buffer too small!\n"); + return -1; + } + memcpy(save_buffer, info, save_size); + used_buffer_size = save_size; + return 1; +} + +int get_romstage_info(void *info, size_t save_size) +{ + const struct cbmem_entry *e; + e = cbmem_entry_find(CBMEM_ID_ROMSTAGE_SAVE); + + if (e == NULL) { + printk(BIOS_ERR, "Can't find romstage save\n"); + return -1; + } + + if (save_size > cbmem_entry_size(e)) { + printk(BIOS_ERR, "Romstage save: requested size too large!\n"); + return -1; + } + + memcpy(info, cbmem_entry_start(e), save_size); + return 0; +}