x86: Support saving MRC data 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. Add a
function to handle that.
Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/arch/x86/include/asm/mrccache.h b/arch/x86/include/asm/mrccache.h
index 04783cd..40fda85 100644
--- a/arch/x86/include/asm/mrccache.h
+++ b/arch/x86/include/asm/mrccache.h
@@ -103,4 +103,15 @@
*/
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 2a89198..f37a732 100644
--- a/arch/x86/lib/mrccache.c
+++ b/arch/x86/lib/mrccache.c
@@ -159,18 +159,11 @@
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 @@
/* 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 @@
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();
+}