diff options
author | Jakub Czapiga <jacz@semihalf.com> | 2021-11-12 13:45:29 +0000 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2021-12-23 14:37:42 +0000 |
commit | 8fac662f308cdfbeec3f71d4728f71ad79c06925 (patch) | |
tree | bc2e73ab891c1643ccbf3bde29b36b7f95383735 /payloads/libpayload/libc/fmap.c | |
parent | e7006fb414d20aa49b1aa7d6e2e5a979f5395a6d (diff) |
libpayload/libc/fmap: Implement new FlashMap API
This patch introduces new FlashMap API, the fmap_locate_area().
It works on cached FlashMap provided in lib_sysinfo.fmap_cache.
Change-Id: Idbf9016ce73aa58e17f3ee19920ab83dc6c25abb
Signed-off-by: Jakub Czapiga <jacz@semihalf.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/59494
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Julius Werner <jwerner@chromium.org>
Diffstat (limited to 'payloads/libpayload/libc/fmap.c')
-rw-r--r-- | payloads/libpayload/libc/fmap.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/payloads/libpayload/libc/fmap.c b/payloads/libpayload/libc/fmap.c index b7d64918ac..2d185a7c60 100644 --- a/payloads/libpayload/libc/fmap.c +++ b/payloads/libpayload/libc/fmap.c @@ -28,10 +28,60 @@ #include <libpayload-config.h> #include <libpayload.h> +#include <commonlib/bsd/fmap_serialized.h> #include <coreboot_tables.h> #include <cbfs.h> -#include <fmap_serialized.h> +#include <boot_device.h> #include <stdint.h> +#include <arch/virtual.h> + +/* Private fmap cache. */ +static struct fmap *_fmap_cache; + +static cb_err_t fmap_find_area(struct fmap *fmap, const char *name, size_t *offset, + size_t *size) +{ + for (size_t i = 0; i < le32toh(fmap->nareas); ++i) { + if (strncmp((const char *)fmap->areas[i].name, name, FMAP_STRLEN) != 0) + continue; + if (offset) + *offset = le32toh(fmap->areas[i].offset); + if (size) + *size = le32toh(fmap->areas[i].size); + return CB_SUCCESS; + } + + return CB_ERR; +} + +static bool fmap_is_signature_valid(struct fmap *fmap) +{ + return memcmp(fmap->signature, FMAP_SIGNATURE, sizeof(fmap->signature)) == 0; +} + +static bool fmap_setup_cache(void) +{ + /* Use FMAP cache if available */ + if (lib_sysinfo.fmap_cache + && fmap_is_signature_valid((struct fmap *)phys_to_virt(lib_sysinfo.fmap_cache))) { + _fmap_cache = (struct fmap *)phys_to_virt(lib_sysinfo.fmap_cache); + return true; + } + + return false; +} + +cb_err_t fmap_locate_area(const char *name, size_t *offset, size_t *size) +{ + if (!_fmap_cache && !fmap_setup_cache()) + return CB_ERR; + + return fmap_find_area(_fmap_cache, name, offset, size); +} + +/*********************************************************************************************** + * LEGACY CODE * + **********************************************************************************************/ int fmap_region_by_name(const uint32_t fmap_offset, const char * const name, uint32_t * const offset, uint32_t * const size) |