cbfs: read cbfs offset and size from sysinfo

This change allows libpayload to read cbfs offset and size from sysinfo.
Legacy way of locating cbfs reagion is still supported in case sysinfo
doesn't store the offset and the size.

BUG=none
BRANCH=master
TEST=tested on samus and smaug

Change-Id: I86434fd249467e7c90d59d6b82f0e6c514bc2d05
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 548a74b7a0758c3f9ba6809425d0fb9c6a5e9d7c
Original-Change-Id: I190d5545a65228483204bf1aa1cbf5a80db31ae0
Original-Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/296993
Original-Commit-Ready: Daisuke Nojiri <dnojiri@google.com>
Original-Tested-by: Daisuke Nojiri <dnojiri@google.com>
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11557
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Daisuke Nojiri 2015-09-02 10:53:13 -07:00 committed by Patrick Georgi
parent 158d00148f
commit 2ccb280f51
1 changed files with 46 additions and 26 deletions

View File

@ -47,6 +47,7 @@
#include <cbfs.h> #include <cbfs.h>
#include <string.h> #include <string.h>
#include <sysinfo.h>
/* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS /* returns a pointer to CBFS master header, or CBFS_HEADER_INVALID_ADDRESS
* on failure */ * on failure */
@ -94,12 +95,50 @@ const struct cbfs_header *cbfs_get_header(struct cbfs_media *media)
return header; return header;
} }
static int get_cbfs_range(uint32_t *offset, uint32_t *cbfs_end,
struct cbfs_media *media)
{
const struct cbfs_header *header;
if (lib_sysinfo.cbfs_offset && lib_sysinfo.cbfs_size) {
*offset = lib_sysinfo.cbfs_offset;
*cbfs_end = *offset + lib_sysinfo.cbfs_size;
return 0;
}
/*
* If sysinfo doesn't have offset or size, we read them from
* a master header.
*/
DEBUG("CBFS offset & size not found in sysinfo\n");
header = cbfs_get_header(media);
if (header == CBFS_HEADER_INVALID_ADDRESS)
return -1;
// Logical offset (for source media) of first file.
*offset = ntohl(header->offset);
*cbfs_end = ntohl(header->romsize);
#if IS_ENABLED(CONFIG_LP_ARCH_X86)
// resolve actual length of ROM used for CBFS components
// the bootblock size was not taken into account
*cbfs_end -= ntohl(header->bootblocksize);
// fine tune the length to handle alignment positioning.
// using (bootblock size) % align, to derive the
// number of bytes the bootblock is off from the alignment size.
if ((ntohl(header->bootblocksize) % CBFS_ALIGNMENT))
*cbfs_end -= (CBFS_ALIGNMENT -
(ntohl(header->bootblocksize) % CBFS_ALIGNMENT));
else
*cbfs_end -= 1;
#endif
return 0;
}
/* public API starts here*/ /* public API starts here*/
struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name) struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name)
{ {
const char *vardata; const char *vardata;
uint32_t offset, romsize, vardata_len; uint32_t offset, cbfs_end, vardata_len;
const struct cbfs_header *header;
struct cbfs_file file, *file_ptr; struct cbfs_file file, *file_ptr;
struct cbfs_media default_media; struct cbfs_media default_media;
@ -111,35 +150,16 @@ struct cbfs_file *cbfs_get_file(struct cbfs_media *media, const char *name)
} }
} }
if (CBFS_HEADER_INVALID_ADDRESS == (header = cbfs_get_header(media))) if (get_cbfs_range(&offset, &cbfs_end, media)) {
ERROR("Failed to find cbfs range\n");
return NULL; return NULL;
}
// Logical offset (for source media) of first file. DEBUG("CBFS location: 0x%x~0x%x\n", offset, cbfs_end);
offset = ntohl(header->offset);
romsize = ntohl(header->romsize);
// TODO Add a "size" in CBFS header for a platform independent way to
// determine the end of CBFS data.
#if IS_ENABLED(CONFIG_LP_ARCH_X86)
// resolve actual length of ROM used for CBFS components
// the bootblock size was not taken into account
romsize -= ntohl(header->bootblocksize);
// fine tune the length to handle alignment positioning.
// using (bootblock size) % align, to derive the
// number of bytes the bootblock is off from the alignment size.
if ((ntohl(header->bootblocksize) % CBFS_ALIGNMENT))
romsize -= (CBFS_ALIGNMENT -
(ntohl(header->bootblocksize) % CBFS_ALIGNMENT));
else
romsize -= 1;
#endif
DEBUG("CBFS location: 0x%x~0x%x\n", offset, romsize);
DEBUG("Looking for '%s' starting from 0x%x.\n", name, offset); DEBUG("Looking for '%s' starting from 0x%x.\n", name, offset);
media->open(media); media->open(media);
while (offset < romsize && while (offset < cbfs_end &&
media->read(media, &file, offset, sizeof(file)) == sizeof(file)) { media->read(media, &file, offset, sizeof(file)) == sizeof(file)) {
if (memcmp(CBFS_FILE_MAGIC, file.magic, if (memcmp(CBFS_FILE_MAGIC, file.magic,
sizeof(file.magic)) != 0) { sizeof(file.magic)) != 0) {