summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/cbfs.h20
-rw-r--r--src/lib/assets.c9
-rw-r--r--src/lib/cbfs.c43
-rw-r--r--src/soc/intel/common/fsp_ramstage.c6
-rw-r--r--src/soc/nvidia/tegra132/ccplex.c5
-rw-r--r--src/soc/nvidia/tegra210/mtc.c5
-rw-r--r--src/vendorcode/google/chromeos/vboot2/vboot_loader.c21
7 files changed, 68 insertions, 41 deletions
diff --git a/src/include/cbfs.h b/src/include/cbfs.h
index f23a82a173..5d60716ef4 100644
--- a/src/include/cbfs.h
+++ b/src/include/cbfs.h
@@ -30,8 +30,8 @@
* - cbfsd which is a descriptor for representing a cbfs instance
*/
-/* Descriptor for cbfs lookup operations. */
-struct cbfsd;
+/* Object representing cbfs files. */
+struct cbfsf;
/***********************************************
* Perform CBFS operations on the boot device. *
@@ -43,8 +43,7 @@ void *cbfs_boot_map_optionrom(uint16_t vendor, uint16_t device);
* failure. */
void *cbfs_boot_load_stage_by_name(const char *name);
/* 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,
- uint32_t *type);
+int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type);
/* Map file into memory leaking the mapping. Only should be used when
* leaking mappings are a no-op. Returns NULL on error, else returns
* 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
* 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);
/*****************************************************************
@@ -64,10 +63,17 @@ int cbfs_locate(struct region_device *fh, const struct cbfsd *cbfs,
* API. *
*****************************************************************/
-struct cbfsd {
- const struct region_device *rdev;
+struct cbfsf {
+ 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. */
struct cbfs_props {
/* CBFS starts at the following offset within the boot region. */
diff --git a/src/lib/assets.c b/src/lib/assets.c
index 656f0b1e2b..0115243b22 100644
--- a/src/lib/assets.c
+++ b/src/lib/assets.c
@@ -31,7 +31,14 @@
#if DEFAULT_CBFS_PROVIDER_PRESENT
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 = {
diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c
index abc40770af..05b939cdfe 100644
--- a/src/lib/cbfs.c
+++ b/src/lib/cbfs.c
@@ -35,9 +35,8 @@
#define DEBUG(x...)
#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;
const struct region_device *boot_dev;
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))
return -1;
- cbfs.rdev = &rdev;
-
- return cbfs_locate(fh, &cbfs, name, type);
+ return cbfs_locate(fh, &rdev, name, type);
}
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;
if (cbfs_boot_locate(&fh, name, &type))
return NULL;
- fsize = region_device_sz(&fh);
+ fsize = region_device_sz(&fh.data);
if (size != NULL)
*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)
{
- size_t offset;
- const struct region_device *rd;
-
- offset = 0;
- rd = cbfs->rdev;
+ size_t offset = 0;
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);
/* 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;
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);
/* 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)
break;
name_match = !strcmp(fname, name);
- rdev_munmap(rd, fname);
+ rdev_munmap(cbfs, fname);
if (!name_match) {
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);
- /* File and type match. Create a chained region_device to
- * represent the cbfs file. */
+ /* File and type match. Keep track of both the metadata and
+ * the data for the file. */
+ if (rdev_chain(&fh->metadata, cbfs, offset, file.offset))
+ break;
offset += file.offset;
datasz = file.len;
- if (rdev_chain(fh, rd, offset, datasz))
+ if (rdev_chain(&fh->data, cbfs, offset, datasz))
break;
/* 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)
{
+ struct cbfsf fh;
struct prog stage = PROG_INIT(ASSET_UNKNOWN, name);
uint32_t type = CBFS_TYPE_STAGE;
- if (cbfs_boot_locate(&stage.asset.rdev, name, &type))
+ if (cbfs_boot_locate(&fh, name, &type))
return NULL;
+ /* Chain data portion in the prog. */
+ cbfs_file_data(prog_rdev(&stage), &fh);
+
if (cbfs_prog_stage_load(&stage))
return NULL;
@@ -204,7 +203,7 @@ int cbfs_prog_stage_load(struct prog *pstage)
void *entry;
size_t fsize;
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))
return 0;
diff --git a/src/soc/intel/common/fsp_ramstage.c b/src/soc/intel/common/fsp_ramstage.c
index d1f2e49aff..c8dfad1f83 100644
--- a/src/soc/intel/common/fsp_ramstage.c
+++ b/src/soc/intel/common/fsp_ramstage.c
@@ -164,15 +164,15 @@ static void fsp_cache_save(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;
- 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");
return -1;
}
- if (fsp_relocate(fsp, &fsp_rdev)) {
+ if (fsp_relocate(fsp, &fsp_file.data)) {
printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
return -1;
}
diff --git a/src/soc/nvidia/tegra132/ccplex.c b/src/soc/nvidia/tegra132/ccplex.c
index e133b48482..b003ec1080 100644
--- a/src/soc/nvidia/tegra132/ccplex.c
+++ b/src/soc/nvidia/tegra132/ccplex.c
@@ -77,6 +77,7 @@ int ccplex_load_mts(void)
{
ssize_t nread;
struct stopwatch sw;
+ struct cbfsf mts_file;
struct region_device fh;
/*
@@ -87,11 +88,13 @@ int ccplex_load_mts(void)
void * const mts = (void *)(uintptr_t)MTS_LOAD_ADDRESS;
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);
return -1;
}
+ cbfs_file_data(&fh, &mts_file);
+
/* Read MTS file into the carveout region. */
nread = rdev_readat(&fh, mts, 0, region_device_sz(&fh));
diff --git a/src/soc/nvidia/tegra210/mtc.c b/src/soc/nvidia/tegra210/mtc.c
index fb6c9cbdd7..b402a14cd3 100644
--- a/src/soc/nvidia/tegra210/mtc.c
+++ b/src/soc/nvidia/tegra210/mtc.c
@@ -33,16 +33,19 @@ int tegra210_run_mtc(void)
{
ssize_t nread;
struct region_device fh;
+ struct cbfsf mtc_file;
void * const mtc = (void *)(uintptr_t)CONFIG_MTC_ADDRESS;
void *dvfs_table;
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");
return -1;
}
+ cbfs_file_data(&fh, &mtc_file);
+
/* Read MTC file into predefined region. */
nread = rdev_readat(&fh, mtc, 0, region_device_sz(&fh));
diff --git a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
index 40f3fa3468..8517a30999 100644
--- a/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
+++ b/src/vendorcode/google/chromeos/vboot2/vboot_loader.c
@@ -73,6 +73,7 @@ static int vboot_active(struct asset *asset)
if (run_verification) {
verstage_main();
} else if (verstage_should_load()) {
+ struct cbfsf file;
struct prog verstage =
PROG_INIT(ASSET_VERSTAGE,
CONFIG_CBFS_PREFIX "/verstage");
@@ -80,9 +81,12 @@ static int vboot_active(struct asset *asset)
printk(BIOS_DEBUG, "VBOOT: Loading verstage.\n");
/* load verstage from RO */
- if (cbfs_boot_locate(prog_rdev(&verstage),
- prog_name(&verstage), NULL) ||
- cbfs_prog_stage_load(&verstage))
+ if (cbfs_boot_locate(&file, prog_name(&verstage), NULL))
+ die("failed to load verstage");
+
+ cbfs_file_data(prog_rdev(&verstage), &file);
+
+ if (cbfs_prog_stage_load(&verstage))
die("failed to load verstage");
/* 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,
struct asset *asset)
{
- struct cbfsd cbfs;
- cbfs.rdev = fw_main;
- return cbfs_locate(asset_rdev(asset), &cbfs, asset_name(asset), NULL);
+ struct cbfsf file;
+
+ 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,