[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