diff options
Diffstat (limited to 'firmware/lib/vboot_api_init.c')
-rw-r--r-- | firmware/lib/vboot_api_init.c | 551 |
1 files changed, 300 insertions, 251 deletions
diff --git a/firmware/lib/vboot_api_init.c b/firmware/lib/vboot_api_init.c index a77b230d..ec33f351 100644 --- a/firmware/lib/vboot_api_init.c +++ b/firmware/lib/vboot_api_init.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. +/* Copyright (c) 2013 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. * @@ -13,254 +13,303 @@ #include "vboot_common.h" #include "vboot_nvstorage.h" - -VbError_t VbInit(VbCommonParams* cparams, VbInitParams* iparams) { - VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob; - GoogleBinaryBlockHeader* gbb = (GoogleBinaryBlockHeader*)cparams->gbb_data; - VbNvContext vnc; - VbError_t retval = VBERROR_SUCCESS; - uint32_t recovery = VBNV_RECOVERY_NOT_REQUESTED; - int is_s3_resume = 0; - uint32_t s3_debug_boot = 0; - uint32_t require_official_os = 0; - uint32_t tpm_version = 0; - uint32_t tpm_status = 0; - int has_virt_dev_switch = 0; - int is_hw_dev = 0; - int is_virt_dev = 0; - uint32_t disable_dev_request = 0; - uint32_t clear_tpm_owner_request = 0; - int is_dev = 0; - - VBDEBUG(("VbInit() input flags 0x%x\n", iparams->flags)); - - /* Initialize output flags */ - iparams->out_flags = 0; - - /* Set up NV storage */ - VbExNvStorageRead(vnc.raw); - VbNvSetup(&vnc); - - /* Initialize shared data structure */ - if (0 != VbSharedDataInit(shared, cparams->shared_data_size)) { - VBDEBUG(("Shared data init error\n")); - return VBERROR_INIT_SHARED_DATA; - } - - shared->timer_vb_init_enter = VbExGetTimer(); - - /* Copy some boot switch flags */ - /* TODO: in next refactor, just save in/out flags in VbSharedData */ - shared->flags = 0; - if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED) - shared->flags |= VBSD_BOOT_REC_SWITCH_ON; - if (iparams->flags & VB_INIT_FLAG_WP_ENABLED) - shared->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED; - if (iparams->flags & VB_INIT_FLAG_SW_WP_ENABLED) - shared->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED; - if (iparams->flags & VB_INIT_FLAG_S3_RESUME) - shared->flags |= VBSD_BOOT_S3_RESUME; - if (iparams->flags & VB_INIT_FLAG_RO_NORMAL_SUPPORT) - shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; - if (iparams->flags & VB_INIT_FLAG_EC_SOFTWARE_SYNC) - shared->flags |= VBSD_EC_SOFTWARE_SYNC; - if (iparams->flags & VB_INIT_FLAG_EC_SLOW_UPDATE) - shared->flags |= VBSD_EC_SLOW_UPDATE; - - is_s3_resume = (iparams->flags & VB_INIT_FLAG_S3_RESUME ? 1 : 0); - - /* Check if the OS is requesting a debug S3 reset */ - VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &s3_debug_boot); - if (s3_debug_boot) { - if (is_s3_resume) { - VBDEBUG(("VbInit() requesting S3 debug boot\n")); - iparams->out_flags |= VB_INIT_OUT_S3_DEBUG_BOOT; - is_s3_resume = 0; /* Proceed as if this is a normal boot */ - } - - /* Clear the request even if this is a normal boot, since we don't - * want the NEXT S3 resume to be a debug reset unless the OS - * asserts the request again. */ - VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 0); - } - - /* If this isn't a S3 resume, read the current recovery request, then clear - * it so we don't get stuck in recovery mode. */ - if (!is_s3_resume) { - VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &recovery); - VBDEBUG(("VbInit sees recovery request = %d\n", recovery)); - if (VBNV_RECOVERY_NOT_REQUESTED != recovery) - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_NOT_REQUESTED); - } - - /* If the previous boot failed in the firmware somewhere outside of verified - * boot, and recovery is not requested for our own reasons, request recovery - * mode. This gives the calling firmware a way to request recovery if it - * finds something terribly wrong. */ - if (VBNV_RECOVERY_NOT_REQUESTED == recovery && - iparams->flags & VB_INIT_FLAG_PREVIOUS_BOOT_FAIL) { - recovery = VBNV_RECOVERY_RO_FIRMWARE; - } - - /* If recovery button is pressed, override recovery reason. Note that we - * do this in the S3 resume path also. */ - if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED) - recovery = VBNV_RECOVERY_RO_MANUAL; - - /* Copy current recovery reason to shared data. If we fail later on, it - * won't matter, since we'll just reboot. */ - shared->recovery_reason = (uint8_t)recovery; - VBDEBUG(("VbInit now sets shared->recovery_reason = %d\n", recovery)); - - /* If this is a S3 resume, resume the TPM. */ - /* FIXME: I think U-Boot won't ever ask us to do this. Can we remove it? */ - if (is_s3_resume) { - if (TPM_SUCCESS != RollbackS3Resume()) { - /* If we can't resume, just do a full reboot. No need to go to recovery - * mode here, since if the TPM is really broken we'll catch it on the - * next boot. */ - retval = VBERROR_TPM_S3_RESUME; - } - } else { - /* Should we pay attention to the TPM's virtual dev-switch? */ - if (iparams->flags & VB_INIT_FLAG_VIRTUAL_DEV_SWITCH) { - shared->flags |= VBSD_HONOR_VIRT_DEV_SWITCH; - has_virt_dev_switch = 1; - } - /* We always believe the HW dev-switch, since there's one attached to servo - * which may be active even on systems without a physical switch. The EC - * may also implement a fake dev-switch for testing. */ - if (iparams->flags & VB_INIT_FLAG_DEV_SWITCH_ON) - is_hw_dev = 1; - /* We may be asked to clear the virtual dev-switch at boot. */ - VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &disable_dev_request); - - /* Allow GBB flag to override dev switch */ - if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) - is_hw_dev = 1; - - /* Check if we've been explicitly asked to clear the TPM owner */ - VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, &clear_tpm_owner_request); - - VBPERFSTART("VB_TPMI"); - /* Initialize the TPM. If the developer mode state has changed since the - * last boot, we need to clear TPM ownership. If the TPM space is - * initialized by this call, the virtual dev-switch will be disabled by - * default) */ - tpm_status = RollbackFirmwareSetup(recovery, is_hw_dev, disable_dev_request, - clear_tpm_owner_request, - /* two outputs on success */ - &is_virt_dev, &tpm_version); - VBPERFEND("VB_TPMI"); - if (0 != tpm_status) { - VBDEBUG(("Unable to setup TPM and read firmware version (0x%x)\n", - tpm_status)); - - if (TPM_E_MUST_REBOOT == tpm_status) { - /* TPM wants to reboot into the same mode we're in now */ - VBDEBUG(("TPM requires a reboot.\n")); - if (!recovery) { - /* Not recovery mode. Just reboot (not into recovery). */ - retval = VBERROR_TPM_REBOOT_REQUIRED; - goto VbInit_exit; - } else if (VBNV_RECOVERY_RO_TPM_REBOOT != shared->recovery_reason) { - /* In recovery mode now, and we haven't requested a TPM reboot yet, - * so request one. */ - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_REBOOT); - retval = VBERROR_TPM_REBOOT_REQUIRED; - goto VbInit_exit; - } - } - - if (!recovery) { - VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, VBNV_RECOVERY_RO_TPM_S_ERROR); - VbNvSet(&vnc, VBNV_RECOVERY_SUBCODE, tpm_status); - retval = VBERROR_TPM_FIRMWARE_SETUP; - goto VbInit_exit; - } - } - - /* TPM setup succeeded. What did we learn? */ - shared->fw_version_tpm_start = tpm_version; - shared->fw_version_tpm = tpm_version; - if (is_hw_dev || (has_virt_dev_switch && is_virt_dev)) { - is_dev = 1; - shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; - } - if (disable_dev_request && !is_virt_dev) - VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 0); - if (clear_tpm_owner_request) { - VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, 0); - VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_DONE, 1); - } - } - - /* Allow BIOS to load arbitrary option ROMs? */ - if (gbb->flags & GBB_FLAG_LOAD_OPTION_ROMS) - iparams->out_flags |= VB_INIT_OUT_ENABLE_OPROM; - - /* The factory may need to boot custom OSes whenever the dev-switch is on */ - if (is_dev && (gbb->flags & GBB_FLAG_ENABLE_ALTERNATE_OS)) - iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS; - - /* Set output flags */ - if (VBNV_RECOVERY_NOT_REQUESTED != recovery) { - /* Requesting recovery mode */ - iparams->out_flags |= (VB_INIT_OUT_ENABLE_RECOVERY | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE); - } - else if (is_dev) { - /* Developer switch is on, so need to support dev mode */ - iparams->out_flags |= (VB_INIT_OUT_ENABLE_DEVELOPER | - VB_INIT_OUT_CLEAR_RAM | - VB_INIT_OUT_ENABLE_DISPLAY | - VB_INIT_OUT_ENABLE_USB_STORAGE); - /* ... which may or may not include custom OSes */ - VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &require_official_os); - if (!require_official_os) - iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS; - - /* Dev-mode needs the VGA option ROM to be loaded so it can display the - * scary boot screen. If we don't have it, we need to request it and - * reboot so it can be loaded. */ - if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) && - !(iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) { - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1); - retval = VBERROR_VGA_OPROM_MISMATCH; - VBDEBUG(("VbInit() needs oprom, doesn't have it\n")); - } - - } else { - /* Normal mode, so disable dev_boot_* flags. This ensures they will be - * initially disabled if the user later transitions back into developer - * mode. */ - VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 0); - VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 0); - VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 0); - - /* If we don't need the VGA option ROM but got it anyway, stop asking for - * it and reboot in case there's some vulnerability in using it. */ - if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) && - (iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) { - VbNvSet(&vnc, VBNV_OPROM_NEEDED, 0); - retval = VBERROR_VGA_OPROM_MISMATCH; - VBDEBUG(("VbInit() has oprom, doesn't need it\n")); - } - } - -VbInit_exit: - - /* Tear down NV storage */ - VbNvTeardown(&vnc); - if (vnc.raw_changed) - VbExNvStorageWrite(vnc.raw); - - VBDEBUG(("VbInit() output flags 0x%x\n", iparams->out_flags)); - - shared->timer_vb_init_exit = VbExGetTimer(); - - VBDEBUG(("VbInit() returning 0x%x\n", retval)); - return retval; +VbError_t VbInit(VbCommonParams *cparams, VbInitParams *iparams) +{ + VbSharedDataHeader *shared = + (VbSharedDataHeader *)cparams->shared_data_blob; + GoogleBinaryBlockHeader *gbb = + (GoogleBinaryBlockHeader *)cparams->gbb_data; + VbNvContext vnc; + VbError_t retval = VBERROR_SUCCESS; + uint32_t recovery = VBNV_RECOVERY_NOT_REQUESTED; + int is_s3_resume = 0; + uint32_t s3_debug_boot = 0; + uint32_t require_official_os = 0; + uint32_t tpm_version = 0; + uint32_t tpm_status = 0; + int has_virt_dev_switch = 0; + int is_hw_dev = 0; + int is_virt_dev = 0; + uint32_t disable_dev_request = 0; + uint32_t clear_tpm_owner_request = 0; + int is_dev = 0; + + VBDEBUG(("VbInit() input flags 0x%x\n", iparams->flags)); + + /* Initialize output flags */ + iparams->out_flags = 0; + + /* Set up NV storage */ + VbExNvStorageRead(vnc.raw); + VbNvSetup(&vnc); + + /* Initialize shared data structure */ + if (0 != VbSharedDataInit(shared, cparams->shared_data_size)) { + VBDEBUG(("Shared data init error\n")); + return VBERROR_INIT_SHARED_DATA; + } + + shared->timer_vb_init_enter = VbExGetTimer(); + + /* Copy some boot switch flags */ + /* TODO: in next refactor, just save in/out flags in VbSharedData */ + shared->flags = 0; + if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED) + shared->flags |= VBSD_BOOT_REC_SWITCH_ON; + if (iparams->flags & VB_INIT_FLAG_WP_ENABLED) + shared->flags |= VBSD_BOOT_FIRMWARE_WP_ENABLED; + if (iparams->flags & VB_INIT_FLAG_SW_WP_ENABLED) + shared->flags |= VBSD_BOOT_FIRMWARE_SW_WP_ENABLED; + if (iparams->flags & VB_INIT_FLAG_S3_RESUME) + shared->flags |= VBSD_BOOT_S3_RESUME; + if (iparams->flags & VB_INIT_FLAG_RO_NORMAL_SUPPORT) + shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT; + if (iparams->flags & VB_INIT_FLAG_EC_SOFTWARE_SYNC) + shared->flags |= VBSD_EC_SOFTWARE_SYNC; + if (iparams->flags & VB_INIT_FLAG_EC_SLOW_UPDATE) + shared->flags |= VBSD_EC_SLOW_UPDATE; + + is_s3_resume = (iparams->flags & VB_INIT_FLAG_S3_RESUME ? 1 : 0); + + /* Check if the OS is requesting a debug S3 reset */ + VbNvGet(&vnc, VBNV_DEBUG_RESET_MODE, &s3_debug_boot); + if (s3_debug_boot) { + if (is_s3_resume) { + VBDEBUG(("VbInit() requesting S3 debug boot\n")); + iparams->out_flags |= VB_INIT_OUT_S3_DEBUG_BOOT; + is_s3_resume = 0; /* Proceed as if normal boot */ + } + + /* + * Clear the request even if this is a normal boot, since we + * don't want the NEXT S3 resume to be a debug reset unless the + * OS asserts the request again. + */ + VbNvSet(&vnc, VBNV_DEBUG_RESET_MODE, 0); + } + + /* + * If this isn't a S3 resume, read the current recovery request, then + * clear it so we don't get stuck in recovery mode. + */ + if (!is_s3_resume) { + VbNvGet(&vnc, VBNV_RECOVERY_REQUEST, &recovery); + VBDEBUG(("VbInit sees recovery request = %d\n", recovery)); + if (VBNV_RECOVERY_NOT_REQUESTED != recovery) + VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, + VBNV_RECOVERY_NOT_REQUESTED); + } + + /* + * If the previous boot failed in the firmware somewhere outside of + * verified boot, and recovery is not requested for our own reasons, + * request recovery mode. This gives the calling firmware a way to + * request recovery if it finds something terribly wrong. + */ + if (VBNV_RECOVERY_NOT_REQUESTED == recovery && + iparams->flags & VB_INIT_FLAG_PREVIOUS_BOOT_FAIL) { + recovery = VBNV_RECOVERY_RO_FIRMWARE; + } + + /* + * If recovery button is pressed, override recovery reason. Note that + * we do this in the S3 resume path also. + */ + if (iparams->flags & VB_INIT_FLAG_REC_BUTTON_PRESSED) + recovery = VBNV_RECOVERY_RO_MANUAL; + + /* + * Copy current recovery reason to shared data. If we fail later on, it + * won't matter, since we'll just reboot. + */ + shared->recovery_reason = (uint8_t)recovery; + VBDEBUG(("VbInit now sets shared->recovery_reason = %d\n", recovery)); + + /* + * If this is a S3 resume, resume the TPM. + * + * FIXME: I think U-Boot won't ever ask us to do this. Can we remove + * it? + */ + if (is_s3_resume) { + if (TPM_SUCCESS != RollbackS3Resume()) { + /* + * If we can't resume, just do a full reboot. No need + * to go to recovery mode here, since if the TPM is + * really broken we'll catch it on the next boot. + */ + retval = VBERROR_TPM_S3_RESUME; + } + } else { + /* Should we pay attention to the TPM's virtual dev-switch? */ + if (iparams->flags & VB_INIT_FLAG_VIRTUAL_DEV_SWITCH) { + shared->flags |= VBSD_HONOR_VIRT_DEV_SWITCH; + has_virt_dev_switch = 1; + } + + /* + * We always believe the HW dev-switch, since there's one + * attached to servo which may be active even on systems + * without a physical switch. The EC may also implement a fake + * dev-switch for testing. + */ + if (iparams->flags & VB_INIT_FLAG_DEV_SWITCH_ON) + is_hw_dev = 1; + + /* We may be asked to clear the virtual dev-switch at boot. */ + VbNvGet(&vnc, VBNV_DISABLE_DEV_REQUEST, &disable_dev_request); + + /* Allow GBB flag to override dev switch */ + if (gbb->flags & GBB_FLAG_FORCE_DEV_SWITCH_ON) + is_hw_dev = 1; + + /* Have we been explicitly asked to clear the TPM owner? */ + VbNvGet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, + &clear_tpm_owner_request); + + VBPERFSTART("VB_TPMI"); + /* + * Initialize the TPM. If the developer mode state has changed + * since the last boot, we need to clear TPM ownership. If the + * TPM space is initialized by this call, the virtual + * dev-switch will be disabled by default) + */ + tpm_status = RollbackFirmwareSetup(recovery, is_hw_dev, + disable_dev_request, + clear_tpm_owner_request, + /* two outputs on success */ + &is_virt_dev, &tpm_version); + VBPERFEND("VB_TPMI"); + + if (0 != tpm_status) { + VBDEBUG(("Unable to setup TPM and read " + "firmware version (0x%x)\n", tpm_status)); + + if (TPM_E_MUST_REBOOT == tpm_status) { + /* + * TPM wants to reboot into the same mode we're + * in now + */ + VBDEBUG(("TPM requires a reboot.\n")); + if (!recovery) { + /* + * Not recovery mode. Just reboot (not + * into recovery). + */ + retval = VBERROR_TPM_REBOOT_REQUIRED; + goto VbInit_exit; + } else if (VBNV_RECOVERY_RO_TPM_REBOOT != + shared->recovery_reason) { + /* + * In recovery mode now, and we haven't + * requested a TPM reboot yet, so + * request one. + */ + VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, + VBNV_RECOVERY_RO_TPM_REBOOT); + retval = VBERROR_TPM_REBOOT_REQUIRED; + goto VbInit_exit; + } + } + + if (!recovery) { + VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, + VBNV_RECOVERY_RO_TPM_S_ERROR); + VbNvSet(&vnc, VBNV_RECOVERY_SUBCODE, + tpm_status); + retval = VBERROR_TPM_FIRMWARE_SETUP; + goto VbInit_exit; + } + } + + /* TPM setup succeeded. What did we learn? */ + shared->fw_version_tpm_start = tpm_version; + shared->fw_version_tpm = tpm_version; + if (is_hw_dev || (has_virt_dev_switch && is_virt_dev)) { + is_dev = 1; + shared->flags |= VBSD_BOOT_DEV_SWITCH_ON; + } + if (disable_dev_request && !is_virt_dev) + VbNvSet(&vnc, VBNV_DISABLE_DEV_REQUEST, 0); + if (clear_tpm_owner_request) { + VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_REQUEST, 0); + VbNvSet(&vnc, VBNV_CLEAR_TPM_OWNER_DONE, 1); + } + } + + /* Allow BIOS to load arbitrary option ROMs? */ + if (gbb->flags & GBB_FLAG_LOAD_OPTION_ROMS) + iparams->out_flags |= VB_INIT_OUT_ENABLE_OPROM; + + /* Factory may need to boot custom OSes when the dev-switch is on */ + if (is_dev && (gbb->flags & GBB_FLAG_ENABLE_ALTERNATE_OS)) + iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS; + + /* Set output flags */ + if (VBNV_RECOVERY_NOT_REQUESTED != recovery) { + /* Requesting recovery mode */ + iparams->out_flags |= (VB_INIT_OUT_ENABLE_RECOVERY | + VB_INIT_OUT_CLEAR_RAM | + VB_INIT_OUT_ENABLE_DISPLAY | + VB_INIT_OUT_ENABLE_USB_STORAGE); + } else if (is_dev) { + /* Developer switch is on, so need to support dev mode */ + iparams->out_flags |= (VB_INIT_OUT_ENABLE_DEVELOPER | + VB_INIT_OUT_CLEAR_RAM | + VB_INIT_OUT_ENABLE_DISPLAY | + VB_INIT_OUT_ENABLE_USB_STORAGE); + /* ... which may or may not include custom OSes */ + VbNvGet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, &require_official_os); + if (!require_official_os) + iparams->out_flags |= VB_INIT_OUT_ENABLE_ALTERNATE_OS; + + /* + * Dev-mode needs the VGA option ROM to be loaded so it can + * display the scary boot screen. If we don't have it, we need + * to request it and reboot so it can be loaded. + */ + if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) && + !(iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) { + VbNvSet(&vnc, VBNV_OPROM_NEEDED, 1); + retval = VBERROR_VGA_OPROM_MISMATCH; + VBDEBUG(("VbInit() needs oprom, doesn't have it\n")); + } + + } else { + /* + * Normal mode, so disable dev_boot_* flags. This ensures they + * will be initially disabled if the user later transitions + * back into developer mode. + */ + VbNvSet(&vnc, VBNV_DEV_BOOT_USB, 0); + VbNvSet(&vnc, VBNV_DEV_BOOT_LEGACY, 0); + VbNvSet(&vnc, VBNV_DEV_BOOT_SIGNED_ONLY, 0); + + /* + * If we don't need the VGA option ROM but got it anyway, stop + * asking for it and reboot in case there's some vulnerability + * in using it. + */ + if ((iparams->flags & VB_INIT_FLAG_OPROM_MATTERS) && + (iparams->flags & VB_INIT_FLAG_OPROM_LOADED)) { + VbNvSet(&vnc, VBNV_OPROM_NEEDED, 0); + retval = VBERROR_VGA_OPROM_MISMATCH; + VBDEBUG(("VbInit() has oprom, doesn't need it\n")); + } + } + + VbInit_exit: + + /* Tear down NV storage */ + VbNvTeardown(&vnc); + if (vnc.raw_changed) + VbExNvStorageWrite(vnc.raw); + + VBDEBUG(("VbInit() output flags 0x%x\n", iparams->out_flags)); + + shared->timer_vb_init_exit = VbExGetTimer(); + + VBDEBUG(("VbInit() returning 0x%x\n", retval)); + + return retval; } |