diff options
-rw-r--r-- | src/include/cbfs.h | 20 | ||||
-rw-r--r-- | src/lib/assets.c | 9 | ||||
-rw-r--r-- | src/lib/cbfs.c | 43 | ||||
-rw-r--r-- | src/soc/intel/common/fsp_ramstage.c | 6 | ||||
-rw-r--r-- | src/soc/nvidia/tegra132/ccplex.c | 5 | ||||
-rw-r--r-- | src/soc/nvidia/tegra210/mtc.c | 5 | ||||
-rw-r--r-- | src/vendorcode/google/chromeos/vboot2/vboot_loader.c | 21 |
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, |