[PATCH 40/67] upl: Add a function to write a UPL handoff to an abuf

Simon Glass sjg at chromium.org
Wed Jan 1 23:09:26 CET 2025


Create a convenience function which can write a UPL handoff into an abuf
and return it.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

 boot/upl_common.c    | 48 ++++++++++++++++++++++++++++++++++++++++++++
 boot/upl_write.c     | 28 ++++++++++++++++++++++++++
 common/spl/spl_upl.c | 26 ++++--------------------
 include/upl.h        | 23 +++++++++++++++++++++
 4 files changed, 103 insertions(+), 22 deletions(-)

diff --git a/boot/upl_common.c b/boot/upl_common.c
index 01301049341..b0246f72597 100644
--- a/boot/upl_common.c
+++ b/boot/upl_common.c
@@ -8,6 +8,7 @@
 
 #define LOG_CATEGORY UCLASS_BOOTSTD
 
+#include <cpu.h>
 #include <dm.h>
 #include <serial.h>
 #include <string.h>
@@ -130,6 +131,53 @@ int upl_add_graphics(struct upl_graphics *gra, ulong *basep, ulong *sizep)
 	return 0;
 }
 
+int upl_create(struct upl *upl)
+{
+	ulong base, size;
+	int ret;
+
+	/* hard-code this for now to keep Tianocore happy */
+	upl->addr_cells = 2;
+	upl->size_cells = 1;
+
+	upl->bootmode = 0;
+	log_debug("conf_offset %d\n", upl->conf_offset);
+	if (IS_ENABLED(CONFIG_X86))
+		upl->addr_width =  cpu_phys_address_size();
+
+	/* no reserved memory */
+
+	ret = upl_add_serial(&upl->serial);
+	if (ret && ret != -ENOENT)
+		return log_msg_ret("ser", ret);
+	ret = upl_add_graphics(&upl->graphics, &base, &size);
+	if (ret && ret != -ENOENT)
+		return log_msg_ret("gra", ret);
+
+	return 0;
+}
+
+int upl_write_to_buf(struct upl *upl, ofnode root, struct abuf *buf)
+{
+	int ret;
+
+	ret = upl_create(upl);
+	if (ret)
+		return log_msg_ret("uwr", ret);
+
+	log_debug("writing to root node %d\n", ofnode_to_offset(root));
+	ret = upl_write_handoff(upl, root, true);
+	if (ret)
+		return log_msg_ret("wr", ret);
+
+	ret = oftree_to_fdt(oftree_default(), buf);
+	if (ret)
+		return log_msg_ret("fdt", ret);
+	log_debug("FDT size %zx\n", abuf_size(buf));
+
+	return 0;
+}
+
 void upl_init(struct upl *upl)
 {
 	memset(upl, '\0', sizeof(struct upl));
diff --git a/boot/upl_write.c b/boot/upl_write.c
index 60548937090..c53fa5396e8 100644
--- a/boot/upl_write.c
+++ b/boot/upl_write.c
@@ -625,3 +625,31 @@ int upl_create_handoff_tree(const struct upl *upl, oftree *treep)
 
 	return 0;
 }
+
+int upl_create_handoff(struct upl *upl, ulong addr, struct abuf *buf)
+{
+	oftree tree;
+	int ret;
+
+	ret = upl_create(upl);
+	if (ret) {
+		log_debug("Failed to create handoff (err=%dE)\n", ret);
+		return log_msg_ret("cho", ret);
+	}
+	log_debug("2a images %d\n", upl->image.count);
+
+	ret = oftree_new(&tree);
+	if (ret)
+		return log_msg_ret("new", ret);
+
+	ret = upl_write_handoff(upl, oftree_root(tree), true);
+	if (ret)
+		return log_msg_ret("wr", ret);
+
+	ret = oftree_to_fdt(tree, buf);
+	if (ret)
+		return log_msg_ret("fdt", ret);
+	oftree_dispose(tree);
+
+	return 0;
+}
diff --git a/common/spl/spl_upl.c b/common/spl/spl_upl.c
index a78ae75e56c..2bc0e265661 100644
--- a/common/spl/spl_upl.c
+++ b/common/spl/spl_upl.c
@@ -15,8 +15,6 @@
 #include <spl.h>
 #include <upl.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 struct upl s_upl;
 
 void upl_set_fit_addr(ulong fit)
@@ -53,38 +51,22 @@ int _upl_add_image(int node, ulong load_addr, ulong size, const char *desc)
 
 int spl_write_upl_handoff(void)
 {
-	struct upl *upl = &s_upl;
-	ulong addr, size;
+	struct upl s_upl, *upl = &s_upl;
 	struct abuf buf;
-	ofnode root;
 	void *ptr;
 	int ret;
 
 	log_debug("UPL: Writing handoff - image_count=%d\n", upl->image.count);
-	upl->addr_cells = IS_ENABLED(CONFIG_PHYS_64BIT) ? 2 : 1;
-	upl->size_cells = IS_ENABLED(CONFIG_PHYS_64BIT) ? 2 : 1;
-	upl->bootmode = UPLBM_DEFAULT;
-	ret = upl_add_serial(&upl->serial);
-	if (ret)
-		return log_msg_ret("ser", ret);
-	ret = upl_add_graphics(&upl->graphics, &addr, &size);
-	if (ret && ret != -ENOENT)
-		return log_msg_ret("gra", ret);
-
-	root = ofnode_root();
-	ret = upl_write_handoff(upl, root, true);
-	if (ret)
-		return log_msg_ret("wr", ret);
 
-	ret = oftree_to_fdt(oftree_default(), &buf);
+	ret = upl_write_to_buf(upl, ofnode_root(), &buf);
 	if (ret)
-		return log_msg_ret("fdt", ret);
-	log_debug("FDT size %zx\n", abuf_size(&buf));
+		return log_msg_ret("wuh", ret);
 
 	ptr = bloblist_add(BLOBLISTT_CONTROL_FDT, abuf_size(&buf), 0);
 	if (!ptr)
 		return log_msg_ret("blo", -ENOENT);
 	memcpy(ptr, abuf_data(&buf), abuf_size(&buf));
+	abuf_uninit(&buf);
 
 	return 0;
 }
diff --git a/include/upl.h b/include/upl.h
index edd333f648a..ce357d16ebe 100644
--- a/include/upl.h
+++ b/include/upl.h
@@ -394,6 +394,29 @@ int upl_add_serial(struct upl_serial *ser);
  */
 int upl_add_graphics(struct upl_graphics *gra, ulong *basep, ulong *sizep);
 
+/**
+ * upl_create() - Create a basic UPL handoff structure
+ *
+ * Sets up common fields which don't depend on having a FIT available
+ *
+ * @upl: UPL structure to create
+ * Return: 0 if OK, -ve on error
+ */
+int upl_create(struct upl *upl);
+
+#ifndef USE_HOSTCC
+/**
+ * upl_write_to_buf() - Write a UPL struct to a tree then flatten it into a buf
+ *
+ * @upl: UPL struct to fill up
+ * @root: Root node to write UPL information to (this is updated before the
+ *	finally buffer is written)
+ * @buf: Buffer to contain the final flattened tree
+ * Return: 0 if OK, -ve on error
+ */
+int upl_write_to_buf(struct upl *upl, ofnode root, struct abuf *buf);
+#endif
+
 /** upl_init() - Set up a UPL struct */
 void upl_init(struct upl *upl);
 
-- 
2.43.0



More information about the U-Boot mailing list