summaryrefslogtreecommitdiff
path: root/firmware/2lib/2ui_screens.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/2lib/2ui_screens.c')
-rw-r--r--firmware/2lib/2ui_screens.c208
1 files changed, 200 insertions, 8 deletions
diff --git a/firmware/2lib/2ui_screens.c b/firmware/2lib/2ui_screens.c
index ca492039..356b3bfb 100644
--- a/firmware/2lib/2ui_screens.c
+++ b/firmware/2lib/2ui_screens.c
@@ -10,7 +10,8 @@
#include "2nvstorage.h"
#include "2ui.h"
#include "2ui_private.h"
-#include "vboot_api.h" /* for VB_KEY_ */
+#include "vboot_api.h"
+#include "vboot_kernel.h"
#define MENU_ITEMS(a) \
.num_items = ARRAY_SIZE(a), \
@@ -45,12 +46,26 @@ static const struct vb2_screen_info recovery_broken_screen = {
/******************************************************************************/
/* VB2_SCREEN_ADVANCED_OPTIONS */
+#define ADVANCED_OPTIONS_ITEM_DEVELOPER_MODE 0
+#define ADVANCED_OPTIONS_ITEM_BACK 1
+
+vb2_error_t advanced_options_init(struct vb2_ui_context *ui)
+{
+ if (vb2_get_sd(ui->ctx)->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) {
+ ui->state.disabled_item_mask |=
+ 1 << ADVANCED_OPTIONS_ITEM_DEVELOPER_MODE;
+ ui->state.selected_item = ADVANCED_OPTIONS_ITEM_BACK;
+ }
+
+ return VB2_REQUEST_UI_CONTINUE;
+}
+
static const struct vb2_menu_item advanced_options_items[] = {
- {
- .text = "Developer mode",
+ [ADVANCED_OPTIONS_ITEM_DEVELOPER_MODE] = {
+ .text = "Enable developer mode",
.target = VB2_SCREEN_RECOVERY_TO_DEV,
},
- {
+ [ADVANCED_OPTIONS_ITEM_BACK] = {
.text = "Back",
.action = vb2_ui_back_action,
},
@@ -59,6 +74,7 @@ static const struct vb2_menu_item advanced_options_items[] = {
static const struct vb2_screen_info advanced_options_screen = {
.id = VB2_SCREEN_ADVANCED_OPTIONS,
.name = "Advanced options",
+ .init = advanced_options_init,
MENU_ITEMS(advanced_options_items),
};
@@ -95,6 +111,7 @@ static const struct vb2_screen_info recovery_invalid_screen = {
/* VB2_SCREEN_RECOVERY_TO_DEV */
#define RECOVERY_TO_DEV_ITEM_CONFIRM 0
+#define RECOVERY_TO_DEV_ITEM_CANCEL 1
vb2_error_t recovery_to_dev_init(struct vb2_ui_context *ui)
{
@@ -109,9 +126,11 @@ vb2_error_t recovery_to_dev_init(struct vb2_ui_context *ui)
}
/* Disable "Confirm" button for other physical presence types. */
- if (!PHYSICAL_PRESENCE_KEYBOARD)
- ui->state.disabled_item_mask =
+ if (!PHYSICAL_PRESENCE_KEYBOARD) {
+ ui->state.disabled_item_mask |=
1 << RECOVERY_TO_DEV_ITEM_CONFIRM;
+ ui->state.selected_item = RECOVERY_TO_DEV_ITEM_CANCEL;
+ }
return VB2_REQUEST_UI_CONTINUE;
}
@@ -158,7 +177,7 @@ vb2_error_t vb2_ui_recovery_to_dev_action(struct vb2_ui_context *ui)
/* Sanity check, should never happen. */
if ((vb2_get_sd(ui->ctx)->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) ||
!vb2_allow_recovery(ui->ctx)) {
- VB2_DEBUG("ERROR: dev transition sanity check failed\n");
+ VB2_DEBUG("ERROR: Dev transition sanity check failed\n");
return VB2_REQUEST_UI_CONTINUE;
}
@@ -172,7 +191,7 @@ static const struct vb2_menu_item recovery_to_dev_items[] = {
.text = "Confirm",
.action = vb2_ui_recovery_to_dev_action,
},
- {
+ [RECOVERY_TO_DEV_ITEM_CANCEL] = {
.text = "Cancel",
.action = vb2_ui_back_action,
},
@@ -203,6 +222,177 @@ static const struct vb2_screen_info recovery_disk_step1_screen = {
};
/******************************************************************************/
+/* VB2_SCREEN_DEVELOPER_MODE */
+
+#define DEVELOPER_MODE_ITEM_RETURN_TO_SECURE 0
+#define DEVELOPER_MODE_ITEM_BOOT_INTERNAL 1
+#define DEVELOPER_MODE_ITEM_BOOT_EXTERNAL 2
+
+vb2_error_t developer_mode_init(struct vb2_ui_context *ui)
+{
+ enum vb2_dev_default_boot default_boot =
+ vb2_get_dev_boot_target(ui->ctx);
+
+ /* Get me outta here! */
+ if (!vb2_dev_boot_allowed(ui->ctx))
+ vb2_ui_change_screen(ui, VB2_SCREEN_DEVELOPER_TO_NORM);
+
+ /* Don't show "Return to secure mode" button if GBB forces dev mode. */
+ if (vb2_get_gbb(ui->ctx)->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON)
+ ui->state.disabled_item_mask |=
+ 1 << DEVELOPER_MODE_ITEM_RETURN_TO_SECURE;
+
+ /* Don't show "Boot from external disk" button if not allowed. */
+ if (!vb2_dev_boot_usb_allowed(ui->ctx))
+ ui->state.disabled_item_mask |=
+ 1 << DEVELOPER_MODE_ITEM_BOOT_EXTERNAL;
+
+ /* Choose the default selection. */
+ switch (default_boot) {
+ case VB2_DEV_DEFAULT_BOOT_USB:
+ ui->state.selected_item = DEVELOPER_MODE_ITEM_BOOT_EXTERNAL;
+ break;
+ default:
+ ui->state.selected_item = DEVELOPER_MODE_ITEM_BOOT_INTERNAL;
+ break;
+ }
+
+ ui->start_time = VbExGetTimer();
+
+ return VB2_REQUEST_UI_CONTINUE;
+}
+
+vb2_error_t vb2_ui_developer_mode_boot_internal_action(
+ struct vb2_ui_context *ui)
+{
+ if (!(ui->ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) ||
+ !vb2_dev_boot_allowed(ui->ctx)) {
+ VB2_DEBUG("ERROR: Dev mode internal boot not allowed\n");
+ return VB2_REQUEST_UI_CONTINUE;
+ }
+
+ if (VbTryLoadKernel(ui->ctx, VB_DISK_FLAG_FIXED)) {
+ VB2_DEBUG("ERROR: Dev mode internal boot failed\n");
+ return VB2_REQUEST_UI_CONTINUE;
+ }
+
+ return VB2_SUCCESS;
+}
+
+vb2_error_t vb2_ui_developer_mode_boot_external_action(
+ struct vb2_ui_context *ui)
+{
+ /* Sanity check, should never happen. */
+ if (!(ui->ctx->flags & VB2_CONTEXT_DEVELOPER_MODE) ||
+ !vb2_dev_boot_allowed(ui->ctx) ||
+ !vb2_dev_boot_usb_allowed(ui->ctx)) {
+ VB2_DEBUG("ERROR: Dev mode external boot not allowed\n");
+ return VB2_REQUEST_UI_CONTINUE;
+ }
+
+ if (VbTryLoadKernel(ui->ctx, VB_DISK_FLAG_REMOVABLE)) {
+ VB2_DEBUG("ERROR: Dev mode external boot failed\n");
+ return VB2_REQUEST_UI_CONTINUE;
+ }
+
+ return VB2_SUCCESS;
+}
+
+vb2_error_t developer_mode_action(struct vb2_ui_context *ui)
+{
+ struct vb2_gbb_header *gbb = vb2_get_gbb(ui->ctx);
+ const int use_short = gbb->flags & VB2_GBB_FLAG_DEV_SCREEN_SHORT_DELAY;
+ uint64_t elapsed;
+
+ /* Once any user interaction occurs, stop the timer. */
+ if (ui->key)
+ ui->disable_timer = 1;
+ if (ui->disable_timer)
+ return VB2_REQUEST_UI_CONTINUE;
+
+ elapsed = VbExGetTimer() - ui->start_time;
+
+ /* If we're using short delay, wait 2 seconds and don't beep. */
+ if (use_short && elapsed > 2 * VB_USEC_PER_SEC) {
+ VB2_DEBUG("Booting default target after 2s\n");
+ ui->disable_timer = 1;
+ return vb2_ui_menu_select_action(ui);
+ }
+
+ /* Otherwise, beep at 20 and 20.5 seconds. */
+ if ((ui->beep_count == 0 && elapsed > 20 * VB_USEC_PER_SEC) ||
+ (ui->beep_count == 1 && elapsed > 20500 * VB_USEC_PER_MSEC)) {
+ VbExBeep(250, 400);
+ ui->beep_count++;
+ }
+
+ /* Stop after 30 seconds. */
+ if (elapsed > 30 * VB_USEC_PER_SEC) {
+ VB2_DEBUG("Booting default target after 30s\n");
+ ui->disable_timer = 1;
+ return vb2_ui_menu_select_action(ui);
+ }
+
+ return VB2_REQUEST_UI_CONTINUE;
+}
+
+static const struct vb2_menu_item developer_mode_items[] = {
+ [DEVELOPER_MODE_ITEM_RETURN_TO_SECURE] = {
+ .text = "Return to secure mode",
+ .target = VB2_SCREEN_DEVELOPER_TO_NORM,
+ },
+ [DEVELOPER_MODE_ITEM_BOOT_INTERNAL] = {
+ .text = "Boot from internal disk",
+ .action = vb2_ui_developer_mode_boot_internal_action,
+ },
+ [DEVELOPER_MODE_ITEM_BOOT_EXTERNAL] = {
+ .text = "Boot from external disk",
+ .action = vb2_ui_developer_mode_boot_external_action,
+ },
+ ADVANCED_OPTIONS_ITEM,
+};
+
+static const struct vb2_screen_info developer_mode_screen = {
+ .id = VB2_SCREEN_DEVELOPER_MODE,
+ .name = "Developer mode",
+ .init = developer_mode_init,
+ .action = developer_mode_action,
+ MENU_ITEMS(developer_mode_items),
+};
+
+/******************************************************************************/
+/* VB2_SCREEN_DEVELOPER_TO_NORM */
+
+vb2_error_t developer_to_norm_action(struct vb2_ui_context *ui)
+{
+ if (vb2_get_gbb(ui->ctx)->flags & VB2_GBB_FLAG_FORCE_DEV_SWITCH_ON) {
+ VB2_DEBUG("ERROR: dev mode forced by GBB flag\n");
+ return VB2_REQUEST_UI_CONTINUE;
+ }
+
+ VB2_DEBUG("Leaving dev mode\n");
+ vb2_nv_set(ui->ctx, VB2_NV_DISABLE_DEV_REQUEST, 1);
+ return VB2_REQUEST_REBOOT;
+}
+
+static const struct vb2_menu_item developer_to_norm_items[] = {
+ {
+ .text = "Confirm",
+ .action = developer_to_norm_action,
+ },
+ {
+ .text = "Cancel",
+ .action = vb2_ui_back_action,
+ },
+};
+
+static const struct vb2_screen_info developer_to_norm_screen = {
+ .id = VB2_SCREEN_DEVELOPER_TO_NORM,
+ .name = "Transition to normal mode",
+ MENU_ITEMS(developer_to_norm_items),
+};
+
+/******************************************************************************/
/*
* TODO(chromium:1035800): Refactor UI code across vboot and depthcharge.
* Currently vboot and depthcharge maintain their own copies of menus/screens.
@@ -219,6 +409,8 @@ static const struct vb2_screen_info *screens[] = {
&recovery_to_dev_screen,
&recovery_phone_step1_screen,
&recovery_disk_step1_screen,
+ &developer_mode_screen,
+ &developer_to_norm_screen,
};
const struct vb2_screen_info *vb2_get_screen_info(enum vb2_screen id)