cbfs: Add helper functions to look up size and type of a file
This patch adds cbfs_get_size() and cbfs_get_type() helper functions (and _ro_ variations) to look up the size or type of a CBFS file without loading it. Generally, use of these should be discouraged because that tends to mean that the file needs to be looked up more than once, and cbfs_alloc() or cbfs_type_load() are usually the more efficient alternative... but sometimes they're unavoidable, so we might as well offer them. Also remove the <cbfs_private.h> header which had already become sort of unnecessary with previous changes. cbfs_boot_lookup() is now exported in <cbfs.h> for use in inlines, but should not be used directly by other files (and is prefixed with an underscore to highlight that). Signed-off-by: Julius Werner <jwerner@chromium.org> Change-Id: I8092d8f6e04bdfb4df6c626dc7d42b402fe0a8ba Reviewed-on: https://review.coreboot.org/c/coreboot/+/59312 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Werner Zeh <werner.zeh@siemens.com> Reviewed-by: Jakub Czapiga <jacz@semihalf.com> Reviewed-by: Lean Sheng Tan <lean.sheng.tan@intel.com>
This commit is contained in:
parent
9a640c0f69
commit
57d4bc63f0
|
@ -7,6 +7,7 @@
|
||||||
#include <commonlib/bsd/cbfs_mdata.h>
|
#include <commonlib/bsd/cbfs_mdata.h>
|
||||||
#include <commonlib/cbfs.h>
|
#include <commonlib/cbfs.h>
|
||||||
#include <commonlib/mem_pool.h>
|
#include <commonlib/mem_pool.h>
|
||||||
|
#include <commonlib/region.h>
|
||||||
#include <program_loading.h>
|
#include <program_loading.h>
|
||||||
#include <types.h>
|
#include <types.h>
|
||||||
#include <vb2_sha.h>
|
#include <vb2_sha.h>
|
||||||
|
@ -119,6 +120,20 @@ void cbfs_unmap(void *mapping);
|
||||||
/* Load stage into memory filling in prog. Return 0 on success. < 0 on error. */
|
/* Load stage into memory filling in prog. Return 0 on success. < 0 on error. */
|
||||||
int cbfs_prog_stage_load(struct prog *prog);
|
int cbfs_prog_stage_load(struct prog *prog);
|
||||||
|
|
||||||
|
/* Returns the size of a CBFS file, or 0 on error. Avoid using this function to allocate space,
|
||||||
|
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);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
* BOOT DEVICE HELPER APIs *
|
* BOOT DEVICE HELPER APIs *
|
||||||
|
@ -173,6 +188,9 @@ int cbfs_locate_file_in_region(struct cbfsf *fh, const char *region_name,
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
* INTERNAL HELPERS FOR INLINES, DO NOT USE. *
|
* INTERNAL HELPERS FOR INLINES, DO NOT USE. *
|
||||||
**********************************************************************************************/
|
**********************************************************************************************/
|
||||||
|
cb_err_t _cbfs_boot_lookup(const char *name, bool force_ro,
|
||||||
|
union cbfs_mdata *mdata, struct region_device *rdev);
|
||||||
|
|
||||||
void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
|
void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
|
||||||
size_t *size_out, bool force_ro, enum cbfs_type *type);
|
size_t *size_out, bool force_ro, enum cbfs_type *type);
|
||||||
|
|
||||||
|
@ -287,4 +305,58 @@ static inline void *cbfs_ro_type_cbmem_alloc(const char *name, uint32_t cbmem_id
|
||||||
size_out, type);
|
size_out, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline size_t cbfs_get_size(const char *name)
|
||||||
|
{
|
||||||
|
union cbfs_mdata mdata;
|
||||||
|
struct region_device rdev;
|
||||||
|
if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
|
||||||
|
return 0;
|
||||||
|
return be32toh(mdata.h.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t cbfs_ro_get_size(const char *name)
|
||||||
|
{
|
||||||
|
union cbfs_mdata mdata;
|
||||||
|
struct region_device rdev;
|
||||||
|
if (_cbfs_boot_lookup(name, true, &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;
|
||||||
|
struct region_device rdev;
|
||||||
|
if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
|
||||||
|
return CBFS_TYPE_NULL;
|
||||||
|
return be32toh(mdata.h.type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline enum cbfs_type cbfs_ro_get_type(const char *name)
|
||||||
|
{
|
||||||
|
union cbfs_mdata mdata;
|
||||||
|
struct region_device rdev;
|
||||||
|
if (_cbfs_boot_lookup(name, true, &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;
|
||||||
|
struct region_device rdev;
|
||||||
|
if (_cbfs_boot_lookup(name, false, &mdata, &rdev) != CB_SUCCESS)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool cbfs_ro_file_exists(const char *name)
|
||||||
|
{
|
||||||
|
union cbfs_mdata mdata;
|
||||||
|
struct region_device rdev;
|
||||||
|
if (_cbfs_boot_lookup(name, true, &mdata, &rdev) != CB_SUCCESS)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
||||||
|
|
||||||
#ifndef _CBFS_PRIVATE_H_
|
|
||||||
#define _CBFS_PRIVATE_H_
|
|
||||||
|
|
||||||
#include <commonlib/bsd/cbfs_private.h>
|
|
||||||
#include <commonlib/region.h>
|
|
||||||
#include <types.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This header contains low-level CBFS APIs that should only be used by code
|
|
||||||
* that really needs this level of access. Most code (particularly platform
|
|
||||||
* code) should use the higher-level CBFS APIs in <cbfs.h>. Code using these
|
|
||||||
* APIs needs to take special care to ensure CBFS file data is verified (in a
|
|
||||||
* TOCTOU-safe manner) before access (TODO: add details on how to do this once
|
|
||||||
* file verification code is in).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Find by name, load metadata into |mdata| and chain file data to |rdev|. */
|
|
||||||
cb_err_t cbfs_boot_lookup(const char *name, bool force_ro,
|
|
||||||
union cbfs_mdata *mdata, struct region_device *rdev);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -3,8 +3,8 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <boot_device.h>
|
#include <boot_device.h>
|
||||||
#include <cbfs.h>
|
#include <cbfs.h>
|
||||||
#include <cbfs_private.h>
|
|
||||||
#include <cbmem.h>
|
#include <cbmem.h>
|
||||||
|
#include <commonlib/bsd/cbfs_private.h>
|
||||||
#include <commonlib/bsd/compression.h>
|
#include <commonlib/bsd/compression.h>
|
||||||
#include <commonlib/endian.h>
|
#include <commonlib/endian.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
@ -35,7 +35,7 @@ static void switch_to_postram_cache(int unused)
|
||||||
}
|
}
|
||||||
ROMSTAGE_CBMEM_INIT_HOOK(switch_to_postram_cache);
|
ROMSTAGE_CBMEM_INIT_HOOK(switch_to_postram_cache);
|
||||||
|
|
||||||
cb_err_t cbfs_boot_lookup(const char *name, bool force_ro,
|
cb_err_t _cbfs_boot_lookup(const char *name, bool force_ro,
|
||||||
union cbfs_mdata *mdata, struct region_device *rdev)
|
union cbfs_mdata *mdata, struct region_device *rdev)
|
||||||
{
|
{
|
||||||
const struct cbfs_boot_device *cbd = cbfs_get_boot_device(force_ro);
|
const struct cbfs_boot_device *cbd = cbfs_get_boot_device(force_ro);
|
||||||
|
@ -65,7 +65,7 @@ cb_err_t cbfs_boot_lookup(const char *name, bool force_ro,
|
||||||
|
|
||||||
if (CONFIG(VBOOT_ENABLE_CBFS_FALLBACK) && !force_ro && err == CB_CBFS_NOT_FOUND) {
|
if (CONFIG(VBOOT_ENABLE_CBFS_FALLBACK) && !force_ro && err == CB_CBFS_NOT_FOUND) {
|
||||||
printk(BIOS_INFO, "CBFS: Fall back to RO region for %s\n", name);
|
printk(BIOS_INFO, "CBFS: Fall back to RO region for %s\n", name);
|
||||||
return cbfs_boot_lookup(name, true, mdata, rdev);
|
return _cbfs_boot_lookup(name, true, mdata, rdev);
|
||||||
}
|
}
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err == CB_CBFS_NOT_FOUND)
|
if (err == CB_CBFS_NOT_FOUND)
|
||||||
|
@ -90,7 +90,7 @@ cb_err_t cbfs_boot_lookup(const char *name, bool force_ro,
|
||||||
|
|
||||||
int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type)
|
int cbfs_boot_locate(struct cbfsf *fh, const char *name, uint32_t *type)
|
||||||
{
|
{
|
||||||
if (cbfs_boot_lookup(name, false, &fh->mdata, &fh->data))
|
if (_cbfs_boot_lookup(name, false, &fh->mdata, &fh->data))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
size_t msize = be32toh(fh->mdata.h.offset);
|
size_t msize = be32toh(fh->mdata.h.offset);
|
||||||
|
@ -330,7 +330,7 @@ void cbfs_preload(const char *name)
|
||||||
|
|
||||||
DEBUG("%s(name='%s')\n", __func__, name);
|
DEBUG("%s(name='%s')\n", __func__, name);
|
||||||
|
|
||||||
if (cbfs_boot_lookup(name, force_ro, &mdata, &rdev))
|
if (_cbfs_boot_lookup(name, force_ro, &mdata, &rdev))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
size = region_device_sz(&rdev);
|
size = region_device_sz(&rdev);
|
||||||
|
@ -422,7 +422,7 @@ void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
|
||||||
DEBUG("%s(name='%s', alloc=%p(%p), force_ro=%s, type=%d)\n", __func__, name, allocator,
|
DEBUG("%s(name='%s', alloc=%p(%p), force_ro=%s, type=%d)\n", __func__, name, allocator,
|
||||||
arg, force_ro ? "true" : "false", type ? *type : -1);
|
arg, force_ro ? "true" : "false", type ? *type : -1);
|
||||||
|
|
||||||
if (cbfs_boot_lookup(name, force_ro, &mdata, &rdev))
|
if (_cbfs_boot_lookup(name, force_ro, &mdata, &rdev))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
|
@ -525,7 +525,7 @@ cb_err_t cbfs_prog_stage_load(struct prog *pstage)
|
||||||
|
|
||||||
prog_locate_hook(pstage);
|
prog_locate_hook(pstage);
|
||||||
|
|
||||||
if ((err = cbfs_boot_lookup(prog_name(pstage), false, &mdata, &rdev)))
|
if ((err = _cbfs_boot_lookup(prog_name(pstage), false, &mdata, &rdev)))
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
assert(be32toh(mdata.h.type) == CBFS_TYPE_STAGE);
|
assert(be32toh(mdata.h.type) == CBFS_TYPE_STAGE);
|
||||||
|
|
Loading…
Reference in New Issue