blob: 26ce3d5064d77153b618e4b9a2c97678158639d9 [file] [log] [blame]
/* Copyright (c) 2010 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.
*
* TEMPORARY stub for calling LoadFirmware() which looks like the old
* VerifyFirmwareDriver_f() call.
* (Firmware portion)
*/
#include "load_firmware_fw.h"
#include "utility.h"
#define BOOT_FIRMWARE_A_CONTINUE 1
#define BOOT_FIRMWARE_B_CONTINUE 2
#define BOOT_FIRMWARE_RECOVERY_CONTINUE 3
typedef struct CallerInternal {
uint8_t *firmwareA;
uint64_t firmwareA_size;
uint8_t *firmwareB;
uint64_t firmwareB_size;
} CallerInternal;
int GetFirmwareBody(LoadFirmwareParams* params, uint64_t index) {
CallerInternal* ci = (CallerInternal*)params->caller_internal;
uint8_t *fw;
uint64_t size;
/* In a real implementation, GetFirmwareBody() should be what reads
* and decompresses the firmware volume. In this temporary hack, we
* just pass the pointer which we got from
* VerifyFirmwareDriver_Stub(). */
switch(index) {
case 0:
size = ci->firmwareA_size;
fw = ci->firmwareA;
break;
case 1:
size = ci->firmwareB_size;
fw = ci->firmwareB;
break;
default:
/* Anything else is invalid */
return 1;
}
/* Need to call UpdateFirmwareBodyHash() with the firmware volume
* data. In this temporary hack, the FV is already decompressed, so
* we pass in the entire volume at once. In a real implementation,
* you should call this as the FV is being decompressed. */
UpdateFirmwareBodyHash(params, fw, size);
/* Success */
return 0;
}
/* Where you're currently calling VerifyFirmwareDriver_f(), call this
* function instead. Because you still need to read in both firmware
* volumes, this call will still be slow. Once we reach feature
* complete, you should modify your code to call LoadImage()
* directly. */
int VerifyFirmwareDriver_stub(uint8_t* gbb_data,
uint64_t gbb_size,
uint8_t* verification_headerA,
uint8_t* firmwareA,
uint8_t* verification_headerB,
uint8_t* firmwareB) {
int rv;
CallerInternal ci;
LoadFirmwareParams p;
VbNvContext vnc;
/* TODO: YOU SHOULD CALL LoadFirmwareSetup() AS SOON AS THE TPM
* INTERFACE IS AVAILABLE */
LoadFirmwareSetup();
/* Copy the firmware volume pointers to our global variables. */
ci.firmwareA = firmwareA;
ci.firmwareB = firmwareB;
/* TODO: YOU NEED TO PASS IN THE FIRMWARE VOLUME SIZES SOMEHOW */
ci.firmwareA_size = 0;
ci.firmwareB_size = 0;
/* TODO: YOU NEED TO LOAD vnc.raw[] FROM NON-VOLATILE STORAGE */
/* Set up the params for LoadFirmware() */
p.caller_internal = &ci;
p.gbb_data = gbb_data;
p.gbb_size = gbb_size;
p.verification_block_0 = verification_headerA;
p.verification_block_1 = verification_headerB;
p.nv_context = &vnc;
/* Allocate a shared data buffer */
p.shared_data_blob = Malloc(VB_SHARED_DATA_REC_SIZE);
p.shared_data_size = VB_SHARED_DATA_REC_SIZE;
/* TODO: YOU NEED TO SET THE BOOT FLAGS SOMEHOW */
p.boot_flags = 0;
/* Call LoadFirmware() */
rv = LoadFirmware(&p);
if (vnc.raw_changed) {
/* TODO: YOU NEED TO SAVE vnc.raw TO NON-VOLATILE STORAGE */
}
if (LOAD_FIRMWARE_SUCCESS == rv) {
/* TODO: YOU NEED TO KEEP TRACK OF p.shared_data_blob AND
* p.shared_data_size SO YOU CAN PASS THEM TO LoadKernel(). */
return (0 == p.firmware_index ? BOOT_FIRMWARE_A_CONTINUE :
BOOT_FIRMWARE_B_CONTINUE);
} else {
/* Error */
return BOOT_FIRMWARE_RECOVERY_CONTINUE;
}
}