aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/google/chromeos/vboot2/recovery.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/google/chromeos/vboot2/recovery.c')
-rw-r--r--src/vendorcode/google/chromeos/vboot2/recovery.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/vendorcode/google/chromeos/vboot2/recovery.c b/src/vendorcode/google/chromeos/vboot2/recovery.c
index 2cd5e806ea..94a8cc3f37 100644
--- a/src/vendorcode/google/chromeos/vboot2/recovery.c
+++ b/src/vendorcode/google/chromeos/vboot2/recovery.c
@@ -14,6 +14,7 @@
*/
#include <assert.h>
+#include <bootstate.h>
#include <rules.h>
#include <string.h>
#include <vb2_api.h>
@@ -32,6 +33,39 @@ static int vb2_get_recovery_reason_shared_data(void)
return sd->recovery_reason;
}
+void vb2_save_recovery_reason_vbnv(void)
+{
+ if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT))
+ return;
+
+ int reason = vb2_get_recovery_reason_shared_data();
+ if (!reason)
+ return;
+
+ set_recovery_mode_into_vbnv(reason);
+}
+
+static void vb2_clear_recovery_reason_vbnv(void *unused)
+{
+ if (!IS_ENABLED(CONFIG_VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT))
+ return;
+
+ set_recovery_mode_into_vbnv(0);
+}
+
+/*
+ * Recovery reason stored in VBNV needs to be cleared before the state of VBNV
+ * is backed-up anywhere or jumping to the payload (whichever occurs
+ * first). Currently, vbnv_cmos.c backs up VBNV on POST_DEVICE. Thus, we need to
+ * make sure that the stored recovery reason is cleared off before that
+ * happens.
+ * IMPORTANT: Any reboot occurring after BS_DEV_INIT state will cause loss of
+ * recovery reason on reboot. Until now, we have seen reboots occuring on x86
+ * only in FSP stages which run before BS_DEV_INIT.
+ */
+BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT,
+ vb2_clear_recovery_reason_vbnv, NULL);
+
/*
* Returns 0 for the stages where we know that cbmem does not come online.
* Even if this function returns 1 for romstage, depending upon the point in