diff options
Diffstat (limited to 'firmware/2lib/2ui_screens.c')
-rw-r--r-- | firmware/2lib/2ui_screens.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/firmware/2lib/2ui_screens.c b/firmware/2lib/2ui_screens.c index 5b235c24..a6fffb5e 100644 --- a/firmware/2lib/2ui_screens.c +++ b/firmware/2lib/2ui_screens.c @@ -6,7 +6,11 @@ */ #include "2common.h" +#include "2misc.h" +#include "2nvstorage.h" #include "2ui.h" +#include "2ui_private.h" +#include "vboot_api.h" /* for VB_KEY_ */ #define MENU_ITEMS(a) \ .num_items = ARRAY_SIZE(a), \ @@ -62,6 +66,101 @@ static const struct vb2_screen_info recovery_invalid_screen = { }; /******************************************************************************/ +/* VB2_SCREEN_RECOVERY_TO_DEV */ + +#define RECOVERY_TO_DEV_ITEM_CONFIRM 0 + +vb2_error_t recovery_to_dev_init(struct vb2_ui_context *ui) +{ + if (vb2_get_sd(ui->ctx)->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) { + VB2_DEBUG("Dev mode already enabled?\n"); + return vb2_ui_back_action(ui); + } + + if (!PHYSICAL_PRESENCE_KEYBOARD && vb2ex_physical_presence_pressed()) { + VB2_DEBUG("Presence button stuck?\n"); + return vb2_ui_back_action(ui); + } + + /* Disable "Confirm" button for other physical presence types. */ + if (!PHYSICAL_PRESENCE_KEYBOARD) + ui->state.disabled_item_mask = + 1 << RECOVERY_TO_DEV_ITEM_CONFIRM; + + return VB2_REQUEST_UI_CONTINUE; +} + +vb2_error_t vb2_ui_recovery_to_dev_action(struct vb2_ui_context *ui) +{ + static int pressed_last; + int pressed; + + if (ui->state.screen->id != VB2_SCREEN_RECOVERY_TO_DEV) { + VB2_DEBUG("Action needs RECOVERY_TO_DEV screen\n"); + return VB2_REQUEST_UI_CONTINUE; + } + + if (ui->key == ' ') { + VB2_DEBUG("SPACE means cancel dev mode transition\n"); + return vb2_ui_back_action(ui); + } + + if (PHYSICAL_PRESENCE_KEYBOARD) { + if (ui->key != VB_KEY_ENTER && + ui->key != VB_BUTTON_POWER_SHORT_PRESS) + return VB2_REQUEST_UI_CONTINUE; + if (!ui->key_trusted) { + VB2_DEBUG("Reject untrusted %s confirmation\n", + ui->key == VB_KEY_ENTER ? + "ENTER" : "POWER"); + return VB2_REQUEST_UI_CONTINUE; + } + } else { + pressed = vb2ex_physical_presence_pressed(); + if (pressed) { + VB2_DEBUG("Physical presence button pressed, " + "awaiting release\n"); + pressed_last = 1; + return VB2_REQUEST_UI_CONTINUE; + } + if (!pressed_last) + return VB2_REQUEST_UI_CONTINUE; + VB2_DEBUG("Physical presence button released\n"); + } + VB2_DEBUG("Physical presence confirmed!\n"); + + /* 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"); + return VB2_REQUEST_UI_CONTINUE; + } + + VB2_DEBUG("Enabling dev mode and rebooting...\n"); + vb2_enable_developer_mode(ui->ctx); + return VB2_REQUEST_REBOOT_EC_TO_RO; +} + +static const struct vb2_menu_item recovery_to_dev_items[] = { + [RECOVERY_TO_DEV_ITEM_CONFIRM] = { + .text = "Confirm", + .action = vb2_ui_recovery_to_dev_action, + }, + { + .text = "Cancel", + .action = vb2_ui_back_action, + }, +}; + +static const struct vb2_screen_info recovery_to_dev_screen = { + .id = VB2_SCREEN_RECOVERY_TO_DEV, + .name = "Transition to developer mode", + .init = recovery_to_dev_init, + .action = vb2_ui_recovery_to_dev_action, + MENU_ITEMS(recovery_to_dev_items), +}; + +/******************************************************************************/ /* VB2_SCREEN_RECOVERY_PHONE_STEP1 */ static const struct vb2_screen_info recovery_phone_step1_screen = { @@ -92,6 +191,7 @@ static const struct vb2_screen_info *screens[] = { &recovery_broken_screen, &recovery_select_screen, &recovery_invalid_screen, + &recovery_to_dev_screen, &recovery_phone_step1_screen, &recovery_disk_step1_screen, }; |