cbfs: add struct cbfsf

Now that cbfs is adding more metadata in the cbfs file
header one needs to access that metadata. Therefore,
add struct cbfsf which tracks the metadata and data
of the file separately. Note that stage and payload
metadata specific to itself is still contained within
the 'data' portion of a cbfs file. Update the cbfs
API to use struct cbfsf. Additionally, remove struct
cbfsd as there's nothing else associated with a cbfs
region aside from offset and size which tracked
by a region_device (thanks, CBFS_ALIGNMENT!).

BUG=None
BRANCH=None
TEST=Built and booted through end of ramstage on qemu armv7.
     Built and booted glados using Chrome OS.

Change-Id: I05486c6cf6cfcafa5c64b36324833b2374f763c2
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/11679
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
Aaron Durbin 2015-09-17 16:09:30 -05:00 committed by Patrick Georgi
parent 72bb66eb9c
commit 37a5d15da9
7 changed files with 68 additions and 41 deletions

View File

@ -30,8 +30,8 @@
* - cbfsd which is a descriptor for representing a cbfs instance * - cbfsd which is a descriptor for representing a cbfs instance
*/ */
/* Descriptor for cbfs lookup operations. */ /* Object representing cbfs files. */
struct cbfsd; struct cbfsf;
/*********************************************** /***********************************************
* Perform CBFS operations on the boot device. * * Perform CBFS operations on the boot device. *
@ -43,8 +43,7 @@ void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device);
* failure. */ * failure. */
void *cbfs_boot_load_stage_by_name(const char *name); void *cbfs_boot_load_stage_by_name(const char *name);
/* Locate file by name and optional type. Return 0 on success. < 0 on error. */ /* Locate file by name and optional type. Return 0 on success. < 0 on error. */
int cbfs_boot_locate(struct region_device *fh, const char *name, int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type);
uint32_t *type);
/* Map file into memory leaking the mapping. Only should be used when /* Map file into memory leaking the mapping. Only should be used when
* leaking mappings are a no-op. Returns NULL on error, else returns * leaking mappings are a no-op. Returns NULL on error, else returns
* the mapping and sets the size of the file. */ * the mapping and sets the size of the file. */
@ -55,7 +54,7 @@ int cbfs_prog_stage_load(struct prog *prog);
/* Locate file by name and optional type. Returns 0 on succcess else < 0 on /* Locate file by name and optional type. Returns 0 on succcess else < 0 on
* error.*/ * error.*/
int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs, int cbfs_locate(struct cbfsf *fh, const struct region_device *cbfs,
const char *name, uint32_t *type); const char *name, uint32_t *type);
/***************************************************************** /*****************************************************************
@ -64,10 +63,17 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
* API. * * API. *
*****************************************************************/ *****************************************************************/
struct cbfsd { struct cbfsf {
const struct region_device *rdev; struct region_device metadata;
struct region_device data;
}; };
static inline void cbfs_file_data(struct region_device *data,
const struct cbfsf *file)
{
rdev_chain(data, &file->data, 0, region_device_sz(&file->data));
}
/* The cbfs_props struct describes the properties associated with a CBFS. */ /* The cbfs_props struct describes the properties associated with a CBFS. */
struct cbfs_props { struct cbfs_props {
/* CBFS starts at the following offset within the boot region. */ /* CBFS starts at the following offset within the boot region. */

View File

@ -31,7 +31,14 @@
#if DEFAULT_CBFS_PROVIDER_PRESENT #if DEFAULT_CBFS_PROVIDER_PRESENT
static int cbfs_boot_asset_locate(struct asset *asset) static int cbfs_boot_asset_locate(struct asset *asset)
{ {
return cbfs_boot_locate(&asset->rdev, asset->name, NULL); struct cbfsf file;
if (cbfs_boot_locate(&file, asset_name(asset), NULL))
return -1;
cbfs_file_data(asset_rdev(asset), &file);
return 0;
} }
static const struct asset_provider cbfs_default_provider = { static const struct asset_provider cbfs_default_provider = {

View File

@ -35,9 +35,8 @@
#define DEBUG(x...) #define DEBUG(x...)
#endif #endif
int cbfs_boot_locate(struct region_device *fh, const char *name, uint32_t *type) int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type)
{ {
struct cbfsd cbfs;
struct region_device rdev; struct region_device rdev;
const struct region_device *boot_dev; const struct region_device *boot_dev;
struct cbfs_props props; struct cbfs_props props;
@ -56,35 +55,29 @@ int cbfs_boot_locate(struct region_device *fh, const char *name, uint32_t *type)
if (rdev_chain(&rdev, boot_dev, props.offset, props.size)) if (rdev_chain(&rdev, boot_dev, props.offset, props.size))
return -1; return -1;
cbfs.rdev = &rdev; return cbfs_locate(fh, &rdev, name, type);
return cbfs_locate(fh, &cbfs, name, type);
} }
void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size) void *cbfs_boot_map_with_leak(const char *name, uint32_t type, size_t *size)
{ {
struct region_device fh; struct cbfsf fh;
size_t fsize; size_t fsize;
if (cbfs_boot_locate(&fh, name, &type)) if (cbfs_boot_locate(&fh, name, &type))
return NULL; return NULL;
fsize = region_device_sz(&fh); fsize = region_device_sz(&fh.data);
if (size != NULL) if (size != NULL)
*size = fsize; *size = fsize;
return rdev_mmap(&fh, 0, fsize); return rdev_mmap(&fh.data, 0, fsize);
} }
int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs, int cbfs_locate(struct cbfsf *fh, const struct region_device *cbfs,
const char *name, uint32_t *type) const char *name, uint32_t *type)
{ {
size_t offset; size_t offset = 0;
const struct region_device *rd;
offset = 0;
rd = cbfs->rdev;
LOG("Locating '%s'\n", name); LOG("Locating '%s'\n", name);
@ -99,7 +92,7 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
DEBUG("Checking offset %zx\n", offset); DEBUG("Checking offset %zx\n", offset);
/* Can't read file. Nothing else to do but bail out. */ /* Can't read file. Nothing else to do but bail out. */
if (rdev_readat(rd, &file, offset, fsz) != fsz) if (rdev_readat(cbfs, &file, offset, fsz) != fsz)
break; break;
if (memcmp(file.magic, CBFS_FILE_MAGIC, sizeof(file.magic))) { if (memcmp(file.magic, CBFS_FILE_MAGIC, sizeof(file.magic))) {
@ -113,13 +106,13 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
file.offset = ntohl(file.offset); file.offset = ntohl(file.offset);
/* See if names match. */ /* See if names match. */
fname = rdev_mmap(rd, offset + fsz, file.offset - fsz); fname = rdev_mmap(cbfs, offset + fsz, file.offset - fsz);
if (fname == NULL) if (fname == NULL)
break; break;
name_match = !strcmp(fname, name); name_match = !strcmp(fname, name);
rdev_munmap(rd, fname); rdev_munmap(cbfs, fname);
if (!name_match) { if (!name_match) {
DEBUG(" Unmatched '%s' at %zx\n", fname, offset); DEBUG(" Unmatched '%s' at %zx\n", fname, offset);
@ -136,11 +129,13 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
} }
LOG("Found @ offset %zx size %x\n", offset, file.len); LOG("Found @ offset %zx size %x\n", offset, file.len);
/* File and type match. Create a chained region_device to /* File and type match. Keep track of both the metadata and
* represent the cbfs file. */ * the data for the file. */
if (rdev_chain(&fh->metadata, cbfs, offset, file.offset))
break;
offset += file.offset; offset += file.offset;
datasz = file.len; datasz = file.len;
if (rdev_chain(fh, rd, offset, datasz)) if (rdev_chain(&fh->data, cbfs, offset, datasz))
break; break;
/* Success. */ /* Success. */
@ -185,12 +180,16 @@ void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device)
void *cbfs_boot_load_stage_by_name(const char *name) void *cbfs_boot_load_stage_by_name(const char *name)
{ {
struct cbfsf fh;
struct prog stage = PROG_INIT(ASSET_UNKNOWN, name); struct prog stage = PROG_INIT(ASSET_UNKNOWN, name);
uint32_t type = CBFS_TYPE_STAGE; uint32_t type = CBFS_TYPE_STAGE;
if (cbfs_boot_locate(&stage.asset.rdev, name, &type)) if (cbfs_boot_locate(&fh, name, &type))
return NULL; return NULL;
/* Chain data portion in the prog. */
cbfs_file_data(prog_rdev(&stage), &fh);
if (cbfs_prog_stage_load(&stage)) if (cbfs_prog_stage_load(&stage))
return NULL; return NULL;
@ -204,7 +203,7 @@ int cbfs_prog_stage_load(struct prog *pstage)
void *entry; void *entry;
size_t fsize; size_t fsize;
size_t foffset; size_t foffset;
const struct region_device *fh = &pstage->asset.rdev; const struct region_device *fh = prog_rdev(pstage);
if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage)) if (rdev_readat(fh, &stage, 0, sizeof(stage)) != sizeof(stage))
return 0; return 0;

View File

@ -164,15 +164,15 @@ static void fsp_cache_save(struct prog *fsp)
static int fsp_find_and_relocate(struct prog *fsp) static int fsp_find_and_relocate(struct prog *fsp)
{ {
struct region_device fsp_rdev; struct cbfsf fsp_file;
uint32_t type = CBFS_TYPE_FSP; uint32_t type = CBFS_TYPE_FSP;
if (cbfs_boot_locate(&fsp_rdev, prog_name(fsp), &type)) { if (cbfs_boot_locate(&fsp_file, prog_name(fsp), &type)) {
printk(BIOS_ERR, "ERROR: Couldn't find fsp.bin in CBFS.\n"); printk(BIOS_ERR, "ERROR: Couldn't find fsp.bin in CBFS.\n");
return -1; return -1;
} }
if (fsp_relocate(fsp, &fsp_rdev)) { if (fsp_relocate(fsp, &fsp_file.data)) {
printk(BIOS_ERR, "ERROR: FSP relocation failed.\n"); printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
return -1; return -1;
} }

View File

@ -77,6 +77,7 @@ int ccplex_load_mts(void)
{ {
ssize_t nread; ssize_t nread;
struct stopwatch sw; struct stopwatch sw;
struct cbfsf mts_file;
struct region_device fh; struct region_device fh;
/* /*
@ -87,11 +88,13 @@ int ccplex_load_mts(void)
void * const mts = (void *)(uintptr_t)MTS_LOAD_ADDRESS; void * const mts = (void *)(uintptr_t)MTS_LOAD_ADDRESS;
stopwatch_init(&sw); stopwatch_init(&sw);
if (cbfs_boot_locate(&fh, MTS_FILE_NAME, NULL)) { if (cbfs_boot_locate(&mts_file, MTS_FILE_NAME, NULL)) {
printk(BIOS_DEBUG, "MTS file not found: %s\n", MTS_FILE_NAME); printk(BIOS_DEBUG, "MTS file not found: %s\n", MTS_FILE_NAME);
return -1; return -1;
} }
cbfs_file_data(&fh, &mts_file);
/* Read MTS file into the carveout region. */ /* Read MTS file into the carveout region. */
nread = rdev_readat(&fh, mts, 0, region_device_sz(&fh)); nread = rdev_readat(&fh, mts, 0, region_device_sz(&fh));

View File

@ -33,16 +33,19 @@ int tegra210_run_mtc(void)
{ {
ssize_t nread; ssize_t nread;
struct region_device fh; struct region_device fh;
struct cbfsf mtc_file;
void * const mtc = (void *)(uintptr_t)CONFIG_MTC_ADDRESS; void * const mtc = (void *)(uintptr_t)CONFIG_MTC_ADDRESS;
void *dvfs_table; void *dvfs_table;
size_t (*mtc_fw)(void **dvfs_table) = (void *)mtc; size_t (*mtc_fw)(void **dvfs_table) = (void *)mtc;
if (cbfs_boot_locate(&fh, "tegra_mtc.bin", NULL)) { if (cbfs_boot_locate(&mtc_file, "tegra_mtc.bin", NULL)) {
printk(BIOS_ERR, "MTC file not found: tegra_mtc.bin\n"); printk(BIOS_ERR, "MTC file not found: tegra_mtc.bin\n");
return -1; return -1;
} }
cbfs_file_data(&fh, &mtc_file);
/* Read MTC file into predefined region. */ /* Read MTC file into predefined region. */
nread = rdev_readat(&fh, mtc, 0, region_device_sz(&fh)); nread = rdev_readat(&fh, mtc, 0, region_device_sz(&fh));

View File

@ -73,6 +73,7 @@ static int vboot_active(struct asset *asset)
if (run_verification) { if (run_verification) {
verstage_main(); verstage_main();
} else if (verstage_should_load()) { } else if (verstage_should_load()) {
struct cbfsf file;
struct prog verstage = struct prog verstage =
PROG_INIT(ASSET_VERSTAGE, PROG_INIT(ASSET_VERSTAGE,
CONFIG_CBFS_PREFIX "/verstage"); CONFIG_CBFS_PREFIX "/verstage");
@ -80,9 +81,12 @@ static int vboot_active(struct asset *asset)
printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n"); printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
/* load verstage from RO */ /* load verstage from RO */
if (cbfs_boot_locate(prog_rdev(&verstage), if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
prog_name(&verstage), NULL) || die("failed to load verstage");
cbfs_prog_stage_load(&verstage))
cbfs_file_data(prog_rdev(&verstage), &file);
if (cbfs_prog_stage_load(&verstage))
die("failed to load verstage"); die("failed to load verstage");
/* verify and select a slot */ /* verify and select a slot */
@ -162,9 +166,14 @@ static int vboot_locate_by_components(const struct region_device *fw_main,
static int vboot_locate_by_multi_cbfs(const struct region_device *fw_main, static int vboot_locate_by_multi_cbfs(const struct region_device *fw_main,
struct asset *asset) struct asset *asset)
{ {
struct cbfsd cbfs; struct cbfsf file;
cbfs.rdev = fw_main;
return cbfs_locate(asset_rdev(asset), &cbfs, asset_name(asset), NULL); if (cbfs_locate(&file, fw_main, asset_name(asset), NULL))
return -1;
cbfs_file_data(asset_rdev(asset), &file);
return 0;
} }
static int vboot_asset_locate(const struct region_device *fw_main, static int vboot_asset_locate(const struct region_device *fw_main,