diff --git a/src/include/cbfs.h b/src/include/cbfs.h index f7067f9009..acdd55211f 100644 --- a/src/include/cbfs.h +++ b/src/include/cbfs.h @@ -140,15 +140,18 @@ enum cb_err cbfs_prog_stage_load(struct prog *prog); and instead use cbfs_alloc() so the file only needs to be looked up once. */ static inline size_t cbfs_get_size(const char *name); static inline size_t cbfs_ro_get_size(const char *name); +static inline size_t cbfs_unverified_area_get_size(const char *area, const char *name); /* Returns the type of a CBFS file, or CBFS_TYPE_NULL on error. Use cbfs_type_load() instead of this where possible to avoid looking up the file more than once. */ static inline enum cbfs_type cbfs_get_type(const char *name); static inline enum cbfs_type cbfs_ro_get_type(const char *name); +static inline enum cbfs_type cbfs_unverified_area_get_type(const char *area, const char *name); /* Check whether a CBFS file exists. */ static inline bool cbfs_file_exists(const char *name); static inline bool cbfs_ro_file_exists(const char *name); +static inline bool cbfs_unverified_area_file_exists(const char *area, const char *name); /********************************************************************************************** @@ -197,6 +200,9 @@ enum cb_err cbfs_init_boot_device(const struct cbfs_boot_device *cbd, enum cb_err _cbfs_boot_lookup(const char *name, bool force_ro, union cbfs_mdata *mdata, struct region_device *rdev); +enum cb_err _cbfs_unverified_area_lookup(const char *area, const char *name, + union cbfs_mdata *mdata, struct region_device *rdev); + void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg, size_t *size_out, bool force_ro, enum cbfs_type *type); @@ -370,6 +376,15 @@ static inline size_t cbfs_ro_get_size(const char *name) return be32toh(mdata.h.len); } +static inline size_t cbfs_unverified_area_get_size(const char *area, const char *name) +{ + union cbfs_mdata mdata; + struct region_device rdev; + if (_cbfs_unverified_area_lookup(area, name, &mdata, &rdev) != CB_SUCCESS) + return 0; + return be32toh(mdata.h.len); +} + static inline enum cbfs_type cbfs_get_type(const char *name) { union cbfs_mdata mdata; @@ -388,6 +403,15 @@ static inline enum cbfs_type cbfs_ro_get_type(const char *name) return be32toh(mdata.h.type); } +static inline enum cbfs_type cbfs_unverified_area_get_type(const char *area, const char *name) +{ + union cbfs_mdata mdata; + struct region_device rdev; + if (_cbfs_unverified_area_lookup(area, name, &mdata, &rdev) != CB_SUCCESS) + return CBFS_TYPE_NULL; + return be32toh(mdata.h.type); +} + static inline bool cbfs_file_exists(const char *name) { union cbfs_mdata mdata; @@ -406,4 +430,13 @@ static inline bool cbfs_ro_file_exists(const char *name) return true; } +static inline bool cbfs_unverified_area_file_exists(const char *area, const char *name) +{ + union cbfs_mdata mdata; + struct region_device rdev; + if (_cbfs_unverified_area_lookup(area, name, &mdata, &rdev) != CB_SUCCESS) + return false; + return true; +} + #endif diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 74314118cf..efd4243a69 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -96,6 +96,33 @@ enum cb_err _cbfs_boot_lookup(const char *name, bool force_ro, return CB_SUCCESS; } +enum cb_err _cbfs_unverified_area_lookup(const char *area, const char *name, union cbfs_mdata *mdata, struct region_device *rdev) +{ + struct region_device area_dev; + + if (fmap_locate_area_as_rdev(area, &area_dev)) { + printk(BIOS_ERR, "CBFS ERROR: Could not find region %s\n", area); + } + + size_t data_offset; + enum cb_err err; + + err = cbfs_lookup(&area_dev, name, mdata, &data_offset, NULL); + + if (err) { + if (err == CB_CBFS_NOT_FOUND) + printk(BIOS_WARNING, "CBFS: Could not find file %s in region %s\n", name, area); + else + printk(BIOS_ERR, "CBFS ERROR: Error %d when looking up '%s'\n", err, name); + return err; + } + + if (rdev_chain(rdev, &area_dev, data_offset, be32toh(mdata->h.len))) + return CB_ERR; + + return CB_SUCCESS; +} + void cbfs_unmap(void *mapping) { /*