| /* 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 "utility.h" |
| #include "vboot_api.h" |
| #include "vboot_common.h" |
| #include "vboot_nvstorage.h" |
| |
| |
| VbError_t VbSelectFirmware(VbCommonParams* cparams, |
| VbSelectFirmwareParams* fparams) { |
| VbSharedDataHeader* shared = (VbSharedDataHeader*)cparams->shared_data_blob; |
| LoadFirmwareParams p; |
| VbNvContext vnc; |
| int rv; |
| |
| /* Start timer */ |
| shared->timer_vb_select_firmware_enter = VbExGetTimer(); |
| |
| /* If recovery is requested, go straight to recovery without checking the |
| * RW firmware. */ |
| if (VBNV_RECOVERY_NOT_REQUESTED != shared->recovery_reason) { |
| VBDEBUG(("VbSelectFirmware() detected recovery request, reason=%d.\n", |
| (int)shared->recovery_reason)); |
| shared->timer_vb_select_firmware_exit = VbExGetTimer(); |
| fparams->selected_firmware = VB_SELECT_FIRMWARE_RECOVERY; |
| return VBERROR_SUCCESS; |
| } |
| |
| /* Copy parameters from wrapper API structs to old struct */ |
| p.gbb_data = cparams->gbb_data; |
| p.gbb_size = cparams->gbb_size; |
| p.shared_data_blob = cparams->shared_data_blob; |
| p.shared_data_size = cparams->shared_data_size; |
| p.nv_context = &vnc; |
| |
| p.verification_block_0 = fparams->verification_block_A; |
| p.verification_block_1 = fparams->verification_block_B; |
| p.verification_size_0 = fparams->verification_size_A; |
| p.verification_size_1 = fparams->verification_size_B; |
| |
| /* Load NV storage */ |
| VbExNvStorageRead(vnc.raw); |
| vnc.raw_changed = 0; |
| |
| /* Use vboot_context and caller_internal to link our params with |
| * LoadFirmware()'s params. */ |
| // TODO: clean up LoadFirmware() to use common params? |
| p.caller_internal = (void*)cparams; |
| cparams->vboot_context = (void*)&p; |
| |
| /* Chain to LoadFirmware() */ |
| rv = LoadFirmware(&p); |
| |
| /* Save NV storage, if necessary */ |
| if (vnc.raw_changed) |
| VbExNvStorageWrite(vnc.raw); |
| |
| /* Copy amount of used shared data back to the wrapper API struct */ |
| cparams->shared_data_size = (uint32_t)p.shared_data_size; |
| |
| /* Stop timer */ |
| shared->timer_vb_select_firmware_exit = VbExGetTimer(); |
| |
| /* Translate return codes */ |
| if (LOAD_FIRMWARE_SUCCESS == rv) { |
| if (shared->flags & VBSD_LF_USE_RO_NORMAL) { |
| /* Request the read-only normal/dev code path */ |
| fparams->selected_firmware = VB_SELECT_FIRMWARE_READONLY; |
| } else if (0 == shared->firmware_index) |
| fparams->selected_firmware = VB_SELECT_FIRMWARE_A; |
| else |
| fparams->selected_firmware = VB_SELECT_FIRMWARE_B; |
| return VBERROR_SUCCESS; |
| |
| } else if (LOAD_FIRMWARE_REBOOT == rv) { |
| /* Reboot in the same mode we just left; copy the recovery reason */ |
| VbNvSetup(&vnc); |
| VbNvSet(&vnc, VBNV_RECOVERY_REQUEST, shared->recovery_reason); |
| VbNvTeardown(&vnc); |
| if (vnc.raw_changed) |
| VbExNvStorageWrite(vnc.raw); |
| return 1; |
| |
| } else { |
| /* Other error */ |
| return 1; |
| } |
| } |
| |
| |
| /* TODO: Move this inside vboot_firmware.c; for now this just translates to |
| * the original function call. */ |
| void VbUpdateFirmwareBodyHash(VbCommonParams* cparams, uint8_t* data, |
| uint32_t size) { |
| LoadFirmwareParams* lfparams = (LoadFirmwareParams*)cparams->vboot_context; |
| |
| UpdateFirmwareBodyHash(lfparams, data, size); |
| } |
| |
| |
| /* Translation layer from LoadFirmware()'s GetFirmwareBody() to the new |
| * wrapper API call. |
| * |
| * TODO: call directly from LoadFirmware() */ |
| int GetFirmwareBody(LoadFirmwareParams* lfparams, uint64_t index) { |
| VbCommonParams* cparams = (VbCommonParams*)lfparams->caller_internal; |
| VbError_t rv; |
| |
| rv = VbExHashFirmwareBody(cparams, (index ? VB_SELECT_FIRMWARE_B : |
| VB_SELECT_FIRMWARE_A)); |
| return (VBERROR_SUCCESS == rv ? 0 : 1); |
| } |