summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Kitching <kitching@google.com>2018-03-28 17:15:38 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2018-07-27 03:19:40 +0000
commit95ab37681a997054f00a3137c4211777bc946eff (patch)
tree48648c1ec96b2efe0030c36994ef1be6f2442df0
parent82414e8186bc4c3f0cd902ec47e3f96fd98e6f02 (diff)
downloadvboot-95ab37681a997054f00a3137c4211777bc946eff.tar.gz
depthcharge: initial implementation of Alt OS boot flow
The goal of Alt OS is to allow for booting of alternate operating systems without leaving verified normal mode. See here for details: go/vboot-altos BUG=b:70804764 TEST=make runtests TEST=COV=1 make coverage TEST=Step with GDB and either use kbatboot or hold down A CQ-DEPEND=CL:1126806,CL:972763 BRANCH=firmware-eve-campfire Change-Id: I71045f6a0f29768f15fcb4130f6063d4190611bb Reviewed-on: https://chromium-review.googlesource.com/983312 Tested-by: Joel Kitching <kitching@chromium.org> Trybot-Ready: Joel Kitching <kitching@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Hung-Te Lin <hungte@chromium.org>
-rw-r--r--Makefile3
-rw-r--r--firmware/include/vboot_api.h7
-rw-r--r--firmware/include/vboot_struct.h4
-rw-r--r--firmware/lib/include/rollback_index.h2
-rw-r--r--firmware/lib/include/vboot_kernel.h5
-rw-r--r--firmware/lib/vboot_api_kernel.c116
-rw-r--r--firmware/lib/vboot_ui.c97
-rw-r--r--firmware/stub/vboot_api_stub_switches.c14
-rw-r--r--tests/vboot_api_kernel2_tests.c42
-rw-r--r--tests/vboot_api_kernel4_tests.c114
10 files changed, 402 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index 31f714b8..d9f65665 100644
--- a/Makefile
+++ b/Makefile
@@ -417,7 +417,8 @@ VBINIT_SRCS += \
VBSLK_SRCS += \
firmware/stub/vboot_api_stub.c \
firmware/stub/vboot_api_stub_disk.c \
- firmware/stub/vboot_api_stub_stream.c
+ firmware/stub/vboot_api_stub_stream.c \
+ firmware/stub/vboot_api_stub_switches.c
FWLIB2X_SRCS += \
firmware/2lib/2stub.c
diff --git a/firmware/include/vboot_api.h b/firmware/include/vboot_api.h
index b6fb0969..2f88a38a 100644
--- a/firmware/include/vboot_api.h
+++ b/firmware/include/vboot_api.h
@@ -126,6 +126,8 @@ enum VbErrorPredefined_t {
VBERROR_RW_JUMP_FAILED = 0x10028,
/* Error reading FWMP from TPM (note: not present is not an error) */
VBERROR_TPM_READ_FWMP = 0x10029,
+ /* Error reading or writing Alt OS flags to TPM */
+ VBERROR_TPM_ALT_OS = 0x10030,
/* VbExEcGetExpectedRWHash() may return the following codes */
/* Compute expected RW hash from the EC image; BIOS doesn't have it */
@@ -916,6 +918,11 @@ uint32_t VbExKeyboardReadWithFlags(uint32_t *flags_ptr);
*/
uint32_t VbExGetSwitches(uint32_t request_mask);
+/**
+ * Return whether Alt OS hotkey was held down at boot.
+ */
+int vb2ex_get_alt_os_hotkey(void);
+
/*****************************************************************************/
/* Embedded controller (EC) */
diff --git a/firmware/include/vboot_struct.h b/firmware/include/vboot_struct.h
index 08910d13..f005feb3 100644
--- a/firmware/include/vboot_struct.h
+++ b/firmware/include/vboot_struct.h
@@ -241,6 +241,10 @@ typedef struct VbKernelPreambleHeader {
#define VBSD_OPROM_LOADED 0x00020000
/* Don't try for boot failures */
#define VBSD_NOFAIL_BOOT 0x00040000
+/* Confirm enabling Alt OS for this boot */
+#define VBSD_ALT_OS_CONFIRM_ENABLE 0x00080000
+/* Show Alt OS picker screen for this boot */
+#define VBSD_ALT_OS_SHOW_PICKER 0x00100000
/*
* Supported flags by header version. It's ok to add new flags while keeping
diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h
index 9152d549..b568ab09 100644
--- a/firmware/lib/include/rollback_index.h
+++ b/firmware/lib/include/rollback_index.h
@@ -164,7 +164,7 @@ uint32_t SetVirtualDevMode(int val);
enum alt_os_flags {
ALT_OS_ENABLE = (1 << 0),
- ALT_OS_HOT_KEY = (1 << 1),
+ ALT_OS_HOTKEY = (1 << 1),
};
/**
diff --git a/firmware/lib/include/vboot_kernel.h b/firmware/lib/include/vboot_kernel.h
index 2195e0cf..ba2f51b0 100644
--- a/firmware/lib/include/vboot_kernel.h
+++ b/firmware/lib/include/vboot_kernel.h
@@ -83,6 +83,11 @@ VbError_t VbBootDeveloperMenu(struct vb2_context *ctx, VbCommonParams *cparams);
VbError_t VbBootRecoveryMenu(struct vb2_context *ctx, VbCommonParams *cparams);
/**
+ * Handle an Alt OS-mode boot.
+ */
+VbError_t VbBootAltOS(struct vb2_context *ctx, VbCommonParams *cparams);
+
+/**
* Return the current FWMP flags. Valid only inside VbSelectAndLoadKernel().
*/
uint32_t vb2_get_fwmp_flags(void);
diff --git a/firmware/lib/vboot_api_kernel.c b/firmware/lib/vboot_api_kernel.c
index d1afc4f7..08254a47 100644
--- a/firmware/lib/vboot_api_kernel.c
+++ b/firmware/lib/vboot_api_kernel.c
@@ -406,6 +406,101 @@ static void vb2_kernel_cleanup(struct vb2_context *ctx, VbCommonParams *cparams)
shared->timer_vb_select_and_load_kernel_exit = VbExGetTimer();
}
+int VbAltOSForceChromeOS(void) {
+ return 0;
+}
+
+VbError_t VbCheckAltOS(struct vb2_context *ctx, VbCommonParams *cparams,
+ int trusted_ec) {
+ VbSharedDataHeader *shared =
+ (VbSharedDataHeader *)cparams->shared_data_blob;
+
+ int req_enable = vb2_nv_get(ctx, VB2_NV_ENABLE_ALT_OS_REQUEST);
+ int req_disable = vb2_nv_get(ctx, VB2_NV_DISABLE_ALT_OS_REQUEST);
+
+ /* Reset enable/disable requests right away to prevent cycles. */
+ vb2_nv_set(ctx, VB2_NV_ENABLE_ALT_OS_REQUEST, 0);
+ vb2_nv_set(ctx, VB2_NV_DISABLE_ALT_OS_REQUEST, 0);
+
+ uint8_t kflags;
+ uint8_t kflags_set;
+ int rv;
+ rv = GetAltOSFlags(&kflags);
+ if (rv) {
+ VB2_DEBUG("Unable to read Alt OS flags from TPM\n");
+ return rv;
+ }
+ kflags_set = kflags;
+
+ int need_oprom = 0;
+ int oprom_loaded = !(shared->flags & VBSD_OPROM_MATTERS) ||
+ shared->flags & VBSD_OPROM_LOADED;
+ int hotkey_after_sync = vb2ex_get_alt_os_hotkey();
+ int hotkey_last_boot = !!(kflags & ALT_OS_HOTKEY);
+ int enabled = !!(kflags & ALT_OS_ENABLE);
+ int force_cros = VbAltOSForceChromeOS();
+
+
+ /* Case 1: Disable Alt OS mode. Does not need UI. */
+ if (enabled && req_disable) {
+ VB2_DEBUG("Disabling Alt OS mode...\n");
+ /* Disable has priority over enable. */
+ req_enable = 0;
+ enabled = 0;
+ kflags_set &= ~ALT_OS_ENABLE;
+ }
+
+ /* Case 2: Enable Alt OS mode. Needs UI. */
+ if (!enabled && ((req_enable && hotkey_after_sync && trusted_ec) ||
+ hotkey_last_boot)) {
+ VB2_DEBUG("Setting flag to show confirm Alt OS mode\n");
+ shared->flags |= VBSD_ALT_OS_CONFIRM_ENABLE;
+ need_oprom = 1;
+ /* If we need to reboot to load VGA Option ROM, save Alt OS
+ * hotkey state in TPM for next boot. */
+ kflags_set |= ALT_OS_HOTKEY;
+ }
+
+ /* Case 3: Show Alt OS picker. Needs UI. */
+ if (enabled && !force_cros) {
+ VB2_DEBUG("Setting flag to show Alt OS picker\n");
+ shared->flags |= VBSD_ALT_OS_SHOW_PICKER;
+ need_oprom = 1;
+ }
+
+ /* If we don't need to store Alt OS hotkey state, then remove it. */
+ if (!need_oprom || oprom_loaded)
+ kflags_set &= ~ALT_OS_HOTKEY;
+
+ if (kflags_set != kflags) {
+ rv = SetAltOSFlags(kflags_set);
+ if (rv) {
+ VB2_DEBUG("Unable to write Alt OS flags to TPM\n");
+ return rv;
+ }
+ }
+
+ VB2_DEBUG("Alt OS: kflags=%d\n", kflags);
+ VB2_DEBUG("Alt OS: kflags_set=%d\n", kflags_set);
+ VB2_DEBUG("Alt OS: hotkey_after_sync=%d\n", hotkey_after_sync);
+ VB2_DEBUG("Alt OS: hotkey_last_boot=%d\n", hotkey_last_boot);
+ VB2_DEBUG("Alt OS: need_oprom=%d\n", need_oprom);
+ VB2_DEBUG("Alt OS: oprom_loaded=%d\n", oprom_loaded);
+ VB2_DEBUG("Alt OS: enabled=%d\n", enabled);
+ VB2_DEBUG("Alt OS: force_cros=%d\n", force_cros);
+ VB2_DEBUG("Alt OS: req_enable=%d\n", req_enable);
+ VB2_DEBUG("Alt OS: req_disable=%d\n", req_disable);
+ VB2_DEBUG("Alt OS: trusted_ec=%d\n", trusted_ec);
+
+ if (need_oprom && !oprom_loaded) {
+ VB2_DEBUG("Reboot to load VGA Option ROM\n");
+ vb2_nv_set(ctx, VB2_NV_OPROM_NEEDED, 1);
+ return VBERROR_VGA_OPROM_MISMATCH;
+ }
+
+ return VBERROR_SUCCESS;
+}
+
VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
VbSelectAndLoadKernelParams *kparams)
{
@@ -417,6 +512,12 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
goto VbSelectAndLoadKernel_exit;
/*
+ * Determine whether the EC is in RO or RW. This information
+ * will be used later on in Alt OS boot flow.
+ */
+ int trusted_ec = VbExTrustEC(0);
+
+ /*
* Do EC software sync if necessary. This has UI, but it's just a
* single non-interactive WAIT screen.
*/
@@ -424,6 +525,15 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
if (retval)
goto VbSelectAndLoadKernel_exit;
+ /*
+ * Check whether confirmation screen or picker screen need to be
+ * shown for Alt OS. Ignore return value, and in the case of failure,
+ * continue to a normal boot.
+ */
+ retval = VbCheckAltOS(&ctx, cparams, trusted_ec);
+ if (retval == VBERROR_VGA_OPROM_MISMATCH)
+ goto VbSelectAndLoadKernel_exit;
+
/* Select boot path */
if (shared->recovery_reason) {
/* Recovery boot. This has UI. */
@@ -439,6 +549,12 @@ VbError_t VbSelectAndLoadKernel(VbCommonParams *cparams,
else
retval = VbBootDeveloper(&ctx, cparams);
VbExEcEnteringMode(0, VB_EC_DEVELOPER);
+ } else if (shared->flags & VBSD_ALT_OS_CONFIRM_ENABLE ||
+ shared->flags & VBSD_ALT_OS_SHOW_PICKER) {
+ /* Alt OS boot. This has UI. */
+ retval = VbBootAltOS(&ctx, cparams);
+ /* Report as normal mode to the EC. */
+ VbExEcEnteringMode(0, VB_EC_NORMAL);
} else {
/* Normal boot */
retval = VbBootNormal(&ctx, cparams);
diff --git a/firmware/lib/vboot_ui.c b/firmware/lib/vboot_ui.c
index 4739cd64..d4691157 100644
--- a/firmware/lib/vboot_ui.c
+++ b/firmware/lib/vboot_ui.c
@@ -153,6 +153,103 @@ int VbUserConfirms(struct vb2_context *ctx, VbCommonParams *cparams,
return -1;
}
+VbError_t vb2_alt_os_picker(struct vb2_context *ctx, VbCommonParams *cparams,
+ uint32_t timeout_msec, int *index)
+{
+ /* Calibrate delay */
+ uint64_t a, b;
+ a = VbExGetTimer();
+ VbExSleepMs(10);
+ b = VbExGetTimer();
+ uint64_t ticks_per_msec = (b - a) / 10ULL ;
+ uint64_t show_until = VbExGetTimer() + timeout_msec * ticks_per_msec;
+
+ VB2_DEBUG("Alt OS picker: timeout_msec=%d\n", timeout_msec);
+ VB2_DEBUG("Alt OS picker: ticks_per_msec=%" PRIu64 "\n",
+ ticks_per_msec);
+
+ *index = 0;
+ while (1) {
+ VbDisplayMenu(ctx, cparams, VB_SCREEN_ALT_OS, 0, *index);
+ if (VbWantShutdown(cparams->gbb->flags))
+ return VBERROR_SHUTDOWN_REQUESTED;
+ uint32_t key = VbExKeyboardRead();
+ if (key == VB_KEY_LEFT)
+ *index = 0;
+ else if (key == VB_KEY_RIGHT)
+ *index = 1;
+ else if (key == '\r' || key == ' ')
+ break;
+ VbExSleepMs(20);
+
+ if (timeout_msec > 0 && VbExGetTimer() > show_until) {
+ VB2_DEBUG("Alt OS picker: timed out\n");
+ break;
+ }
+ }
+ return VBERROR_SUCCESS;
+}
+
+VbError_t vb2_alt_os_ui(struct vb2_context *ctx, VbCommonParams *cparams)
+{
+ /* Note that OPROM will not be disabled until the next reboot. */
+ const int picker_timeout_msec = 20 * 1000;
+ VbSharedDataHeader *shared =
+ (VbSharedDataHeader *)cparams->shared_data_blob;
+ int boot_alt_os = 0; /* 0 = Chrome OS; 1 = Alt OS */
+ uint8_t tpm_flags;
+
+ /* Confirm enabling Alt OS */
+ if (shared->flags & VBSD_ALT_OS_CONFIRM_ENABLE) {
+ VB2_DEBUG("Alt OS UI: Picker screen without timeout\n");
+ VbError_t ret = vb2_alt_os_picker(ctx, cparams,
+ 0, &boot_alt_os);
+ if (ret != VBERROR_SUCCESS) {
+ VB2_DEBUG("Error from Alt OS picker screen\n");
+ return ret;
+ }
+ }
+
+ /* Enable if Alt OS is chosen */
+ if (boot_alt_os) {
+ if (GetAltOSFlags(&tpm_flags)) {
+ VB2_DEBUG("Unable to read Alt OS flags from TPM\n");
+ return VBERROR_TPM_ALT_OS;
+ }
+ tpm_flags |= ALT_OS_ENABLE;
+ if (SetAltOSFlags(tpm_flags)) {
+ VB2_DEBUG("Unable to write Alt OS flags to TPM\n");
+ return VBERROR_TPM_ALT_OS;
+ }
+ }
+
+ /* Show Alt OS picker screen */
+ else if (shared->flags & VBSD_ALT_OS_SHOW_PICKER) {
+ VB2_DEBUG("Alt OS UI: Picker screen with timeout\n");
+ VbError_t ret = vb2_alt_os_picker(ctx, cparams,
+ picker_timeout_msec,
+ &boot_alt_os);
+ if (ret != VBERROR_SUCCESS) {
+ VB2_DEBUG("Error from Alt OS picker screen\n");
+ return ret;
+ }
+ }
+
+ if (boot_alt_os) {
+ /* Will only return on failure */
+ VbTryLegacy(ctx, 1);
+ }
+
+ /* Will only return on failure */
+ return VbBootNormal(ctx, cparams);
+}
+
+VbError_t VbBootAltOS(struct vb2_context *ctx, VbCommonParams *cparams)
+{
+ VbError_t retval = vb2_alt_os_ui(ctx, cparams);
+ return retval;
+}
+
static const char dev_disable_msg[] =
"Developer mode is disabled on this device by system policy.\n"
"For more information, see http://dev.chromium.org/chromium-os/fwmp\n"
diff --git a/firmware/stub/vboot_api_stub_switches.c b/firmware/stub/vboot_api_stub_switches.c
new file mode 100644
index 00000000..29ab8e0d
--- /dev/null
+++ b/firmware/stub/vboot_api_stub_switches.c
@@ -0,0 +1,14 @@
+/* Copyright 2018 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Stub implementations of switch APIs.
+ */
+
+#include "vboot_api.h"
+
+
+int vb2ex_get_alt_os_hotkey(void)
+{
+ return 0;
+}
diff --git a/tests/vboot_api_kernel2_tests.c b/tests/vboot_api_kernel2_tests.c
index f6776e9e..cbad7827 100644
--- a/tests/vboot_api_kernel2_tests.c
+++ b/tests/vboot_api_kernel2_tests.c
@@ -51,6 +51,8 @@ static uint32_t screens_displayed[8];
static uint32_t screens_count = 0;
static uint32_t mock_num_disks[8];
static uint32_t mock_num_disks_count;
+static uint8_t gaf_val, saf_val;
+static int gaf_retval, saf_retval;
extern enum VbEcBootMode_t VbGetMode(void);
extern struct RollbackSpaceFwmp *VbApiKernelGetFwmp(void);
@@ -89,6 +91,8 @@ static void ResetMocks(void)
trust_ec = 0;
virtdev_set = 0;
virtdev_retval = 0;
+ gaf_val = saf_val = 0;
+ gaf_retval = saf_retval = VBERROR_SUCCESS;
memset(screens_displayed, 0, sizeof(screens_displayed));
screens_count = 0;
@@ -204,6 +208,18 @@ uint32_t SetVirtualDevMode(int val)
return virtdev_retval;
}
+uint32_t GetAltOSFlags(uint8_t *val)
+{
+ *val = gaf_val;
+ return gaf_retval;
+}
+
+uint32_t SetAltOSFlags(uint8_t val)
+{
+ saf_val = val;
+ return saf_retval;
+}
+
/* Tests */
static void VbUserConfirmsTest(void)
@@ -733,12 +749,38 @@ static void VbBootRecTest(void)
}
+static void VbBootAltOSTest(void)
+{
+ printf("Testing VbBootAltOS()...\n");
+
+ /* Right arrow then enter means enable */
+ ResetMocks();
+ shared->flags = VBSD_ALT_OS_CONFIRM_ENABLE;
+ mock_keypress[0] = 0x103;
+ mock_keypress[1] = '\r';
+ TEST_EQ(VbBootAltOS(&ctx, &cparams), 1002, "Enable Alt OS failure");
+ TEST_EQ(vbexlegacy_called, 1, " boot legacy");
+ TEST_TRUE(saf_val & ALT_OS_ENABLE, " enable flag");
+
+ /* Right arrow then enter means boot Chrome OS */
+ ResetMocks();
+ shared->flags = VBSD_ALT_OS_SHOW_PICKER;
+ mock_keypress[0] = 0x102;
+ mock_keypress[1] = '\r';
+ TEST_EQ(VbBootAltOS(&ctx, &cparams), 1002, "Boot Chrome OS failure");
+ TEST_EQ(vbexlegacy_called, 0, " boot normal");
+
+ printf("...done.\n");
+}
+
+
int main(void)
{
VbUserConfirmsTest();
VbBootTest();
VbBootDevTest();
VbBootRecTest();
+ VbBootAltOSTest();
return gTestSuccess ? 0 : 255;
}
diff --git a/tests/vboot_api_kernel4_tests.c b/tests/vboot_api_kernel4_tests.c
index 41e58c8e..1edea80a 100644
--- a/tests/vboot_api_kernel4_tests.c
+++ b/tests/vboot_api_kernel4_tests.c
@@ -34,6 +34,8 @@ static uint32_t rkr_version;
static uint32_t new_version;
static struct RollbackSpaceFwmp rfr_fwmp;
static int rkr_retval, rkw_retval, rkl_retval, rfr_retval;
+static uint8_t gaf_val, saf_val;
+static int gah_retval, gaf_retval, saf_retval;
static VbError_t vbboot_retval;
/* Reset mock data (for use before each test) */
@@ -65,6 +67,9 @@ static void ResetMocks(void)
ecsync_retval = VBERROR_SUCCESS;
rkr_version = new_version = 0x10002;
rkr_retval = rkw_retval = rkl_retval = VBERROR_SUCCESS;
+ gaf_val = saf_val = 0;
+ gaf_retval = saf_retval = VBERROR_SUCCESS;
+ gah_retval = 0;
vbboot_retval = VBERROR_SUCCESS;
}
@@ -87,6 +92,28 @@ VbError_t VbExEcRunningRW(int devidx, int *in_rw)
return ecsync_retval;
}
+int VbExTrustEC(int devidx)
+{
+ return !ecsync_retval;
+}
+
+int vb2ex_get_alt_os_hotkey(void)
+{
+ return gah_retval;
+}
+
+uint32_t GetAltOSFlags(uint8_t *val)
+{
+ *val = gaf_val;
+ return gaf_retval;
+}
+
+uint32_t SetAltOSFlags(uint8_t val)
+{
+ saf_val = val;
+ return saf_retval;
+}
+
uint32_t RollbackKernelRead(uint32_t *version)
{
*version = rkr_version;
@@ -142,6 +169,14 @@ VbError_t VbBootRecovery(struct vb2_context *ctx, VbCommonParams *cparams)
return vbboot_retval;
}
+VbError_t VbBootAltOS(struct vb2_context *ctx, VbCommonParams *cparams)
+{
+ if (vbboot_retval == -4)
+ return VBERROR_SIMULATED;
+
+ return vbboot_retval;
+}
+
static void test_slk(VbError_t retval, int recovery_reason, const char *desc)
{
uint32_t u;
@@ -258,7 +293,86 @@ static void VbSlkTest(void)
// todo: rkr/w/l fail ignored if recovery
+ /* Boot alt OS */
+ uint32_t oprom_needed;
+ /*
+ * Enable request without OPROM
+ * oprom matters: Y
+ * oprom loaded: N
+ * current hotkey: Y
+ * stored hotkey: N
+ * enable request: Y
+ * disable request: N
+ * enabled: N
+ * result: request reboot for OPROM
+ */
+ ResetMocks();
+ shared->flags |= VBSD_OPROM_MATTERS;
+ gah_retval = 1;
+ VbNvSet(&vnc, VBNV_ENABLE_ALT_OS_REQUEST, 1);
+ VbNvTeardown(&vnc);
+ test_slk(VBERROR_VGA_OPROM_MISMATCH, 0, "Alt OS doesn't request OPROM");
+ VbNvGet(&vnc, VBNV_OPROM_NEEDED, &oprom_needed);
+ TEST_EQ(oprom_needed, 1, "Alt OS doesn't request OPROM");
+
+ /*
+ * Enable request with OPROM
+ * oprom matters: Y
+ * oprom loaded: Y
+ * current hotkey: N
+ * stored hotkey: Y
+ * enable request: Y
+ * disable request: N
+ * enabled: N
+ * result: run VbBootAltOS
+ */
+ ResetMocks();
+ shared->flags |= VBSD_OPROM_MATTERS;
+ shared->flags |= VBSD_OPROM_LOADED;
+ gaf_val |= ALT_OS_HOTKEY;
+ VbNvSet(&vnc, VBNV_ENABLE_ALT_OS_REQUEST, 1);
+ VbNvTeardown(&vnc);
+ vbboot_retval = -4;
+ test_slk(VBERROR_SIMULATED, 0, "Alt OS enable bad");
+
+ /*
+ * Enabled with OPROM
+ * oprom matters: Y
+ * oprom loaded: Y
+ * current hotkey: N
+ * stored hotkey: Y
+ * enable request: N
+ * disable request: N
+ * enabled: Y
+ * result: run VbBootAltOS
+ */
+ ResetMocks();
+ shared->flags |= VBSD_OPROM_MATTERS;
+ shared->flags |= VBSD_OPROM_LOADED;
+ gaf_val |= ALT_OS_ENABLE;
+ vbboot_retval = -4;
+ test_slk(VBERROR_SIMULATED, 0, "Alt OS boot bad");
+
+ /*
+ * Disable request without OPROM
+ * oprom matters: Y
+ * oprom loaded: N
+ * current hotkey: N
+ * stored hotkey: N
+ * enable request: N
+ * disable request: Y
+ * enabled: Y
+ * result: disable Alt OS and boot normal mode
+ */
+ ResetMocks();
+ shared->flags |= VBSD_OPROM_MATTERS;
+ gaf_val |= ALT_OS_ENABLE;
+ VbNvSet(&vnc, VBNV_DISABLE_ALT_OS_REQUEST, 1);
+ VbNvTeardown(&vnc);
+ vbboot_retval = -1;
+ test_slk(VBERROR_SIMULATED, 0, "Alt OS incorrect boot after disable");
+ TEST_FALSE(saf_val & ALT_OS_ENABLE, "Alt OS doesn't disable");
}
int main(void)