summaryrefslogtreecommitdiff
path: root/payloads/libpayload/libc/fmap.c
diff options
context:
space:
mode:
authorJakub Czapiga <jacz@semihalf.com>2021-11-12 13:45:29 +0000
committerFelix Held <felix-coreboot@felixheld.de>2021-12-23 14:37:42 +0000
commit8fac662f308cdfbeec3f71d4728f71ad79c06925 (patch)
treebc2e73ab891c1643ccbf3bde29b36b7f95383735 /payloads/libpayload/libc/fmap.c
parente7006fb414d20aa49b1aa7d6e2e5a979f5395a6d (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.c52
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)