diff mbox series

[05/10] imx: imx8qm/qxp: Recover SPL data section for partition reboot

Message ID 20200505122846.15992-6-peng.fan@nxp.com
State Accepted
Commit 6aead23323bee1d780fd0b9696f512194458e379
Headers show
Series imx: imx8qm/qxp update | expand

Commit Message

Peng Fan May 5, 2020, 12:28 p.m. UTC
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 at nxp.com>
Signed-off-by: Peng Fan <peng.fan at nxp.com>
---
 arch/arm/cpu/armv8/Kconfig        |  6 ++++++
 arch/arm/cpu/armv8/Makefile       |  4 ++++
 arch/arm/cpu/armv8/spl_data.c     | 29 +++++++++++++++++++++++++++++
 arch/arm/cpu/armv8/u-boot-spl.lds |  8 ++++++++
 arch/arm/mach-imx/imx8/Kconfig    |  2 ++
 arch/arm/mach-imx/imx8/cpu.c      |  5 +++++
 include/spl.h                     |  1 +
 7 files changed, 55 insertions(+)
 create mode 100644 arch/arm/cpu/armv8/spl_data.c

Comments

Stefano Babic May 11, 2020, 10:17 a.m. UTC | #1
> 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 at nxp.com>
> Signed-off-by: Peng Fan <peng.fan at nxp.com>
Applied to u-boot-imx, master, thanks !

Best regards,
Stefano Babic
diff mbox series

Patch

diff --git a/arch/arm/cpu/armv8/Kconfig b/arch/arm/cpu/armv8/Kconfig
index 16c83e8614..3655990772 100644
--- a/arch/arm/cpu/armv8/Kconfig
+++ b/arch/arm/cpu/armv8/Kconfig
@@ -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
diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
index b349b13f49..2e48df0eb9 100644
--- a/arch/arm/cpu/armv8/Makefile
+++ b/arch/arm/cpu/armv8/Makefile
@@ -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
index 0000000000..8fd986a67a
--- /dev/null
+++ b/arch/arm/cpu/armv8/spl_data.c
@@ -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++;
+}
diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds
index ccbf359bd1..0e67ab09d7 100644
--- a/arch/arm/cpu/armv8/u-boot-spl.lds
+++ b/arch/arm/cpu/armv8/u-boot-spl.lds
@@ -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*)));
diff --git a/arch/arm/mach-imx/imx8/Kconfig b/arch/arm/mach-imx/imx8/Kconfig
index 69149d3cd5..9d1f73dfc7 100644
--- a/arch/arm/mach-imx/imx8/Kconfig
+++ b/arch/arm/mach-imx/imx8/Kconfig
@@ -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
diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c
index 3bd0dee025..e03193cb4c 100644
--- a/arch/arm/mach-imx/imx8/cpu.c
+++ b/arch/arm/mach-imx/imx8/cpu.c
@@ -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;
 
diff --git a/include/spl.h b/include/spl.h
index 6bf9fd8beb..90395fedb0 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -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