diff options
author | Ji Luo <ji.luo@nxp.com> | 2020-05-11 11:47:46 +0800 |
---|---|---|
committer | Ji Luo <ji.luo@nxp.com> | 2020-05-15 17:34:38 +0800 |
commit | f388e3aaeb1cf8ce1d55280927ead5c357a57336 (patch) | |
tree | ab4cfb074e4339663a6b86a4d35951f6a94c1748 /lib | |
parent | ba0ab383e1ea5331c83879b45eb0a37dbbcefa06 (diff) |
MA-15814 Check 'successful_boot' flag before marking unbootable
Slot will be marked as "unbootable" state if error happens during
image load/verify process, this may cause the board never boot up
if some random failures happen (like eMMC/DRAM access error at some
critical temperature).
Check the "successful_boot" flag before marking the slot as "unbootable",
this will help ease the "no bootable slot" issue.
Test: slot switch on imx8qm_mek.
Signed-off-by: Ji Luo <ji.luo@nxp.com>
(cherry picked from commit 6db8ebe2224ab6656e8e798288bd1b3c0472c0c0)
Change-Id: Ib060b11cc6687a3bacd09cecda7dd925beba6316
Diffstat (limited to 'lib')
-rw-r--r-- | lib/avb/fsl/fsl_avb_ab_flow.c | 76 |
1 files changed, 50 insertions, 26 deletions
diff --git a/lib/avb/fsl/fsl_avb_ab_flow.c b/lib/avb/fsl/fsl_avb_ab_flow.c index c93a2427e3..bd56af0fb6 100644 --- a/lib/avb/fsl/fsl_avb_ab_flow.c +++ b/lib/avb/fsl/fsl_avb_ab_flow.c @@ -388,11 +388,19 @@ int mmc_load_image_raw_sector_dual_uboot(struct spl_image_info *spl_image, /* Set current slot to unbootable if load/verify fail. */ if (ret != 0) { - printf("Load or verify bootloader%s fail, setting unbootable..\n", - slot_suffixes[target_slot]); - fsl_slot_set_unbootable(&ab_data.slots[target_slot]); - /* Switch to another slot. */ - target_slot = (target_slot == 1 ? 0 : 1); + /* Reboot if current slot has booted succefully before, this prevents + * slot been marked as "unbootable" due to some random failures (like + * eMMC/DRAM access error at some critical temperature). + */ + if (ab_data.slots[target_slot].successful_boot) + do_reset(NULL, 0, 0, NULL); + else { + printf("Load or verify bootloader%s fail, setting unbootable..\n", + slot_suffixes[target_slot]); + fsl_slot_set_unbootable(&ab_data.slots[target_slot]); + /* Switch to another slot. */ + target_slot = (target_slot == 1 ? 0 : 1); + } } else { slot_index_to_boot = target_slot; n = 2; @@ -651,20 +659,28 @@ AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops, } if (set_slot_unbootable) { - avb_errorv("Error verifying slot ", - slot_suffixes[target_slot], - " with result ", - avb_slot_verify_result_to_string(verify_result), - " - setting unbootable.\n", - NULL); - fsl_slot_set_unbootable(&ab_data.slots[target_slot]); - - /* Only the slot chosen by SPL will be verified here so we - * return AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS if the - * slot should be set unbootable. + /* Reboot if current slot has booted succefully before, this prevents + * slot been marked as "unbootable" due to some random failures (like + * eMMC/DRAM access error at some critical temperature). */ - ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS; - goto out; + if (ab_data.slots[target_slot].successful_boot) + do_reset(NULL, 0, 0, NULL); + else { + avb_errorv("Error verifying slot ", + slot_suffixes[target_slot], + " with result ", + avb_slot_verify_result_to_string(verify_result), + " - setting unbootable.\n", + NULL); + fsl_slot_set_unbootable(&ab_data.slots[target_slot]); + + /* Only the slot chosen by SPL will be verified here so we + * return AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS if the + * slot should be set unbootable. + */ + ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS; + goto out; + } } /* Update stored rollback index only when the slot has been marked @@ -969,14 +985,22 @@ AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops, } if (set_slot_unbootable) { - avb_errorv("Error verifying slot ", - slot_suffixes[target_slot], - " with result ", - avb_slot_verify_result_to_string(verify_result), - " - setting unbootable.\n", - NULL); - fsl_slot_set_unbootable(&ab_data.slots[target_slot]); - set_slot_unbootable = false; + /* Reboot if current slot has booted succefully before, this prevents + * slot been marked as "unbootable" due to some random failures (like + * eMMC/DRAM access error at some critical temperature). + */ + if (ab_data.slots[target_slot].successful_boot) + do_reset(NULL, 0, 0, NULL); + else { + avb_errorv("Error verifying slot ", + slot_suffixes[target_slot], + " with result ", + avb_slot_verify_result_to_string(verify_result), + " - setting unbootable.\n", + NULL); + fsl_slot_set_unbootable(&ab_data.slots[target_slot]); + set_slot_unbootable = false; + } } /* switch to another slot */ target_slot = (target_slot == 1 ? 0 : 1); |