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>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
(cherry picked from commit
9e406ea46a93013b4b5370d0d45fe892e9f52583)
*(.data*)
} >.sram
+#ifdef CONFIG_RECOVER_SPL_DATA_SECTION
+ .data_save : {
+ *(.__data_save_start)
+ . = SIZEOF(.data);
+ *(.__data_save_end)
+ } >.sram
+#endif
+
.u_boot_list : {
. = ALIGN(8);
KEEP(*(SORT(.u_boot_list*)));
if ARCH_IMX8
+config RECOVER_SPL_DATA_SECTION
+ bool
+ help
+ Save SPL DATA section for cold boot, restore at warm boot
+
config IMX_SMMU
bool "Enable SMMU on i.MX8"
help
config IMX8QM
select IMX8
select SUPPORT_SPL
+ select RECOVER_SPL_DATA_SECTION
bool
config IMX8QXP
select IMX8
select SUPPORT_SPL
+ select RECOVER_SPL_DATA_SECTION
bool
config SYS_SOC
return p;
}
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_RECOVER_SPL_DATA_SECTION)
+char __data_save_start[0] __attribute__((section(".__data_save_start")));
+char __data_save_end[0] __attribute__((section(".__data_save_end")));
+
+u32 cold_reboot_flag = 1;
+
+static void 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++;
+}
+#endif
+
int arch_cpu_init(void)
{
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_RECOVER_SPL_DATA_SECTION)
+ save_restore_data();
+#endif
+
#ifdef CONFIG_SPL_BUILD
struct pass_over_info_t *pass_over;