Commit c7a3cec998ac419ad715a5f19bcb845ab3703811

Authored by Ji Luo
1 parent 8b4b7d98f8

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

Showing 1 changed file with 50 additions and 26 deletions Side-by-side Diff

lib/avb/fsl/fsl_avb_ab_flow.c
... ... @@ -388,11 +388,19 @@
388 388  
389 389 /* Set current slot to unbootable if load/verify fail. */
390 390 if (ret != 0) {
391   - printf("Load or verify bootloader%s fail, setting unbootable..\n",
392   - slot_suffixes[target_slot]);
393   - fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
394   - /* Switch to another slot. */
395   - target_slot = (target_slot == 1 ? 0 : 1);
  391 + /* Reboot if current slot has booted succefully before, this prevents
  392 + * slot been marked as "unbootable" due to some random failures (like
  393 + * eMMC/DRAM access error at some critical temperature).
  394 + */
  395 + if (ab_data.slots[target_slot].successful_boot)
  396 + do_reset(NULL, 0, 0, NULL);
  397 + else {
  398 + printf("Load or verify bootloader%s fail, setting unbootable..\n",
  399 + slot_suffixes[target_slot]);
  400 + fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
  401 + /* Switch to another slot. */
  402 + target_slot = (target_slot == 1 ? 0 : 1);
  403 + }
396 404 } else {
397 405 slot_index_to_boot = target_slot;
398 406 n = 2;
399 407  
... ... @@ -651,20 +659,28 @@
651 659 }
652 660  
653 661 if (set_slot_unbootable) {
654   - avb_errorv("Error verifying slot ",
655   - slot_suffixes[target_slot],
656   - " with result ",
657   - avb_slot_verify_result_to_string(verify_result),
658   - " - setting unbootable.\n",
659   - NULL);
660   - fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
661   -
662   - /* Only the slot chosen by SPL will be verified here so we
663   - * return AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS if the
664   - * slot should be set unbootable.
  662 + /* Reboot if current slot has booted succefully before, this prevents
  663 + * slot been marked as "unbootable" due to some random failures (like
  664 + * eMMC/DRAM access error at some critical temperature).
665 665 */
666   - ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
667   - goto out;
  666 + if (ab_data.slots[target_slot].successful_boot)
  667 + do_reset(NULL, 0, 0, NULL);
  668 + else {
  669 + avb_errorv("Error verifying slot ",
  670 + slot_suffixes[target_slot],
  671 + " with result ",
  672 + avb_slot_verify_result_to_string(verify_result),
  673 + " - setting unbootable.\n",
  674 + NULL);
  675 + fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
  676 +
  677 + /* Only the slot chosen by SPL will be verified here so we
  678 + * return AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS if the
  679 + * slot should be set unbootable.
  680 + */
  681 + ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
  682 + goto out;
  683 + }
668 684 }
669 685  
670 686 /* Update stored rollback index only when the slot has been marked
... ... @@ -969,14 +985,22 @@
969 985 }
970 986  
971 987 if (set_slot_unbootable) {
972   - avb_errorv("Error verifying slot ",
973   - slot_suffixes[target_slot],
974   - " with result ",
975   - avb_slot_verify_result_to_string(verify_result),
976   - " - setting unbootable.\n",
977   - NULL);
978   - fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
979   - set_slot_unbootable = false;
  988 + /* Reboot if current slot has booted succefully before, this prevents
  989 + * slot been marked as "unbootable" due to some random failures (like
  990 + * eMMC/DRAM access error at some critical temperature).
  991 + */
  992 + if (ab_data.slots[target_slot].successful_boot)
  993 + do_reset(NULL, 0, 0, NULL);
  994 + else {
  995 + avb_errorv("Error verifying slot ",
  996 + slot_suffixes[target_slot],
  997 + " with result ",
  998 + avb_slot_verify_result_to_string(verify_result),
  999 + " - setting unbootable.\n",
  1000 + NULL);
  1001 + fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
  1002 + set_slot_unbootable = false;
  1003 + }
980 1004 }
981 1005 /* switch to another slot */
982 1006 target_slot = (target_slot == 1 ? 0 : 1);