imx: imx8qm/qxp: Recover SPL data section for partition reboot
authorPeng Fan <peng.fan@nxp.com>
Tue, 5 May 2020 12:28:41 +0000 (20:28 +0800)
committerStefano Babic <sbabic@denx.de>
Sun, 10 May 2020 18:55:20 +0000 (20:55 +0200)
When doing partition reboot, the boot image won't be reloaded by ROM,
it is just CPU reset to boot entry. The SW has to keep the boot image
inside the RAM unchanged. It includes both the TEXT section and DATA
section.

For SPL, the problem is DATA section will be updated at runtime, so in
next partition reboot the data is not same as the initial value from
cold boot. If any code depends on the initial value, then it will have
problem.

This patch introduces a mechanism to recover the data section
for partition reboot. It adds a new section in image for saving
data section. When from cold boot, the data section will be saved
to that new section at SPL early phase. When from partition reboot,
the data section will be restored from the new section.

Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
arch/arm/cpu/armv8/Kconfig
arch/arm/cpu/armv8/Makefile
arch/arm/cpu/armv8/spl_data.c [new file with mode: 0644]
arch/arm/cpu/armv8/u-boot-spl.lds
arch/arm/mach-imx/imx8/Kconfig
arch/arm/mach-imx/imx8/cpu.c
include/spl.h

index 16c83e86149a752e4c539b9febef4b6da15e0ea4..3655990772c012bc456aee5cbcb8a52117845c12 100644 (file)
@@ -76,6 +76,12 @@ config SPL_ARMV8_SEC_FIRMWARE_SUPPORT
        help
          Say Y here to support this framework in SPL phase.
 
+config SPL_RECOVER_DATA_SECTION
+       bool "save/restore SPL data section"
+       help
+         Say Y here to save SPL data section for cold boot, and restore
+         at warm boot in SPL phase.
+
 config SEC_FIRMWARE_ARMV8_PSCI
        bool "PSCI implementation in secure monitor firmware"
        depends on ARMV8_SEC_FIRMWARE_SUPPORT || SPL_ARMV8_SEC_FIRMWARE_SUPPORT
index b349b13f497a2caa01da8751de0955ef62ff7912..2e48df0eb981c418112af04c5cd4b7bbdac968d3 100644 (file)
@@ -30,6 +30,10 @@ obj-$(CONFIG_ARMV8_SPIN_TABLE) += spin_table.o spin_table_v8.o
 endif
 obj-$(CONFIG_$(SPL_)ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_asm.o
 
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_SPL_RECOVER_DATA_SECTION) += spl_data.o
+endif
+
 obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/
 obj-$(CONFIG_S32V234) += s32v234/
 obj-$(CONFIG_TARGET_HIKEY) += hisilicon/
diff --git a/arch/arm/cpu/armv8/spl_data.c b/arch/arm/cpu/armv8/spl_data.c
new file mode 100644 (file)
index 0000000..8fd986a
--- /dev/null
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2020 NXP
+ */
+
+#include <common.h>
+#include <spl.h>
+
+char __data_save_start[0] __section(.__data_save_start);
+char __data_save_end[0] __section(.__data_save_end);
+
+u32 cold_reboot_flag = 1;
+
+void spl_save_restore_data(void)
+{
+       u32 data_size = __data_save_end - __data_save_start;
+
+       if (cold_reboot_flag == 1) {
+               /* Save data section to data_save section */
+               memcpy(__data_save_start, __data_save_start - data_size,
+                      data_size);
+       } else {
+               /* Restore the data_save section to data section */
+               memcpy(__data_save_start - data_size, __data_save_start,
+                      data_size);
+       }
+
+       cold_reboot_flag++;
+}
index ccbf359bd11d7951d37f589787caa21a877b03f8..0e67ab09d77aee609059ad7eca00f4f1ae3ec11f 100644 (file)
@@ -38,6 +38,14 @@ SECTIONS
                *(.data*)
        } >.sram
 
+#ifdef CONFIG_SPL_RECOVER_DATA_SECTION
+       .data_save : {
+               *(.__data_save_start)
+               . = SIZEOF(.data);
+               *(.__data_save_end)
+       } >.sram
+#endif
+
        .u_boot_list : {
                . = ALIGN(8);
                KEEP(*(SORT(.u_boot_list*)));
index 69149d3cd51cf4041e00a4b77b0dfd807e236a6d..9d1f73dfc7063c53a5ca1ccdf7f7528b40909220 100644 (file)
@@ -18,11 +18,13 @@ config MU_BASE_SPL
 config IMX8QM
        select IMX8
        select SUPPORT_SPL
+       select SPL_RECOVER_DATA_SECTION
        bool
 
 config IMX8QXP
        select IMX8
        select SUPPORT_SPL
+       select SPL_RECOVER_DATA_SECTION
        bool
 
 config SYS_SOC
index 3bd0dee0251f0615e4a64ae6da62922619afffe2..e03193cb4cad3fb77824fca53718c41749e6cb23 100644 (file)
@@ -13,6 +13,7 @@
 #include <dm/lists.h>
 #include <dm/uclass.h>
 #include <errno.h>
+#include <spl.h>
 #include <thermal.h>
 #include <asm/arch/sci/sci.h>
 #include <asm/arch/sys_proto.h>
@@ -39,6 +40,10 @@ struct pass_over_info_t *get_pass_over_info(void)
 
 int arch_cpu_init(void)
 {
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION)
+       spl_save_restore_data();
+#endif
+
 #ifdef CONFIG_SPL_BUILD
        struct pass_over_info_t *pass_over;
 
index 6bf9fd8bebb6de440909c785cf3ba4cc4865308b..90395fedb0fd35e0d2b5ceb52295dca81334580b 100644 (file)
@@ -582,4 +582,5 @@ void spl_perform_fixups(struct spl_image_info *spl_image);
  */
 struct image_header *spl_get_load_buffer(ssize_t offset, size_t size);
 
+void spl_save_restore_data(void);
 #endif