mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-23 17:55:01 +00:00
As shipped, H2C only loads the option ROM for the built-in video, and that only when it needs display the BIOS warning screens. By setting a flag in the GBB, you can allow all option ROMs to be loaded: Note that we'll never enable this ourselves (and there's a factory test to ensure that*) because it executes non-verified code. But if a customer wants to void their warranty and set this flag in the read-only flash so they can install and use other PCI devices, they should be able to do so. BUG=chrome-os-partner:6148 TEST=none The only way to test this is to use a BIOS that was compiled with serial debugging enabled, so there's nothing for QA to do. If you have such a BIOS, you can see the difference like so: flashrom -r oldbios.bin gbb_utility -s --flags=2 oldbios.bin newbios.bin flashrom -w newbios.bin <reboot> When bit 1 of the GBB flags is 0, you'll see these lines in the serial output: LoadOpRomImage-->GetSystemConfigurationTable Status = Success LoadOpRomImage-->GetH2cBootMode Status = Success When bit 1 of the GBB flags is 1, you'll see these lines in the serial output: LoadOpRomImage-->GetSystemConfigurationTable Status = Success LoadOpRomImage-->GetH2cBootMode Status = Success LoadOpRomImage-->PCI OpRom on 1.0.0 is allowed!!! This happens in any boot mode (normal, developer, recovery). -- *The factory test for GBB zero flags is gft_clear_gbb_flags.sh, in src/platform/factory_test_tools Change-Id: I31a10cc9d562b4b83669ca8a114b60e87ae28b0a Reviewed-on: https://gerrit.chromium.org/gerrit/11505 Tested-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Gaurav Shah <gauravsh@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org>
138 lines
4.8 KiB
C
138 lines
4.8 KiB
C
/* Copyright (c) 2011 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.
|
|
*
|
|
* High-level firmware wrapper API - entry points for init, firmware selection
|
|
*/
|
|
|
|
#include "gbb_header.h"
|
|
#include "load_firmware_fw.h"
|
|
#include "rollback_index.h"
|
|
#include "utility.h"
|
|
#include "vboot_api.h"
|
|
#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;
|
|
|
|
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 boot switch flags */
|
|
shared->flags = 0;
|
|
if (iparams->flags & VB_INIT_FLAG_DEV_SWITCH_ON)
|
|
shared->flags |= VBSD_BOOT_DEV_SWITCH_ON;
|
|
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_S3_RESUME)
|
|
shared->flags |= VBSD_BOOT_S3_RESUME;
|
|
if (iparams->flags & VB_INIT_FLAG_RO_NORMAL_SUPPORT)
|
|
shared->flags |= VBSD_BOOT_RO_NORMAL_SUPPORT;
|
|
|
|
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);
|
|
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;
|
|
|
|
/* 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 (iparams->flags & VB_INIT_FLAG_DEV_SWITCH_ON) {
|
|
/* Developer switch is on, so need to support dev mode */
|
|
iparams->out_flags |= (VB_INIT_OUT_CLEAR_RAM |
|
|
VB_INIT_OUT_ENABLE_DISPLAY |
|
|
VB_INIT_OUT_ENABLE_USB_STORAGE);
|
|
}
|
|
|
|
/* Allow BIOS to load arbitrary option ROMs? */
|
|
if (gbb->flags & GBB_FLAG_LOAD_OPTION_ROMS)
|
|
iparams->out_flags |= VB_INIT_OUT_ENABLE_OPROM;
|
|
|
|
/* copy current recovery reason to shared data */
|
|
shared->recovery_reason = (uint8_t)recovery;
|
|
|
|
/* If this is a S3 resume, resume the TPM */
|
|
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;
|
|
}
|
|
}
|
|
|
|
/* 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();
|
|
|
|
return retval;
|
|
}
|