diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h index 04783cd329271cc7f8fbd364d6f02cfa8a6e7a08..40fda856ff47f9fcce92ecc2faf4b95eb833998a 100644 --- a/arch/x86/include/asm/mrccache.h +++ b/arch/x86/include/asm/mrccache.h @@ -103,4 +103,15 @@ int mrccache_get_region(struct udevice **devp, struct mrc_region *entry); */ int mrccache_save(void); +/** + * mrccache_spl_save() - Save to the MRC region from SPL + * + * When SPL is used to set up the memory controller we want to save the MRC + * data in SPL to avoid needing to pass it up to U-Boot proper to save. This + * function handles that. + * + * @return 0 if saved to SPI flash successfully, other error if failed + */ +int mrccache_spl_save(void); + #endif /* _ASM_MRCCACHE_H */ diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c index 2a8919885b7d96416815c0190bcf9688acb75f0a..f37a732a45cc52f7b7de707db2347d2c1f82826f 100644 --- a/arch/x86/lib/mrccache.c +++ b/arch/x86/lib/mrccache.c @@ -159,18 +159,11 @@ int mrccache_update(struct udevice *sf, struct mrc_region *entry, return 0; } -int mrccache_reserve(void) +static void mrccache_setup(void *data) { - struct mrc_data_container *cache; + struct mrc_data_container *cache = data; u16 checksum; - if (!gd->arch.mrc_output_len) - return 0; - - /* adjust stack pointer to store pure cache data plus the header */ - gd->start_addr_sp -= (gd->arch.mrc_output_len + MRC_DATA_HEADER_SIZE); - cache = (struct mrc_data_container *)gd->start_addr_sp; - cache->signature = MRC_DATA_SIGNATURE; cache->data_size = gd->arch.mrc_output_len; checksum = compute_ip_checksum(gd->arch.mrc_output, cache->data_size); @@ -182,6 +175,16 @@ int mrccache_reserve(void) /* gd->arch.mrc_output now points to the container */ gd->arch.mrc_output = (char *)cache; +} + +int mrccache_reserve(void) +{ + if (!gd->arch.mrc_output_len) + return 0; + + /* adjust stack pointer to store pure cache data plus the header */ + gd->start_addr_sp -= (gd->arch.mrc_output_len + MRC_DATA_HEADER_SIZE); + mrccache_setup((void *)gd->start_addr_sp); gd->start_addr_sp &= ~0xf; @@ -256,3 +259,18 @@ err_entry: debug("%s: Failed: %d\n", __func__, ret); return ret; } + +int mrccache_spl_save(void) +{ + void *data; + int size; + + size = gd->arch.mrc_output_len + MRC_DATA_HEADER_SIZE; + data = malloc(size); + if (!data) + return log_msg_ret("Allocate MRC cache block", -ENOMEM); + mrccache_setup(data); + gd->arch.mrc_output = data; + + return mrccache_save(); +}