binman: Add a library to access binman entries
authorSimon Glass <sjg@chromium.org>
Sat, 7 Dec 2019 04:41:34 +0000 (21:41 -0700)
committerBin Meng <bmeng.cn@gmail.com>
Sun, 15 Dec 2019 00:48:33 +0000 (08:48 +0800)
SPL and TPL can access information about binman entries using link-time
symbols but this is not available in U-Boot proper. Of course it could be
made available, but the intention is to just read the device tree.

Add support for this, so that U-Boot can locate entries.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
common/board_r.c
include/binman.h [new file with mode: 0644]
lib/Kconfig
lib/Makefile
lib/binman.c [new file with mode: 0644]

index 5464172..9902c51 100644 (file)
@@ -18,6 +18,7 @@
 #if defined(CONFIG_CMD_BEDBUG)
 #include <bedbug/type.h>
 #endif
+#include <binman.h>
 #include <command.h>
 #include <console.h>
 #include <dm.h>
@@ -347,6 +348,14 @@ static int initr_manual_reloc_cmdtable(void)
 }
 #endif
 
+static int initr_binman(void)
+{
+       if (!CONFIG_IS_ENABLED(BINMAN_FDT))
+               return 0;
+
+       return binman_init();
+}
+
 #if defined(CONFIG_MTD_NOR_FLASH)
 static int initr_flash(void)
 {
@@ -697,6 +706,7 @@ static init_fnc_t init_sequence_r[] = {
 #ifdef CONFIG_EFI_LOADER
        efi_memory_init,
 #endif
+       initr_binman,
        stdio_init_tables,
        initr_serial,
        initr_announce,
diff --git a/include/binman.h b/include/binman.h
new file mode 100644 (file)
index 0000000..b462dc8
--- /dev/null
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: Intel */
+/*
+ * Access to binman information at runtime
+ *
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef _BINMAN_H_
+#define _BINMAN_H_
+
+/**
+ *struct binman_entry - information about a binman entry
+ *
+ * @image_pos: Position of entry in the image
+ * @size: Size of entry
+ */
+struct binman_entry {
+       u32 image_pos;
+       u32 size;
+};
+
+/**
+ * binman_entry_find() - Find a binman symbol
+ *
+ * This searches the binman information in the device tree for a symbol of the
+ * given name
+ *
+ * @name: Path to entry to examine (e.g. "/read-only/u-boot")
+ * @entry: Returns information about the entry
+ * @return 0 if OK, -ENOENT if the path is not found, other -ve value if the
+ *     binman information is invalid (missing image-pos or size)
+ */
+int binman_entry_find(const char *name, struct binman_entry *entry);
+
+/**
+ * binman_init() - Set up the binman symbol information
+ *
+ * This locates the binary symbol information in the device tree ready for use
+ *
+ * @return 0 if OK, -ENOMEM if out of memory, -EINVAL if there is no binman node
+ */
+int binman_init(void);
+
+#endif
index 965cf7b..d040a87 100644 (file)
@@ -7,6 +7,16 @@ config BCH
          This is used by SoC platforms which do not have built-in ELM
          hardware engine required for BCH ECC correction.
 
+config BINMAN_FDT
+       bool "Allow access to binman information in the device tree"
+       depends on BINMAN && OF_CONTROL
+       default y
+       help
+         This enables U-Boot to access information about binman entries,
+         stored in the device tree in a binman node. Typical uses are to
+         locate entries in the firmware image. See binman.h for the available
+         functionality.
+
 config CC_OPTIMIZE_LIBS_FOR_SPEED
        bool "Optimize libraries for speed"
        help
index 1fb650c..7a713a5 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_ASN1_DECODER) += asn1_decoder.o
 obj-y += crypto/
 
 obj-$(CONFIG_AES) += aes.o
+obj-$(CONFIG_$(SPL_TPL_)BINMAN_FDT) += binman.o
 
 ifndef API_BUILD
 ifneq ($(CONFIG_UT_UNICODE)$(CONFIG_EFI_LOADER),)
diff --git a/lib/binman.c b/lib/binman.c
new file mode 100644 (file)
index 0000000..1774bdf
--- /dev/null
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: Intel
+/*
+ * Access to binman information at runtime
+ *
+ * Copyright 2019 Google LLC
+ * Written by Simon Glass <sjg@chromium.org>
+ */
+
+#include <common.h>
+#include <binman.h>
+#include <dm.h>
+
+struct binman_info {
+       ofnode image;
+};
+
+static struct binman_info *binman;
+
+int binman_entry_find(const char *name, struct binman_entry *entry)
+{
+       ofnode node;
+       int ret;
+
+       node = ofnode_find_subnode(binman->image, name);
+       if (!ofnode_valid(node))
+               return log_msg_ret("no binman node", -ENOENT);
+
+       ret = ofnode_read_u32(node, "image-pos", &entry->image_pos);
+       if (ret)
+               return log_msg_ret("bad binman node1", ret);
+       ret = ofnode_read_u32(node, "size", &entry->size);
+       if (ret)
+               return log_msg_ret("bad binman node2", ret);
+
+       return 0;
+}
+
+int binman_init(void)
+{
+       binman = malloc(sizeof(struct binman_info));
+       if (!binman)
+               return log_msg_ret("space for binman", -ENOMEM);
+       binman->image = ofnode_path("/binman");
+       if (!ofnode_valid(binman->image))
+               return log_msg_ret("binman node", -EINVAL);
+
+       return 0;
+}