summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fallback.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/fallback.c b/fallback.c
index c006cc58..12e8064c 100644
--- a/fallback.c
+++ b/fallback.c
@@ -9,6 +9,8 @@
#include "shim.h"
+#define NO_REBOOT L"FB_NO_REBOOT"
+
EFI_LOADED_IMAGE *this_image = NULL;
int
@@ -971,6 +973,65 @@ try_start_first_option(EFI_HANDLE parent_image_handle)
return efi_status;
}
+static UINT32
+get_fallback_no_reboot(void)
+{
+ EFI_STATUS efi_status;
+ UINT32 no_reboot;
+ UINTN size = sizeof(UINT32);
+
+ efi_status = gRT->GetVariable(NO_REBOOT, &SHIM_LOCK_GUID,
+ NULL, &size, &no_reboot);
+ if (!EFI_ERROR(efi_status)) {
+ return no_reboot;
+ }
+ return 0;
+}
+
+static EFI_STATUS
+set_fallback_no_reboot(void)
+{
+ EFI_STATUS efi_status;
+ UINT32 no_reboot = 1;
+ efi_status = gRT->SetVariable(NO_REBOOT, &SHIM_LOCK_GUID,
+ EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(UINT32), &no_reboot);
+ return efi_status;
+}
+
+static int
+draw_countdown(void)
+{
+ CHAR16 *title = L"Boot Option Restoration";
+ CHAR16 *message = L"Press any key to stop system reset";
+ int timeout;
+
+ timeout = console_countdown(title, message, 5);
+
+ return timeout;
+}
+
+static int
+get_user_choice(void)
+{
+ int choice;
+ CHAR16 *title[] = {L"Boot Option Restored", NULL};
+ CHAR16 *menu_strings[] = {
+ L"Reset system",
+ L"Continue boot",
+ L"Always continue boot",
+ NULL
+ };
+
+ do {
+ choice = console_select(title, menu_strings, 0);
+ } while (choice < 0 || choice > 2);
+
+ return choice;
+}
+
extern EFI_STATUS
efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab);
@@ -1037,6 +1098,26 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
VerbosePrint(L"tpm not present, starting the first image\n");
try_start_first_option(image);
} else {
+ if (get_fallback_no_reboot() == 1) {
+ VerbosePrint(L"NO_REBOOT is set, starting the first image\n");
+ try_start_first_option(image);
+ }
+
+ int timeout = draw_countdown();
+ if (timeout == 0)
+ goto reset;
+
+ int choice = get_user_choice();
+ if (choice == 0) {
+ goto reset;
+ } else if (choice == 2) {
+ efi_status = set_fallback_no_reboot();
+ if (EFI_ERROR(efi_status))
+ goto reset;
+ }
+ VerbosePrint(L"tpm present, starting the first image\n");
+ try_start_first_option(image);
+reset:
VerbosePrint(L"tpm present, resetting system\n");
}