recovery: Add new recovery reason to train memory and reboot

This new recovery reason will instruct the calling firmware in
vboot_select_and_load_kernel to reboot the device (under the assumption
that training of memory has already been performed by the firmware). On
seeing the return code VBERROR_REBOOT_REQUESTED, calling firmware should
perform a reboot.

BUG=chrome-os-partner:59352
BRANCH=None
TEST=make -j runtests successful

Change-Id: I110a735e612665cb2378bd71ca01a111edaf58e3
Signed-off-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/407656
Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Furquan Shaikh
2016-11-03 16:05:07 -07:00
committed by chrome-bot
parent 6e3931d1f6
commit 95b2d6ca2b
7 changed files with 25 additions and 11 deletions

View File

@@ -220,6 +220,9 @@ enum vb2_nv_recovery {
/* Fastboot mode requested by user-mode */ /* Fastboot mode requested by user-mode */
VB2_RECOVERY_US_FASTBOOT = 0xc3, VB2_RECOVERY_US_FASTBOOT = 0xc3,
/* User requested recovery for training memory and rebooting. */
VB2_RECOVERY_TRAIN_AND_REBOOT = 0xc4,
/* Unspecified/unknown error in user-mode */ /* Unspecified/unknown error in user-mode */
VB2_RECOVERY_US_UNSPECIFIED = 0xff, VB2_RECOVERY_US_UNSPECIFIED = 0xff,
}; };

View File

@@ -68,8 +68,8 @@ enum VbErrorPredefined_t {
VBERROR_TPM_LOCK_FIRMWARE = 0x10005, VBERROR_TPM_LOCK_FIRMWARE = 0x10005,
/* Unable to set boot mode state in TPM */ /* Unable to set boot mode state in TPM */
VBERROR_TPM_SET_BOOT_MODE_STATE = 0x10006, VBERROR_TPM_SET_BOOT_MODE_STATE = 0x10006,
/* TPM requires reboot */ /* Calling firmware needs to perform a reboot. */
VBERROR_TPM_REBOOT_REQUIRED = 0x10007, VBERROR_REBOOT_REQUIRED = 0x10007,
/* Unable to set up TPM */ /* Unable to set up TPM */
VBERROR_TPM_FIRMWARE_SETUP = 0x10008, VBERROR_TPM_FIRMWARE_SETUP = 0x10008,
/* Unable to read kernel versions from TPM */ /* Unable to read kernel versions from TPM */

View File

@@ -290,6 +290,8 @@ typedef enum VbFwResult {
#define VBNV_RECOVERY_BCB_USER_MODE 0xC2 #define VBNV_RECOVERY_BCB_USER_MODE 0xC2
/* Fastboot mode requested by user-mode */ /* Fastboot mode requested by user-mode */
#define VBNV_RECOVERY_US_FASTBOOT 0xC3 #define VBNV_RECOVERY_US_FASTBOOT 0xC3
/* User requested recovery for training memory and rebooting. */
#define VBNV_RECOVERY_TRAIN_AND_REBOOT 0xC4
/* Unspecified/unknown error in user-mode */ /* Unspecified/unknown error in user-mode */
#define VBNV_RECOVERY_US_UNSPECIFIED 0xFF #define VBNV_RECOVERY_US_UNSPECIFIED 0xFF

View File

@@ -365,7 +365,7 @@ VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
VB_SCREEN_TO_NORM_CONFIRMED, VB_SCREEN_TO_NORM_CONFIRMED,
0, &vnc); 0, &vnc);
VbExSleepMs(5000); VbExSleepMs(5000);
return VBERROR_TPM_REBOOT_REQUIRED; return VBERROR_REBOOT_REQUIRED;
case -1: case -1:
VBDEBUG(("%s() - shutdown requested\n", __func__)); VBDEBUG(("%s() - shutdown requested\n", __func__));
return VBERROR_SHUTDOWN_REQUESTED; return VBERROR_SHUTDOWN_REQUESTED;
@@ -437,7 +437,7 @@ VbError_t VbBootDeveloper(VbCommonParams *cparams, LoadKernelParams *p)
VB_SCREEN_TO_NORM_CONFIRMED, VB_SCREEN_TO_NORM_CONFIRMED,
0, &vnc); 0, &vnc);
VbExSleepMs(5000); VbExSleepMs(5000);
return VBERROR_TPM_REBOOT_REQUIRED; return VBERROR_REBOOT_REQUIRED;
case -1: case -1:
VBDEBUG(("%s() - shutdown requested\n", VBDEBUG(("%s() - shutdown requested\n",
__func__)); __func__));
@@ -667,7 +667,7 @@ VbError_t VbBootRecovery(VbCommonParams *cparams, LoadKernelParams *p)
if (VbExGetSwitches if (VbExGetSwitches
(VB_INIT_FLAG_ALLOW_USB_BOOT)) (VB_INIT_FLAG_ALLOW_USB_BOOT))
VbAllowUsbBoot(); VbAllowUsbBoot();
return VBERROR_TPM_REBOOT_REQUIRED; return VBERROR_REBOOT_REQUIRED;
case -1: case -1:
VBDEBUG(("%s() - Shutdown requested\n", VBDEBUG(("%s() - Shutdown requested\n",
__func__)); __func__));
@@ -1218,7 +1218,12 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
#endif #endif
/* Select boot path */ /* Select boot path */
if (shared->recovery_reason) { if (shared->recovery_reason == VBNV_RECOVERY_TRAIN_AND_REBOOT) {
/* Reboot requested by user recovery code. */
VBDEBUG(("Reboot requested by user (recovery_reason=%d).\n",
shared->recovery_reason));
retval = VBERROR_REBOOT_REQUIRED;
} else if (shared->recovery_reason) {
/* Recovery boot */ /* Recovery boot */
p.boot_flags |= BOOT_FLAG_RECOVERY; p.boot_flags |= BOOT_FLAG_RECOVERY;
retval = VbBootRecovery(cparams, &p); retval = VbBootRecovery(cparams, &p);

View File

@@ -539,6 +539,8 @@ const char *RecoveryReasonString(uint8_t code)
return "User-mode requested recovery via BCB"; return "User-mode requested recovery via BCB";
case VBNV_RECOVERY_US_FASTBOOT: case VBNV_RECOVERY_US_FASTBOOT:
return "User-mode requested fastboot mode"; return "User-mode requested fastboot mode";
case VBNV_RECOVERY_TRAIN_AND_REBOOT:
return "User-mode requested DRAM train and reboot";
case VBNV_RECOVERY_US_UNSPECIFIED: case VBNV_RECOVERY_US_UNSPECIFIED:
return "Unspecified/unknown error in user-mode"; return "Unspecified/unknown error in user-mode";
} }

