x86: Support saving MRC data from SPL
authorSimon Glass <sjg@chromium.org>
Fri, 26 Apr 2019 03:58:57 +0000 (21:58 -0600)
committerBin Meng <bmeng.cn@gmail.com>
Wed, 8 May 2019 05:02:14 +0000 (13:02 +0800)
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>
arch/x86/include/asm/mrccache.h
arch/x86/lib/mrccache.c

index 04783cd329271cc7f8fbd364d6f02cfa8a6e7a08..40fda856ff47f9fcce92ecc2faf4b95eb833998a 100644 (file)
@@ -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 */
index 2a8919885b7d96416815c0190bcf9688acb75f0a..f37a732a45cc52f7b7de707db2347d2c1f82826f 100644 (file)
@@ -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();
+}