mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-11-24 18:25:10 +00:00
Originally, vboot1 code used VbExMalloc() and VbExFree() since it needed to talk to EFI firmware that didn't have standard malloc() and free(). Now, coreboot and depthcharge implement them as wrappers around those standard calls. vboot2 code already calls them directly, so let vboot1 code do that too. BUG=chromium:611535 BRANCH=none TEST=make runtests; emerge-kevin coreboot depthcharge Change-Id: I49ad0e32e38d278dc3589bfaf494bcf0e4b0a4bd Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/400905
201 lines
5.0 KiB
C
201 lines
5.0 KiB
C
/* 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.
|
|
*
|
|
* High-level firmware API for loading and verifying rewritable firmware.
|
|
* (Firmware portion)
|
|
*/
|
|
|
|
#include "sysincludes.h"
|
|
|
|
#include "bmpblk_header.h"
|
|
#include "region.h"
|
|
#include "gbb_access.h"
|
|
#include "gbb_header.h"
|
|
#include "load_kernel_fw.h"
|
|
#include "utility.h"
|
|
#include "vboot_api.h"
|
|
#include "vboot_struct.h"
|
|
|
|
static VbError_t VbRegionReadGbb(VbCommonParams *cparams, uint32_t offset,
|
|
uint32_t size, void *buf)
|
|
{
|
|
return VbRegionReadData(cparams, VB_REGION_GBB, offset, size, buf);
|
|
}
|
|
|
|
VbError_t VbGbbReadBmpHeader(VbCommonParams *cparams, BmpBlockHeader *hdr_ret)
|
|
{
|
|
BmpBlockHeader *hdr;
|
|
VbError_t ret;
|
|
|
|
if (!cparams)
|
|
return VBERROR_INVALID_GBB;
|
|
if (!cparams->bmp) {
|
|
GoogleBinaryBlockHeader *gbb = cparams->gbb;
|
|
|
|
if (0 == gbb->bmpfv_size)
|
|
return VBERROR_INVALID_GBB;
|
|
|
|
hdr = malloc(sizeof(*hdr));
|
|
ret = VbRegionReadGbb(cparams, gbb->bmpfv_offset,
|
|
sizeof(BmpBlockHeader), hdr);
|
|
if (ret) {
|
|
free(hdr);
|
|
return ret;
|
|
}
|
|
|
|
/* Sanity-check the bitmap block header */
|
|
if ((0 != memcmp(hdr->signature, BMPBLOCK_SIGNATURE,
|
|
BMPBLOCK_SIGNATURE_SIZE)) ||
|
|
(hdr->major_version > BMPBLOCK_MAJOR_VERSION) ||
|
|
((hdr->major_version == BMPBLOCK_MAJOR_VERSION) &&
|
|
(hdr->minor_version > BMPBLOCK_MINOR_VERSION))) {
|
|
VBDEBUG(("VbGbbReadBmpHeader(): "
|
|
"invalid/too new bitmap header\n"));
|
|
free(hdr);
|
|
return VBERROR_INVALID_BMPFV;
|
|
}
|
|
cparams->bmp = hdr;
|
|
}
|
|
|
|
*hdr_ret = *cparams->bmp;
|
|
return VBERROR_SUCCESS;
|
|
}
|
|
|
|
VbError_t VbRegionReadHWID(VbCommonParams *cparams, char *hwid,
|
|
uint32_t max_size)
|
|
{
|
|
GoogleBinaryBlockHeader *gbb;
|
|
VbError_t ret;
|
|
|
|
if (!max_size)
|
|
return VBERROR_INVALID_PARAMETER;
|
|
*hwid = '\0';
|
|
StrnAppend(hwid, "{INVALID}", max_size);
|
|
if (!cparams)
|
|
return VBERROR_INVALID_GBB;
|
|
|
|
gbb = cparams->gbb;
|
|
|
|
if (0 == gbb->hwid_size) {
|
|
VBDEBUG(("VbHWID(): invalid hwid size\n"));
|
|
return VBERROR_SUCCESS; /* oddly enough! */
|
|
}
|
|
|
|
if (gbb->hwid_size > max_size) {
|
|
VBDEBUG(("VbDisplayDebugInfo(): invalid hwid offset/size\n"));
|
|
return VBERROR_INVALID_PARAMETER;
|
|
}
|
|
ret = VbRegionReadGbb(cparams, gbb->hwid_offset, gbb->hwid_size, hwid);
|
|
if (ret)
|
|
return ret;
|
|
|
|
return VBERROR_SUCCESS;
|
|
}
|
|
|
|
VbError_t VbGbbReadImage(VbCommonParams *cparams,
|
|
uint32_t localization, uint32_t screen_index,
|
|
uint32_t image_num, ScreenLayout *layout,
|
|
ImageInfo *image_info, char **image_datap,
|
|
uint32_t *image_data_sizep)
|
|
{
|
|
uint32_t layout_offset, image_offset, data_offset, data_size;
|
|
GoogleBinaryBlockHeader *gbb;
|
|
BmpBlockHeader hdr;
|
|
void *data = NULL;
|
|
VbError_t ret;
|
|
|
|
if (!cparams)
|
|
return VBERROR_INVALID_GBB;
|
|
|
|
ret = VbGbbReadBmpHeader(cparams, &hdr);
|
|
if (ret)
|
|
return ret;
|
|
|
|
gbb = cparams->gbb;
|
|
layout_offset = gbb->bmpfv_offset + sizeof(BmpBlockHeader) +
|
|
localization * hdr.number_of_screenlayouts *
|
|
sizeof(ScreenLayout) +
|
|
screen_index * sizeof(ScreenLayout);
|
|
ret = VbRegionReadGbb(cparams, layout_offset, sizeof(*layout), layout);
|
|
if (ret)
|
|
return ret;
|
|
|
|
if (!layout->images[image_num].image_info_offset)
|
|
return VBERROR_NO_IMAGE_PRESENT;
|
|
|
|
image_offset = gbb->bmpfv_offset +
|
|
layout->images[image_num].image_info_offset;
|
|
ret = VbRegionReadGbb(cparams, image_offset, sizeof(*image_info),
|
|
image_info);
|
|
if (ret)
|
|
return ret;
|
|
|
|
data_offset = image_offset + sizeof(*image_info);
|
|
data_size = image_info->compressed_size;
|
|
if (data_size) {
|
|
void *orig_data;
|
|
|
|
data = malloc(image_info->compressed_size);
|
|
ret = VbRegionReadGbb(cparams, data_offset,
|
|
image_info->compressed_size, data);
|
|
if (ret) {
|
|
free(data);
|
|
return ret;
|
|
}
|
|
if (image_info->compression != COMPRESS_NONE) {
|
|
uint32_t inoutsize = image_info->original_size;
|
|
|
|
orig_data = malloc(image_info->original_size);
|
|
ret = VbExDecompress(data,
|
|
image_info->compressed_size,
|
|
image_info->compression,
|
|
orig_data, &inoutsize);
|
|
data_size = inoutsize;
|
|
free(data);
|
|
data = orig_data;
|
|
if (ret) {
|
|
free(data);
|
|
return ret;
|
|
}
|
|
}
|
|
}
|
|
|
|
*image_datap = data;
|
|
*image_data_sizep = data_size;
|
|
|
|
return VBERROR_SUCCESS;
|
|
}
|
|
|
|
#define OUTBUF_LEN 128
|
|
|
|
void VbRegionCheckVersion(VbCommonParams *cparams)
|
|
{
|
|
GoogleBinaryBlockHeader *gbb;
|
|
|
|
if (!cparams)
|
|
return;
|
|
|
|
gbb = cparams->gbb;
|
|
|
|
/*
|
|
* If GBB flags is nonzero, complain because that's something that the
|
|
* factory MUST fix before shipping. We only have to do this here,
|
|
* because it's obvious that something is wrong if we're not displaying
|
|
* screens from the GBB.
|
|
*/
|
|
if (gbb->major_version == GBB_MAJOR_VER && gbb->minor_version >= 1 &&
|
|
(gbb->flags != 0)) {
|
|
uint32_t used = 0;
|
|
char outbuf[OUTBUF_LEN];
|
|
|
|
*outbuf = '\0';
|
|
used += StrnAppend(outbuf + used, "gbb.flags is nonzero: 0x",
|
|
OUTBUF_LEN - used);
|
|
used += Uint64ToString(outbuf + used, OUTBUF_LEN - used,
|
|
gbb->flags, 16, 8);
|
|
used += StrnAppend(outbuf + used, "\n", OUTBUF_LEN - used);
|
|
(void)VbExDisplayDebugInfo(outbuf);
|
|
}
|
|
}
|