View File

@@ -360,7 +360,7 @@ static void VbBootDevTest(void)
shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON; shared->flags = VBSD_HONOR_VIRT_DEV_SWITCH | VBSD_BOOT_DEV_SWITCH_ON;
mock_keypress[0] = ' '; mock_keypress[0] = ' ';
mock_keypress[1] = '\r'; mock_keypress[1] = '\r';
TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED, TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_REBOOT_REQUIRED,
"Space = tonorm"); "Space = tonorm");
TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING, TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_WARNING,
" warning screen"); " warning screen");
@@ -398,7 +398,7 @@ static void VbBootDevTest(void)
gbb.flags |= GBB_FLAG_ENTER_TRIGGERS_TONORM; gbb.flags |= GBB_FLAG_ENTER_TRIGGERS_TONORM;
mock_keypress[0] = '\r'; mock_keypress[0] = '\r';
mock_keypress[1] = '\r'; mock_keypress[1] = '\r';
TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED, TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_REBOOT_REQUIRED,
"Enter = tonorm"); "Enter = tonorm");
/* Tonorm ignored if GBB forces dev switch on */ /* Tonorm ignored if GBB forces dev switch on */
@@ -502,7 +502,7 @@ static void VbBootDevTest(void)
VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT; VbApiKernelGetFwmp()->flags |= FWMP_DEV_DISABLE_BOOT;
mock_keypress[0] = '\x1b'; /* Just causes TONORM again */ mock_keypress[0] = '\x1b'; /* Just causes TONORM again */
mock_keypress[1] = '\r'; mock_keypress[1] = '\r';
TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED, TEST_EQ(VbBootDeveloper(&cparams, &lkp), VBERROR_REBOOT_REQUIRED,
"FWMP dev disabled"); "FWMP dev disabled");
TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_TO_NORM, TEST_EQ(screens_displayed[0], VB_SCREEN_DEVELOPER_TO_NORM,
" tonorm screen"); " tonorm screen");
@@ -690,7 +690,7 @@ static void VbBootRecTest(void)
mock_keypress[0] = 0x04; mock_keypress[0] = 0x04;
mock_keypress[1] = '\r'; mock_keypress[1] = '\r';
mock_keyflags[1] = VB_KEY_FLAG_TRUSTED_KEYBOARD; mock_keyflags[1] = VB_KEY_FLAG_TRUSTED_KEYBOARD;
TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_TPM_REBOOT_REQUIRED, TEST_EQ(VbBootRecovery(&cparams, &lkp), VBERROR_REBOOT_REQUIRED,
"Ctrl+D todev confirm"); "Ctrl+D todev confirm");
TEST_EQ(virtdev_set, 1, " virtual dev mode on"); TEST_EQ(virtdev_set, 1, " virtual dev mode on");

View File

@@ -244,7 +244,9 @@ static void VbSlkTest(void)
rkr_retval = rkw_retval = rkl_retval = VBERROR_SIMULATED; rkr_retval = rkw_retval = rkl_retval = VBERROR_SIMULATED;
test_slk(0, 0, "Recovery ignore TPM errors"); test_slk(0, 0, "Recovery ignore TPM errors");
ResetMocks();
shared->recovery_reason = VBNV_RECOVERY_TRAIN_AND_REBOOT;
test_slk(VBERROR_REBOOT_REQUIRED, 0, "Recovery train and reboot");
// todo: rkr/w/l fail ignored if recovery // todo: rkr/w/l fail ignored if recovery